Keras - Customized Layer

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.
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.
backend is used to access the dot function.
Layer is the base class and we will be sub-classing it to create our layer
Layer is the base class and we will be sub-classing it to create our layer
Let us create a new class, MyCustomLayer by sub-classing Layer class −
class MyCustomLayer(Layer): 
   ...

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 2 sets the output dimension.
Line 3 calls the base or super layer’s init function.
Line 3 calls the base or super layer’s init function.
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 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 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.
Line 6 calls the base class, build 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 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
Line 2 return the dot product of the input data, input_data and our layer’s kernel, self.kernel
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 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.
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)
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
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 
_________________________________________________________________

    87 Lectures 
     11 hours 

 Abhilash Nelson

    61 Lectures 
     9 hours 

 Abhishek And Pukhraj

    57 Lectures 
     7 hours 

 Abhishek And Pukhraj

    52 Lectures 
     7 hours 

 Abhishek And Pukhraj

    52 Lectures 
     6 hours 

 Abhishek And Pukhraj

    68 Lectures 
     2 hours 

 Mike West
 Print
 Add Notes
 Bookmark this page