findPlaceholderLayers

Find placeholder layers in network architecture imported from Keras or ONNX

Description

example

placeholderLayers = findPlaceholderLayers(importedLayers) returns all placeholder layers that exist in the network architecture importedLayers imported by the importKerasLayers or importONNXLayers functions, or created by the functionToLayerGraph function. Placeholder layers are the layers that these functions insert in place of layers that are not supported by Deep Learning Toolbox™.

To use with an imported network, this function requires either the Deep Learning Toolbox Importer for TensorFlow™-Keras Models support package or the Deep Learning Toolbox Converter for ONNX™ Model Format support package.

[placeholderLayers,indices] = findPlaceholderLayers(importedLayers) also returns the indices of the placeholder layers.

Examples

collapse all

Specify the Keras network file to import layers from.

modelfile = 'digitsDAGnetwithnoise.h5';

Import the network architecture. The network includes some layer types that are not supported by Deep Learning Toolbox. The importKerasLayers function replaces each unsupported layer with a placeholder layer and returns a warning message.

lgraph = importKerasLayers(modelfile)
Warning: Unable to import some Keras layers, because they are not yet 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. 
> In nnet.internal.cnn.keras.importKerasLayers (line 26)
  In importKerasLayers (line 102) 

lgraph = 

  LayerGraph with properties:

         Layers: [15×1 nnet.cnn.layer.Layer]
    Connections: [15×2 table]

Display the imported layers of the network. Two placeholder layers replace the Gaussian noise layers in the Keras network.

lgraph.Layers
ans = 

  15x1 Layer array with layers:

     1   'input_1'                            Image Input             28x28x1 images
     2   'conv2d_1'                           Convolution             20 7x7 convolutions with stride [1  1] and padding 'same'
     3   'conv2d_1_relu'                      ReLU                    ReLU
     4   'conv2d_2'                           Convolution             20 3x3 convolutions with stride [1  1] and padding 'same'
     5   'conv2d_2_relu'                      ReLU                    ReLU
     6   'gaussian_noise_1'                   PLACEHOLDER LAYER       Placeholder for 'GaussianNoise' Keras layer
     7   'gaussian_noise_2'                   PLACEHOLDER LAYER       Placeholder for 'GaussianNoise' Keras layer
     8   'max_pooling2d_1'                    Max Pooling             2x2 max pooling with stride [2  2] and padding 'same'
     9   'max_pooling2d_2'                    Max Pooling             2x2 max pooling with stride [2  2] and padding 'same'
    10   'flatten_1'                          Flatten C-style         Flatten activations into 1D assuming C-style (row-major) order
    11   'flatten_2'                          Flatten C-style         Flatten activations into 1D assuming C-style (row-major) order
    12   'concatenate_1'                      Depth concatenation     Depth concatenation of 2 inputs
    13   'dense_1'                            Fully Connected         10 fully connected layer
    14   'activation_1_softmax'               Softmax                 softmax
    15   'ClassificationLayer_activation_1'   Classification Output   crossentropyex

Find the placeholder layers using findPlaceholderLayers. The output argument contains the two placeholder layers that importKerasLayers inserted in place of the Gaussian noise layers of the Keras network.

placeholders = findPlaceholderLayers(lgraph)
placeholders = 

  2x1 PlaceholderLayer array with layers:

     1   'gaussian_noise_1'   PLACEHOLDER LAYER   Placeholder for 'GaussianNoise' Keras layer
     2   'gaussian_noise_2'   PLACEHOLDER LAYER   Placeholder for 'GaussianNoise' Keras layer

Display the configuration of each placeholder layer.

gaussian1.KerasConfiguration
gaussian2.KerasConfiguration
ans = 

  struct with fields:

    trainable: 1
         name: 'gaussian_noise_1'
       stddev: 1.5000


ans = 

  struct with fields:

    trainable: 1
         name: 'gaussian_noise_2'
       stddev: 0.7000

This example shows how to import the layers from a pretrained Keras network, replace the unsupported layers with custom 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 'digitsDAGnetwithnoise.h5' classifies images of digits.

filename = 'digitsDAGnetwithnoise.h5';
lgraph = importKerasLayers(filename,'ImportWeights',true);
Warning: Unable to import some Keras layers, because they are not yet 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.

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.

Plot the layer graph using plot.

figure
plot(lgraph)
title("Imported Network")

Replace Placeholder Layers

To replace the placeholder layers, first identify the names of the layers to replace. Find the placeholder layers using findPlaceholderLayers.

