Building Models

DLPy offers you several options to build neural networks, including building them from scratch or using architectures already defined in the DLPy API. Similarly, you can train your models from scratch or you can load pre-trained weights. Regardless of your approach, it helps to know the difference between the Sequential Model and the Functional API. This document serves as an introduction to these topics, but for more detail see the examples on GitHub.

Note: All examples on this page assume that you have a CAS server started and have created a CAS session in swat named sess.

Sequential Model

A Sequential model is a modular way to build a custom neural network. A Sequential model acts like a stack of layers or blocks (e.g. a ResNet block).

The following example illustrates how you can use the Sequential Model in order to create a LeNet architecture.

In [1]: from dlpy import Sequential, InputLayer, Conv2d, Pooling, Dense, OutputLayer

In [2]: sequential_model = Sequential(conn=sess, model_table="Simple_CNN")

In [3]: sequential_model.add(InputLayer(n_channels=1, width=28, height=28))
NOTE: Input layer added.

In [4]: sequential_model.add(Conv2d(n_filters=6, width=5, height=5, stride=1))
NOTE: Convolution layer added.

In [5]: sequential_model.add(Pooling(width=2, height=2, stride=2, pool='max'))
NOTE: Pooling layer added.

In [6]: sequential_model.add(Conv2d(n_filters=16, width=5, height=5, stride=1))
NOTE: Convolution layer added.

In [7]: sequential_model.add(Pooling(width=2, height=2, stride=2, pool='max'))
NOTE: Pooling layer added.

In [8]: sequential_model.add(Dense(n=120))
NOTE: Fully-connected layer added.

In [9]: sequential_model.add(Dense(n=84))
NOTE: Fully-connected layer added.

In [10]: sequential_model.add(OutputLayer(n=10))
NOTE: Output layer added.
NOTE: Model compiled successfully.

The Sequential model is best used when your network architecture can be easily specified as a stack of modular elements. Although the Sequential model can be used to specify architectures with multi-input and multi-output layers, (see the src_layers parameter of the dlpy.layers.Layer class for details), architectures with complex connections are often better suited for the Functional API.

An additional option is to generate a Functional model from an existing Sequential model. This can be useful to quickly create variations of the same basic architecture. To generate a Functional model from a Sequential model, use Sequential.to_functional_model(). Then customize the Functional model with the Functional API as detailed in Functional API.

In [11]: functional_model = sequential_model.to_functional_model()

In [12]: functional_model.plot_network()
Out[12]: <graphviz.dot.Digraph at 0x1def4f314c8>

Functional API

The Functional API is a more flexible way of building models. Using the Functional API, you can easily specify architectures with multi-input and multi-output layers. To use the Functional API, define the architecture like you would call functions. That is, pass each input tensor as an argument to a layer to produce an output tensor. Once you complete the model, pass the inputs and outputs to the Model class and compile it.

In [13]: from dlpy.layers import Input, Conv2d, Concat, OutputLayer

In [14]: from dlpy import Model

In [15]: input1 = Input(n_channels = 1, width = 28, height = 28)

In [16]: input2 = Input(n_channels = 3, width = 28, height = 28)

In [17]: conv1 = Conv2d(2, name='conv1')(Conv2d(2, name='conv0')(input1))

In [18]: conv2 = Conv2d(2, name='conv2')(input1)

In [19]: conv3 = Conv2d(2, name='conv3')(input2)

In [20]: output2 = OutputLayer(n=2)(conv3)

In [21]: concat1 = Concat()([conv1, conv2, conv3])

In [22]: output1 = OutputLayer(n=2)(concat1)

In [23]: model1 = Model(conn = sess, inputs = [input1, input2], outputs = [output1, output2])

In [24]: model1.compile()
NOTE: Model compiled successfully.

Using Pre-built Models

DLPy supplies many industry standard models for a variety of computer vision and natural language processing tasks. These models are generally built with a single function call and can be customized using Sequential model building methods (including Sequential.to_functional_model()). This flexibility enables you to quickly customize existing models.

For a full list of the pre-build models, see Pre-built Models for Computer Vision Tasks and Pre-built Models for Natural Language Processing Tasks.

The following example shows how you can start with a stock ResNet18 model, remove the default output layer, and add two custom output layers using the Functional API.

In [25]: from dlpy.applications import ResNet18_SAS

In [26]: resnet = ResNet18_SAS(sess, n_classes=1000, width=224, height=224, n_channels=3)
NOTE: Input layer added.
NOTE: Convolution layer added.
NOTE: Batch normalization layer added.
NOTE: Pooling layer added.
NOTE: Pooling layer added.
NOTE: Output layer added.
NOTE: Model compiled successfully.

In [27]: resnet_base = resnet.to_functional_model(stop_layers=resnet.layers[-1])

In [28]: input_1 = Input(n_channels = 1, width = 28, height = 28)

In [29]: resnet_base_tensor = resnet_base(input_1)

In [30]: output_0 = OutputLayer(n=2)(resnet_base_tensor)

In [31]: output_1 = OutputLayer(n=100)(resnet_base_tensor)

In [32]: modified_resnet = Model(sess, inputs=input_1, outputs=[output_0,output_1])

In [33]: modified_resnet.compile()
NOTE: Model compiled successfully.

In [34]: modified_resnet.plot_network()
Out[34]: <graphviz.dot.Digraph at 0x1defe8ee748>

Loading Pre-trained Weights

Regardless of whether you build a model from scratch or use a pre-built model, you can load pre-trained weights as long as the weights were trained from a model with an identical architecture. The most common way to load weights is to use Model.load_weights().

Select pre-trained weights can be downloaded from Deep Learning Models and Tools.