简体   繁体   English

在 Tensorflow 2.0 中使用层子类化在我的自定义层中出现此错误“必须始终传递 `Layer.call` 的第一个参数。”

[英]Getting this error in my custom layer using layer subclassing in Tensorflow 2.0 “The first argument to `Layer.call` must always be passed.”

I've made this custom layer using layer using Tensorflow 2.0 layer subclassing.我已经使用 Tensorflow 2.0 层子类化的层制作了这个自定义层。 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.但是,当我通过顺序 API 在我的 model 中添加此自定义层时,我收到以下错误。

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.

During the call method change the forward pass of batch norms to h=self.bn_1(inputs) .在调用方法期间,将批处理规范的前向传递更改为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.由于您正在为整个层传递training=True tensorflow 将自动为所有子层维护相同的标志,您不需要为每个子层显式传递它。 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) .但是,如果您的应用程序想要以不同于其他层的方式控制批规范,请使用h=self.bn_1(inputs, training=True) And your final return statement is not in correct format and should be like Add()([inputs, h])并且您的最终返回语句格式不正确,应该类似于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.因此,一旦使用 tf.ones() 的示例输入调用 model,就会调用 build 来创建批处理规范和卷积层。 For conv layer you are using the number of filters same as the input by indexing into the last dimension对于 conv 层,您通过索引到最后一个维度来使用与输入相同的过滤器数量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误:必须始终传递“Layer.call”的第一个参数 - ERROR:The first argument to `Layer.call` must always be passed 如何解决“必须始终传递 `Layer.call` 的第一个参数。” 问题 - How to solve 'The first argument to `Layer.call` must always be passed.' issue ValueError:必须始终传递“Layer.call”的第一个参数 - ValueError: The first argument to `Layer.call` must always be passed `Layer.call` 的第一个参数必须始终传递 - The first argument to `Layer.call` must always be passed Scikit-learn cross_val_score 抛出 ValueError:必须始终传递“Layer.call”的第一个参数 - Scikit-learn cross_val_score throws ValueError: The first argument to `Layer.call` must always be passed 在 Tensorflow 2.0 中使用我的自定义嵌入层时出错 - Getting error while using my custom embedding layer in Tensorflow 2.0 Layer.call 没有急切地执行 - Layer.call is not executed eagerly ValueError: `multiple` 必须是 ['layer', 'stack', 'fill', 'dodge'] 之一,但 s 已通过。 - ValueError: `multiple` must be one of ['layer', 'stack', 'fill', 'dodge'], but s was passed.` 在张量流中创建自定义层时出错 - Error creating a custom layer in tensorflow 将连接层添加到 TensorFlow 2.0(使用注意) - Adding a Concatenated layer to TensorFlow 2.0 (using Attention)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM