Keras - Customized Layer


Advertisements

Keras allows to create our own customized layer. Once a new layer is created, it can be used in any model without any restriction. Let us learn how to create new layer in this chapter.

Keras provides a base layer class, Layer which can sub-classed to create our own customized layer. Let us create a simple layer which will find weight based on normal distribution and then do the basic computation of finding the summation of the product of input and its weight during training.

Step 1: Import the necessary module

First, let us import the necessary modules −

from keras import backend as K 
from keras.layers import Layer

Here,

  • backend is used to access the dot function.

  • Layer is the base class and we will be sub-classing it to create our layer

Step 2: Define a layer class

Let us create a new class, MyCustomLayer by sub-classing Layer class

class MyCustomLayer(Layer): 
   ...

Step 3: Initialize the layer class

Let us initialize our new class as specified below −

def __init__(self, output_dim, **kwargs):    
   self.output_dim = output_dim 
   super(MyCustomLayer, self).__init__(**kwargs)

Here,

  • Line 2 sets the output dimension.

  • Line 3 calls the base or super layer’s init function.

Step 4: Implement build method

build is the main method and its only purpose is to build the layer properly. It can do anything related to the inner working of the layer. Once the custom functionality is done, we can call the base class build function. Our custom build function is as follows −

def build(self, input_shape): 
   self.kernel = self.add_weight(name = 'kernel', 
      shape = (input_shape[1], self.output_dim), 
      initializer = 'normal', trainable = True) 
   super(MyCustomLayer, self).build(input_shape)

Here,

  • Line 1 defines the build method with one argument, input_shape. Shape of the input data is referred by input_shape.

  • Line 2 creates the weight corresponding to input shape and set it in the kernel. It is our custom functionality of the layer. It creates the weight using ‘normal’ initializer.

  • Line 6 calls the base class, build method.

Step 5: Implement call method

call method does the exact working of the layer during training process.

Our custom call method is as follows

def call(self, input_data): 
   return K.dot(input_data, self.kernel)

Here,

  • Line 1 defines the call method with one argument, input_data. input_data is the input data for our layer.

  • Line 2 return the dot product of the input data, input_data and our layer’s kernel, self.kernel

Step 6: Implement compute_output_shape method

def compute_output_shape(self, input_shape): return (input_shape[0], self.output_dim)

Here,

  • Line 1 defines compute_output_shape method with one argument input_shape

  • Line 2 computes the output shape using shape of input data and output dimension set while initializing the layer.

Implementing the build, call and compute_output_shape completes the creating a customized layer. The final and complete code is as follows

from keras import backend as K from keras.layers import Layer
class MyCustomLayer(Layer): 
   def __init__(self, output_dim, **kwargs): 
      self.output_dim = output_dim 
      super(MyCustomLayer, self).__init__(**kwargs) 
   def build(self, input_shape): self.kernel = 
      self.add_weight(name = 'kernel', 
      shape = (input_shape[1], self.output_dim), 
      initializer = 'normal', trainable = True) 
      super(MyCustomLayer, self).build(input_shape) # 
      Be sure to call this at the end 
   def call(self, input_data): return K.dot(input_data, self.kernel) 
   def compute_output_shape(self, input_shape): return (input_shape[0], self.output_dim)

Using our customized layer

Let us create a simple model using our customized layer as specified below −

from keras.models import Sequential 
from keras.layers import Dense 

model = Sequential() 
model.add(MyCustomLayer(32, input_shape = (16,))) 
model.add(Dense(8, activation = 'softmax')) model.summary()

Here,

  • Our MyCustomLayer is added to the model using 32 units and (16,) as input shape

Running the application will print the model summary as below −

Model: "sequential_1" 
_________________________________________________________________ 
Layer (type) Output Shape Param 
#================================================================ 
my_custom_layer_1 (MyCustomL (None, 32) 512 
_________________________________________________________________
dense_1 (Dense) (None, 8) 264 
================================================================= 
Total params: 776 
Trainable params: 776 
Non-trainable params: 0 
_________________________________________________________________
Advertisements