Getting this error in my custom layer using layer subclassing in Tensorflow 2.0 "The first argument to `Layer.call` must always be passed."
During the call method change the forward pass of batch norms to h=self.bn_1(inputs)
. Since you are passing training=True
for the whole layer tensorflow will automatically take care of maintaining the same flag for all of it's sublayers and you don't need to pass it explicitly for each of them. But if your application is such that you want to control batch norm differently compared to other layers use h=self.bn_1(inputs, training=True)
. And your final return statement is not in correct format and should be like Add()([inputs, h])
class ResidualBlock(Layer):
def __init__(self, **kwargs):
super(ResidualBlock, self).__init__(**kwargs)
def build(self, input_shape):
"""
This method should build the layers according to the above specification. Make sure
to use the input_shape argument to get the correct number of filters, and to set the
input_shape of the first layer in the block.
"""
self.bn_1 = BatchNormalization(input_shape=input_shape)
self.conv_1 = Conv2D(input_shape[3],(3,3), padding='SAME')
self.bn_2 = BatchNormalization()
self.conv_2 = Conv2D(input_shape[3],(3,3), padding='SAME')
def call(self, inputs, training=False):
"""
This method should contain the code for calling the layer according to the above
specification, using the layer objects set up in the build method.
"""
h = self.bn_1(inputs)
h = tf.nn.relu(h)
h = self.conv_1(h)
h = self.bn_2(h)
h = tf.nn.relu(h)
h = self.conv_2(h)
return Add()([inputs, h])
pk = ResidualBlock()
model = tf.keras.Sequential([pk])
model(tf.ones((1, 28, 28, 3)))
So once your model is called with example input of tf.ones(), build will be called to create the batch norm and convolution layers. For conv layer you are using the number of filters same as the input by indexing into the last dimension
Abhinav Prakash
Updated on June 05, 2022Comments
-
Abhinav Prakash almost 2 years
I've made this custom layer using layer using Tensorflow 2.0 layer subclassing. I'm trying to make a layer of residual block. But when I add this custom layer in my model through sequential API I'm getting the below error.
class ResidualBlock(Layer): def __init__(self, **kwargs): super(ResidualBlock, self).__init__(**kwargs) def build(self, input_shape): """ This method should build the layers according to the above specification. Make sure to use the input_shape argument to get the correct number of filters, and to set the input_shape of the first layer in the block. """ self.bn_1 = BatchNormalization(input_shape=input_shape) self.conv_1 = Conv2D( input_shape[0],(3,3), padding='SAME') self.bn_2 = BatchNormalization() self.conv_2 = Conv2D( input_shape[0],(3,3), padding='SAME') def call(self, inputs, training=False): """ This method should contain the code for calling the layer according to the above specification, using the layer objects set up in the build method. """ h = self.bn_1(training=True)(inputs) h = tf.nn.relu(h) h = self.conv_1(h) h = self.bn_2(training=True)(h) h = tf.nn.relu(h) h = self.conv_2(h) return Add(inputs, h)
But when I initialize this layer I'm getting the error.
test_model = tf.keras.Sequential([ResidualBlock(input_shape=(28, 28, 1), name="residual_block")]) test_model.summary()
My error logs:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-13-991ed1d78e4b> in <module>() 1 # Test your custom layer - the following should create a model using your layer 2 ----> 3 test_model = tf.keras.Sequential([ResidualBlock(input_shape=(28, 28, 1), name="residual_block")]) 4 test_model.summary() 5 frames /usr/local/lib/python3.6/dist-packages/tensorflow/python/autograph/impl/api.py in wrapper(*args, **kwargs) 263 except Exception as e: # pylint:disable=broad-except 264 if hasattr(e, 'ag_error_metadata'): --> 265 raise e.ag_error_metadata.to_exception(e) 266 else: 267 raise ValueError: in user code: <ipython-input-12-3beea3ca10b0>:32 call * h = self.bn_1(training=True)(inputs) /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/base_layer.py:800 __call__ ** 'The first argument to `Layer.call` must always be passed.') ValueError: The first argument to `Layer.call` must always be passed.
-
Abhinav Prakash almost 4 yearsI've changed my according to your question but now I'm facing new error." TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'"
-
gouthamvgk almost 4 yearsRemove input_shape from your init function. If you are using build function then the first time you call your model with some input, tensorflow will consider that input tensor shape inside the build function. You shouldn't pass the input_shape manually in the init. Also in your build function you are using input_shape[0] which is batch dimension, correct it according to your needs.
-
Abhinav Prakash almost 4 yearsActually this are the instructions that I've to follow.
-
Abhinav Prakash almost 4 yearsactually I've to follow certain instructions. Kindly have a look into my colab notebook: colab.research.google.com/drive/… . Thanks
-
gouthamvgk almost 4 yearssee the changed answer
-
Abhinav Prakash almost 4 yearsGetting again error while executing in this manner: pk = ResidualBlock() model = tf.keras.Sequential([pk(input_shape=(28, 28, 1), name="residual_block")]) model.summary()
-
gouthamvgk almost 4 yearspk = ResidualBlock() model = tf.keras.Sequential([pk]) You create the layer without using input_shape and directly use it in sequential