DeepFusion is a highly modular and customizable deep learning framework.
It is designed to provide strong and explicit control over all data, operations and parameters while maintaining a simple and intuitive code base.
- Table of Contents
- DeepFusion Framework
- Basic Usage
- Highlights
- Installation
- Resources
- Contribution Guidelines
- License
- Acknowledgements
- Credits
In DeepFusion, all networks are composed by combining 3 basic types of components
:
Data
Module
Net
Data
objects hold the network activations and Module
objects perform operations on them. The
Net
object forms a thin wrapper around the Data
and Module
objects and is used to perform
the forward and backward passes.
A simple neural network is shown below, where, ellipses represent Data
objects and rectangles
represent Module
.
Note the alternating sequence of
Data
andModule
. The scheme isData
->Module
->Data
. Red represents nodes with updatable parameters.
Every node (Data
or Module
) has a unique ID (for eg: z1 or MatMul1) using which it can be
accessed and modified thus providing explicit access and control over all data and parameters.
More details on Data
, Module
and Net
functionalities can be found in their respective readmes
in deepfusion/components.
This is the basic idea behind deepfusion and any and all neural networks are created using this
procedure of attaching alternating Data
and Module
nodes.
As described before, in DeepFusion, all networks are composed by combining 3 basic types of
components
:
Data
Module
Net
The codebase follows the same intuitive structure:
deepfusion
└── components
├── net
├── data
└── modules
├── activation_functions
├── loss_functions
└── matmul.py
To construct a neural network we need to import the Net
, Data
and required Module
objects.
# Import Net, Data and necessary Modules
from deepfusion.components.net import Net
from deepfusion.components.data import Data
from deepfusion.components.modules import MatMul
from deepfusion.components.modules.activation_functions import Relu
from deepfusion.components.modules.loss_functions import MSELoss
The codebase is designed in an intuitive manner. Let's see how we would think about the above imports. "Okay, to create a neural network I need components (deepfusion.components). What kind of components do we need? Net, Data and Modules (import these). What kind of modules (operations) do we need? we need matrix multiplication, an activation function and a loss function (import these). That's it!"
To connect Data
and Module
objects we need to keep in mind the following 2 things:
Data
objects are used to specify the activation dimensions.Module
objects require the inputs and output data objects to be specified.
Now, let's construct the simple network we saw above.
# Basic structure: x -> Matmul -> z1 -> Relu -> a -> Matmul -> z2, + y -> MSE -> loss
x = Data(ID = 'x', shape = (1, 3))
z1 = Data(ID = 'z1', shape = (1, 5))
Matmul1 = MatMul(ID = 'Matmul1', inputs = [x], output = z1)
a = Data(ID = 'a', shape = (1, 5))
ActF = Relu(ID = 'ActF', inputs = [z1], output = a)
z2 = Data(ID = 'z2', shape = (1, 1))
Matmul2 = MatMul(ID = 'Matmul2', inputs = [a], output = z2)
# Add target variable, loss variable and loss function
y = Data('y', shape = (1, 1))
loss = Data('loss', shape = (1, 1))
LossF = MSELoss(ID = 'LossF', inputs = [z2, y], output = loss)
# Initialize the neural network
net = Net(ID = 'Net', root_nodes = [loss])
For
Data
the first dimension is the batch size. This is specified 1 during initialization. Eg: a length 3 vector would have shape = (1, 3) and a conv volume (C, H, W) would have shape = (1, C, H, W). During training any batch size (B, 3) or (B, C, H, W) can be used, theNet
object takes care of it.
Module parameter dimensions are inferred from connected data objects.
Examples introducing the basics and all features of the library can be found in the demo directory or in other resources.
To have a look at the codebase tree have a look at Codebase Tree.
Let's say we make the simple neural network as before:
And train it. During training only the red portions of the network receive updates and are trained. Therefore, the matrix multiplication modules will be trained.
Let's say we have trained the network and now we want to find the input that optimizes the function that we have learnt. This also falls under the same forward-backward-update procedure with the following simple twist:
net.freeze() # Freezes all modules
x.unfreeze() # Unfreezes the input node
After this we obtain the following network:
Now when we train the network only the input node value will get updates and be trained!
When developing new modules, the implementation of the backward pass can often be tricky and have subtle bugs. Deepfusion provides a gradient checking utility that can find the derivatives of the loss function(s) w.r.t. any specified data object (data node or module parameter). Eg:
# Compare analytic and numeric gradients with a step size of 1e-6 for:
# Input node: x
gradient_checker(net, data_obj = x, h = 1e-6)
# Matrix multiplication parameter W
gradient_checker(net, data_obj = Matmul1.W, h = 1e-6)
Note
Other features such as forward and backward pass profiling, multiple loss functions, automated training, gpu training etc. can be found in the demo directory or in other resources.
To install the core part of deepfusion use:
$ pip install deepfusion
To use GPU training capabilities you will require CuPy which needs the CUDA Toolkit. If the CUDA Toolkit is installed then use:
$ pip install deepfusion[gpu]
For visualizing networks you will require the Graphviz software and the graphviz package. If Graphviz is installed then use:
$ pip install deepfusion[visualization]
If all dependencies are pre-installed use:
pip install deepfusion[gpu,visualization]
Important
Make sure to select add to PATH options when downloading dependency softwares.
Contributions for the following are encouraged and greatly appreciated:
- Code Optimization: Benchmark your results and show a clear improvement.
- Visualization: Currently requires graphviz which is usually a pain to install. Structured graph visualization using say matplotlib would be a clear win.
- More Modules: Most scope for contribution currently in the following modules: loss_functions, pooling, normalizations, RNN modules etc.
- More Features: Some ideas include adding multiprocessing, working with pre-trained models from other libraries etc.
- Testing: Incorporating testing codes.
- Improving Documentation: Improving doc-string clarity and including doc tests. Also perhaps making a website for API reference.
We'll use Github issues for tracking pull requests and bugs.
Distributed under the MIT License.
Theoretical and code ideas inspired from:
- CS231n: Deep Learning for Computer Vision
- Coursera: Deep Learning Specialization
- Google Python Style Guide
- Udemy: Python Packaging
- Logo design by Ankur Tiwary