placeholderLayers = findPlaceholderLayers(lgraph)
placeholderLayers = 
  2x1 PlaceholderLayer array with layers:

     1   'gaussian_noise_1'   PLACEHOLDER LAYER   Placeholder for 'GaussianNoise' Keras layer
     2   'gaussian_noise_2'   PLACEHOLDER LAYER   Placeholder for 'GaussianNoise' Keras layer

Display the Keras configurations of these layers.

placeholderLayers.KerasConfiguration
ans = struct with fields:
    trainable: 1
         name: 'gaussian_noise_1'
       stddev: 1.5000

ans = struct with fields:
    trainable: 1
         name: 'gaussian_noise_2'
       stddev: 0.7000

Define a custom Gaussian noise layer. To create this layer, save the file gaussianNoiseLayer.m in the current folder. Then, create two Gaussian noise layers with the same configurations as the imported Keras layers.

gnLayer1 = gaussianNoiseLayer(1.5,'new_gaussian_noise_1');
gnLayer2 = gaussianNoiseLayer(0.7,'new_gaussian_noise_2');

Replace the placeholder layers with the custom layers using replaceLayer.

lgraph = replaceLayer(lgraph,'gaussian_noise_1',gnLayer1);
lgraph = replaceLayer(lgraph,'gaussian_noise_2',gnLayer2);

Plot the updated layer graph using plot.

figure
plot(lgraph)
title("Network with Replaced Layers")

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 = 
  15x1 Layer array with layers:

     1   'input_1'                            Image Input             28x28x1 images
     2   'conv2d_1'                           Convolution             20 7x7x1 convolutions with stride [1  1] and padding 'same'
     3   'conv2d_1_relu'                      ReLU                    ReLU
     4   'conv2d_2'                           Convolution             20 3x3x1 convolutions with stride [1  1] and padding 'same'
     5   'conv2d_2_relu'                      ReLU                    ReLU
     6   'new_gaussian_noise_1'               Gaussian Noise          Gaussian noise with standard deviation 1.5
     7   'new_gaussian_noise_2'               Gaussian Noise          Gaussian noise with standard deviation 0.7
     8   'max_pooling2d_1'                    Max Pooling             2x2 max pooling with stride [2  2] and padding 'same'
     9   'max_pooling2d_2'                    Max Pooling             2x2 max pooling with stride [2  2] and padding 'same'
    10   'flatten_1'                          Flatten C-style         Flatten activations into 1D assuming C-style (row-major) order
    11   'flatten_2'                          Flatten C-style         Flatten activations into 1D assuming C-style (row-major) order
    12   'concatenate_1'                      Depth concatenation     Depth concatenation of 2 inputs
    13   'dense_1'                            Fully Connected         10 fully connected layer
    14   'activation_1'                       Softmax                 softmax
    15   'ClassificationLayer_activation_1'   Classification Output   crossentropyex

The classification layer has the name 'ClassificationLayer_activation_1'. View the classification layer and check the Classes property.

cLayer = lgraph.Layers(end)
cLayer = 
  ClassificationOutputLayer with properties:

            Name: 'ClassificationLayer_activation_1'
         Classes: 'auto'
      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)
cLayer = 
  ClassificationOutputLayer with properties:

            Name: 'ClassificationLayer_activation_1'
         Classes: [0    1    2    3    4    5    6    7    8    9]
      OutputSize: 10

   Hyperparameters
    LossFunction: 'crossentropyex'

lgraph = replaceLayer(lgraph,'ClassificationLayer_activation_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: [15×1 nnet.cnn.layer.Layer]
    Connections: [15×2 table]

Input Arguments

collapse all

Network architecture imported from Keras or ONNX or created by functionToLayerGraph, specified as a Layer array or LayerGraph object.

Output Arguments

collapse all

All placeholder layers in the network architecture, returned as an array of PlaceholderLayer objects.

Indices of placeholder layers, returned as a vector.

  • If importedLayers is a layer array, then indices are the indices of the placeholder layers in importedLayers.

  • If importedLayers is a LayerGraph object, then indices are the indices of the placeholder layers in importedLayers.Layers.

If you remove a layer from or add a layer to a Layer array or LayerGraph object, then the indices of the other layers in the object can change. You must use findPlaceholderLayers again to find the updated indices of the rest of the placeholder layers.

Tips

  • If you have installed Deep Learning Toolbox Importer for TensorFlow-Keras Models and findPlaceholderLayers is unable to find placeholder layers created when importing an ONNX network, then try updating the Deep Learning Toolbox Importer for TensorFlow-Keras Models support package in the Add-On Explorer.

Introduced in R2017b