[英]TensorFlow2 / Keras: input_shape seems to not have an effect when subclassing keras.Model
When accessing the output of an intermediate layer I always received the error message: AttributeError: Layer l has no inbound nodes.
访问中间层的输出时,我总是收到错误消息:
AttributeError: Layer l has no inbound nodes.
I read that one has to determine the input_shape
in the entry layer to overcome this problem:我读到
input_shape
在入口层确定input_shape
才能克服这个问题:
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
self.flatten = tf.keras.layers.Flatten(input_shape=(28, 28))
self.dense = tf.keras.layers.Dense(64, activation=tf.nn.relu)
self.classifier = tf.keras.layers.Dense(10, name='classifier')
def call(self, inputs):
x = self.flatten(inputs)
x = self.dense(x)
return self.classifier(x)
Unfortunately, this didn't work for me.不幸的是,这对我不起作用。
After this failed attempt, I tried to reconstruct my model using tf.keras.Sequential
and again specified the input_shape
for the first layer:在这次失败的尝试之后,我尝试使用
tf.keras.Sequential
重建我的模型,并再次为第一层指定input_shape
:
tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(64, activation=tf.nn.relu),
tf.keras.layers.Dense(10, name='classifier')
])
This, on the other hand worked!另一方面,这有效!
So I asked myself why the first approach didn't work.所以我问自己为什么第一种方法不起作用。 To test this I specified arbitrary/wrong
input_shapes
for the subclassed model like this:为了测试这一点,我为子类模型指定了任意/错误的
input_shapes
,如下所示:
class WrongInputShapeModel(tf.keras.Model):
def __init__(self):
super(WrongInputShapeModel, self).__init__()
self.flatten = tf.keras.layers.Flatten(input_shape=(42, 42, 42))
# ...
I noticed that this model still functioned with MNIST (which has 28x28 images).我注意到这个模型仍然可以与 MNIST(具有 28x28 图像)一起使用。 That let me to believe that the keyword
input_shape
has no effect when defining a model subclassing tf.keras.Model
.这让我相信关键字
input_shape
在定义模型子类化tf.keras.Model
。
Is this a bug, or am I missing something?这是一个错误,还是我错过了什么?
From your model subclassing code, it looks like you are not returning the model's forward-pass output.从您的模型子类化代码来看,您似乎没有返回模型的前向传递输出。 Maybe that's the reason it didn't work.
也许这就是它不起作用的原因。
This should work:这应该有效:
import tensorflow as tf
class MyModel(tf.keras.Model):
def __init__(self):
super().__init__()
self.flatten = tf.keras.layers.Flatten()
self.dense = tf.keras.layers.Dense(64, activation=tf.nn.relu)
self.classifier = tf.keras.layers.Dense(10, name='classifier', activation='softmax')
def call(self, inputs):
x = self.flatten(inputs)
x = self.dense(x)
return self.classifier(x)
And then, just as an example:然后,举个例子:
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
model = MyModel()
model.compile(optimizer=tf.keras.optimizers.Adam(1e-3), loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])
history = model.fit(x_train, y_train, epochs=5)
Now, Flatten
input shape is actually defined by the shape of the layer's input tensor, so it does not require an input_shape
argument.现在,
Flatten
输入形状实际上是由层的输入张量的形状定义的,因此它不需要input_shape
参数。 input_shape
is an attribute of Layer
, so you can pass it, but the layer's forward-pass doesn't use it. input_shape
是Layer
一个属性,所以你可以传递它,但是 layer 的 forward-pass 不使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.