python - 在 Tensorflow 2.0 中使用层子类化在我的自定义层中出现此错误“必须始终传递 `Layer.call` 的第一个参数。”
问题描述
我使用 Tensorflow 2.0 图层子类化的图层制作了这个自定义图层。我正在尝试制作一层残留块。但是当我通过顺序 API 在我的模型中添加这个自定义层时,我得到了以下错误。
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)
但是当我初始化这一层时,我得到了错误。
test_model = tf.keras.Sequential([ResidualBlock(input_shape=(28, 28, 1), name="residual_block")])
test_model.summary()
我的错误日志:
---------------------------------------------------------------------------
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.
解决方案
在调用方法期间,将批处理规范的前向传递更改为 h=self.bn_1(inputs)
. 由于您要传递training=True
整个层,因此 tensorflow 将自动为它的所有子层维护相同的标志,您不需要为每个子层显式传递它。但是,如果您的应用程序想要以不同于其他层的方式控制批规范,请使用h=self.bn_1(inputs, training=True)
. 而且您的最终退货声明格式不正确,应该像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)))
因此,一旦使用 tf.ones() 的示例输入调用您的模型,就会调用 build 来创建批处理规范和卷积层。对于 conv 层,您通过索引到最后一个维度来使用与输入相同的过滤器数量
推荐阅读
- python - 无法在 Scrapy 中找到选择器的路径
- excel - VBA Excel 上的多个过滤器不起作用
- c# - 如何将特定数据表列中的值添加到 datagridview
- c# - 组合框文本在 UWP 中不可见?
- sql - 默认与 LLAP Hive 连接 HiveQL 语法,区别?
- jquery - 如何通过jquery检测选择选项更改
- azure - 自动删除 Microsoft Azure 应用服务中的 Tomcat 日志
- python - TensorFlow 对象检测运行非常缓慢
- android - 如何为按日期排序的帖子(如instagram)构建firestore数据库?
- python - Python中第一个键具有默认值的嵌套字典