Keras custom layer with trainable weights

Viewed 4472

I need to create custom layer in Keras (1.1) that has trainable weights (the same shape as input). And I try to init the weights by random values. There is my 'mylayer.py' file:

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np
from numpy import random

class MyLayer(Layer):

def __init__(self,**kwargs):
    super(MyLayer, self).__init__(**kwargs)

def build(self, input_shape):
    # Create a trainable weight variable for this layer.
    self.W_init = np.random(input_shape)
    self.W = K.variable(self.W_init, name="W")
    self.trainable_weights = [self.W]
    super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

def call(self, x):
    num, n, m = x.shape
    res=np.empty(num,1,1)
    for i in range(num):
        res[i,0,0]=K.dot(x[i,:,:], self.W[i,:,:])
    return res

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

But when I try to use it:

    from mylayer import *
def get_my_model_2():
    model = Sequential([
        Lambda(norm_input, input_shape=(1,28,28)),
        Convolution2D(32,3,3, activation='relu'),
        BatchNormalization(axis=1),
        Convolution2D(32,3,3, activation='relu'),
        MaxPooling2D(),
        BatchNormalization(axis=1),
        Convolution2D(64,3,3, activation='relu'),
        BatchNormalization(axis=1),
        Convolution2D(64,3,3, activation='relu'),
        MaxPooling2D(),
        MyLayer(input_shape=(64,4,4)), # MY LAYER
        Flatten(),
        BatchNormalization(),
        Dense(512, activation='relu'),
        BatchNormalization(),
        Dropout(0.5),
        Dense(10, activation='softmax')
        ])
    model.compile(Adam(), loss='categorical_crossentropy', metrics=['accuracy'])
    return model

model=get_my_model_2()

I have the error "'module' object is not callable":

> 
> /home/universal/anaconda3/envs/practicecourse2/mylayer.py in
> build(self, input_shape)
>      15                    #                   initializer='uniform',
>      16                    #                   trainable=True)
> ---> 17         self.W_init = np.random(input_shape)
>      18         self.W = K.variable(self.W_init, name="W")
>      19         self.trainable_weights = [self.W]
> 
> TypeError: 'module' object is not callable

What's wrong?

Thank you in advance

Added:

After fixing the "random" problem I have another error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-31-8e5ded840273> in <module>()
----> 1 model=get_my_model_2()
      2 model.summary()

<ipython-input-30-09ee1207017c> in get_my_model_2()
     20         BatchNormalization(),
     21         Dropout(0.5),
---> 22         Dense(10, activation='softmax')
     23         ])
     24     model.compile(Adam(), loss='categorical_crossentropy', metrics=['accuracy'])

/home/universal/anaconda3/envs/practicecourse2/lib/python2.7/site-packages/keras/models.pyc in __init__(self, layers, name)
    253 
    254         for layer in layers:
--> 255             self.add(layer)
    256 
    257     def add(self, layer):

/home/universal/anaconda3/envs/practicecourse2/lib/python2.7/site-packages/keras/models.pyc in add(self, layer)
    310                  output_shapes=[self.outputs[0]._keras_shape])
    311         else:
--> 312             output_tensor = layer(self.outputs[0])
    313             if type(output_tensor) is list:
    314                 raise Exception('All layers in a Sequential model '

/home/universal/anaconda3/envs/practicecourse2/lib/python2.7/site-packages/keras/engine/topology.pyc in __call__(self, x, mask)
    512         if inbound_layers:
    513             # this will call layer.build() if necessary
--> 514             self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
    515             input_added = True
    516 

/home/universal/anaconda3/envs/practicecourse2/lib/python2.7/site-packages/keras/engine/topology.pyc in add_inbound_node(self, inbound_layers, node_indices, tensor_indices)
    570         # creating the node automatically updates self.inbound_nodes
    571         # as well as outbound_nodes on inbound layers.
--> 572         Node.create_node(self, inbound_layers, node_indices, tensor_indices)
    573 
    574     def get_output_shape_for(self, input_shape):

/home/universal/anaconda3/envs/practicecourse2/lib/python2.7/site-packages/keras/engine/topology.pyc in create_node(cls, outbound_layer, inbound_layers, node_indices, tensor_indices)
    147 
    148         if len(input_tensors) == 1:
--> 149             output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
    150             output_masks = to_list(outbound_layer.compute_mask(input_tensors[0], input_masks[0]))
    151             # TODO: try to auto-infer shape if exception is raised by get_output_shape_for

TypeError: call() got an unexpected keyword argument 'mask'

It seems to me that there is still sth wrong with my custom layer

0 Answers
Related