Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keras unable to calculate number of parameters in a Keras Custom Layer

I am building a Keras Custom layer with some Tensorflow support. Before that I wanted to test whether a Convolution2D layer works properly if I write a Keras layer with Tensorflow's conv2d in the call function.

class Convolutional2D(Layer):
    def __init__(self, filters=None, kernel_size=None, padding='same', activation='linear', strides=(1,1), name ='Conv2D', **kwargs):
        self.filters = filters
        self.kernel_size = kernel_size
        self.padding = padding
        self.activation = activation
        self.strides = strides
        self.name = name
        self.input_spec = [InputSpec(ndim=4)]
        super(Convolutional2D, self).__init__(**kwargs)

    def call(self, input):
        out = tf.layers.conv2d(inputs=input, filters=self.filters, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding, 
        data_format='channels_last')
        return(out)

    def compute_output_shape(self, input_shape):
        batch_size = input_shape[0]
        width = input_shape[1]/self.strides[0]
        height = input_shape[2]/self.strides[1]
        channels = self.filters
        return(batch_size, width, height, channels)

    def get_config(self):
        config = {'filters': self.filters, 'kernel_size': self.kernel_size, 'padding': self.padding, 'activation':self.activation, 'strides':self.strides, 
        'name':self.name}
        base_config = super(Convolutional2D, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

    def build(self, input_shape):
        self.input_spec = [InputSpec(shape=input_shape)]

This compiles properly but when the I use model.summary() it does not calculate the number of parameters for this layer.

What do I have to do so that when I check the total number of parameters of the model the number includes the trainable number of parameters of this layer?

like image 646
Subham Mukherjee Avatar asked Nov 08 '22 16:11

Subham Mukherjee


1 Answers

I have found the answer to this problem.

    def build(self, input_shape):
    if self.data_format == 'channels_first':
        channel_axis = 1
    else:
        channel_axis = -1
    if input_shape[channel_axis] is None:
        raise ValueError('The channel dimension of the inputs '
                         'should be defined. Found `None`.')
    input_dim = input_shape[channel_axis]
    kernel_shape = self.kernel_size + (input_dim, self.filters)

    self.kernel = self.add_weight(shape=kernel_shape,
                                  initializer=self.kernel_initializer,
                                  name='kernel',
                                  regularizer=self.kernel_regularizer,
                                  constraint=self.kernel_constraint)
    if self.use_bias:
        self.bias = self.add_weight(shape=(self.filters,),
                                    initializer=self.bias_initializer,
                                    name='bias',
                                    regularizer=self.bias_regularizer,
                                    constraint=self.bias_constraint)
    else:
        self.bias = None
    # Set input spec.
    self.input_spec = InputSpec(ndim=self.rank + 2,
                                axes={channel_axis: input_dim})
    self.built = True

The add weights defines the number of parameters which I have not done in my code. But that does not hamper the performance of the model. It works fine except for the fact one cannot get the number of parameters specification.

like image 93
Subham Mukherjee Avatar answered Nov 15 '22 08:11

Subham Mukherjee