Replace Unsupported Keras Layer with Function Layer
This example shows how to import the layers from a pretrained Keras network, replace the unsupported layers with function layers, and assemble the layers into a network ready for prediction.
Import Keras Network
Import the layers from a Keras network model. The network in "digitsNet.h5"
classifies images of digits.
filename = "digitsNet.h5";
layers = importKerasLayers(filename,ImportWeights=true)
Warning: 'importKerasLayers' is not recommended and will be removed in a future release. To import TensorFlow-Keras models, save using the SavedModel format and use importNetworkFromTensorFlow function.
Warning: Unable to import layer. Keras layer 'Activation' with the specified settings is not supported. The problem was: Activation type 'softsign' is not supported.
Warning: Unable to import layer. Keras layer 'Activation' with the specified settings is not supported. The problem was: Activation type 'softsign' is not supported.
Warning: Unable to import some Keras layers, because they are not supported by the Deep Learning Toolbox. They have been replaced by placeholder layers. To find these layers, call the function findPlaceholderLayers on the returned object.
layers = 13x1 Layer array with layers: 1 'ImageInputLayer' Image Input 28x28x1 images 2 'conv2d' 2-D Convolution 8 3x3x1 convolutions with stride [1 1] and padding [0 0 0 0] 3 'conv2d_softsign' Activation Placeholder for 'Activation' Keras layer 4 'max_pooling2d' 2-D Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 5 'conv2d_1' 2-D Convolution 16 3x3x8 convolutions with stride [1 1] and padding [0 0 0 0] 6 'conv2d_1_softsign' Activation Placeholder for 'Activation' Keras layer 7 'max_pooling2d_1' 2-D Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 8 'flatten' Keras Flatten Flatten activations into 1-D assuming C-style (row-major) order 9 'dense' Fully Connected 100 fully connected layer 10 'dense_relu' ReLU ReLU 11 'dense_1' Fully Connected 10 fully connected layer 12 'dense_1_softmax' Softmax softmax 13 'ClassificationLayer_dense_1' Classification Output crossentropyex
The Keras network contains some layers that are not supported by Deep Learning Toolbox. The importKerasLayers
function displays a warning and replaces the unsupported layers with placeholder layers.
Replace Placeholder Layers
To replace the placeholder layers, first identify the names of the layers to replace. Find the placeholder layers using the findPlaceholderLayers
function.
placeholderLayers = findPlaceholderLayers(layers)
placeholderLayers = 2x1 PlaceholderLayer array with layers: 1 'conv2d_softsign' Activation Placeholder for 'Activation' Keras layer 2 'conv2d_1_softsign' Activation Placeholder for 'Activation' Keras layer
Replace the placeholder layers with function layers with function specified by the softsign
function, listed at the end of the example.
Create a function layer with function specified by the softsign
function, attached to this example as a supporting file. To access this function, open this example as a live script. Set the layer description to "softsign"
.
layer = functionLayer(@softsign,Description="softsign");
Replace the layers using the replaceLayer
function. To use the replaceLayer
function, first convert the layer array to a layer graph.
lgraph = layerGraph(layers); lgraph = replaceLayer(lgraph,"conv2d_softsign",layer); lgraph = replaceLayer(lgraph,"conv2d_1_softsign",layer);
Specify Class Names
If the imported classification layer does not contain the classes, then you must specify these before prediction. If you do not specify the classes, then the software automatically sets the classes to 1
, 2
, ..., N
, where N
is the number of classes.
Find the index of the classification layer by viewing the Layers
property of the layer graph.
lgraph.Layers
ans = 13x1 Layer array with layers: 1 'ImageInputLayer' Image Input 28x28x1 images 2 'conv2d' 2-D Convolution 8 3x3x1 convolutions with stride [1 1] and padding [0 0 0 0] 3 'layer' Function softsign 4 'max_pooling2d' 2-D Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 5 'conv2d_1' 2-D Convolution 16 3x3x8 convolutions with stride [1 1] and padding [0 0 0 0] 6 'layer_1' Function softsign 7 'max_pooling2d_1' 2-D Max Pooling 2x2 max pooling with stride [2 2] and padding [0 0 0 0] 8 'flatten' Keras Flatten Flatten activations into 1-D assuming C-style (row-major) order 9 'dense' Fully Connected 100 fully connected layer 10 'dense_relu' ReLU ReLU 11 'dense_1' Fully Connected 10 fully connected layer 12 'dense_1_softmax' Softmax softmax 13 'ClassificationLayer_dense_1' Classification Output crossentropyex
The classification layer has the name 'ClassificationLayer_dense_1'
. View the classification layer and check the Classes
property.
cLayer = lgraph.Layers(end)
cLayer = ClassificationOutputLayer with properties: Name: 'ClassificationLayer_dense_1' Classes: 'auto' ClassWeights: 'none' OutputSize: 'auto' Hyperparameters LossFunction: 'crossentropyex'
Because the Classes
property of the layer is "auto"
, you must specify the classes manually. Set the classes to 0
, 1
, ..., 9
, and then replace the imported classification layer with the new one.
cLayer.Classes = string(0:9);
lgraph = replaceLayer(lgraph,"ClassificationLayer_dense_1",cLayer);
Assemble Network
Assemble the layer graph using assembleNetwork
. The function returns a DAGNetwork
object that is ready to use for prediction.
net = assembleNetwork(lgraph)
net = DAGNetwork with properties: Layers: [13x1 nnet.cnn.layer.Layer] Connections: [12x2 table] InputNames: {'ImageInputLayer'} OutputNames: {'ClassificationLayer_dense_1'}
Test Network
Make predictions with the network using a test data set.
[XTest,YTest] = digitTest4DArrayData; YPred = classify(net,XTest);
View the accuracy.
mean(YPred == YTest)
ans = 0.9900
Visualize the predictions in a confusion matrix.
confusionchart(YTest,YPred)
See Also
importKerasNetwork
| assembleNetwork
| replaceLayer
| importKerasLayers
| trainNetwork
| layerGraph
| DAGNetwork
| findPlaceholderLayers