为什么在 Keras 层的方法调用中批大小为 None?

nbr*_*bro 4 keras tensorflow

我正在 Keras 中实现一个自定义层。如果我打印传递给call方法的输入的形状,我会得到None第一个元素。这是为什么?第一个元素不应该是批量大小吗?

def call(self, x):
    print(x.shape)  # (None, ...)
Run Code Online (Sandbox Code Playgroud)

当我打电话时model.fit,我正在传递批量大小

batch_size = 50
model.fit(x_train, y_train, ..., batch_size=batch_size)
Run Code Online (Sandbox Code Playgroud)

那么,该方法call实际何时被调用?在方法中获取批量大小的推荐方法是call什么?

Rya*_*ira 7

我遇到了同样的问题,发现使用tf.shape(your_variable)而不是your_variable.shape解决了问题。正如tf.shape(your_variable)稍后调用 fit 函数时动态评估的那样。

参考 https://github.com/tensorflow/tensorflow/issues/36991#issuecomment-590448880

要获取整数值,请考虑 output_shape 变量。最小工作示例

import tensorflow as tf

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.InputLayer((2,), batch_size=50))
model.add(tf.keras.layers.Dense(units=2, input_shape=(2, )))

print(model.output_shape)
print(type(model.output_shape[0]), type(model.output_shape[1]))
Run Code Online (Sandbox Code Playgroud)

输出:

(50, 2)
<class 'int'> <class 'int'>
Run Code Online (Sandbox Code Playgroud)


Vla*_*lad 6

None意味着它是一个动态的形状。根据您选择的批量大小,它可以采用任何值。

默认情况下定义模型时,它被定义为支持您可以选择的任何批量大小。这就是None手段。在TensorFlow 1.*模型的输入中是tf.placeholder().

如果您不使用keras.InputLayer()指定的批量大小None,默认情况下您将获得第一个维度:

import tensorflow as tf

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(units=2, input_shape=(2, )))
print(model.inputs[0].get_shape().as_list()) # [None, 2]
print(model.inputs[0].op.type == 'Placeholder') # True
Run Code Online (Sandbox Code Playgroud)

当您使用keras.InputLayer()指定的批量大小时,您可以定义具有固定批量大小的输入占位符:

import tensorflow as tf

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.InputLayer((2,), batch_size=50))
model.add(tf.keras.layers.Dense(units=2, input_shape=(2, )))
print(model.inputs[0].get_shape().as_list()) # [50, 2]
print(model.inputs[0].op.type == 'Placeholder') # True
Run Code Online (Sandbox Code Playgroud)

当您为model.fit()方法指定批量大小时,这些输入占位符已被定义,您无法修改它们的形状。的批次大小model.fit()仅用于拆分您提供给批次的数据。

如果您使用批量大小定义输入层,2然后将批量大小的不同值传递给model.fit()您将获得的方法ValueError

import tensorflow as tf
import numpy as np

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.InputLayer((2,), batch_size=2)) # <--batch_size==2
model.add(tf.keras.layers.Dense(units=2, input_shape=(2, )))
model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss='categorical_crossentropy')
x_train = np.random.normal(size=(10, 2))
y_train = np.array([[0, 1] for _ in range(10)])

model.fit(x_train, y_train, batch_size=3) # <--batch_size==3
Run Code Online (Sandbox Code Playgroud)

这将提高: ValueError: Thebatch_sizeargument value 3 is incompatible with the specified batch size of your Input Layer: 2

  • 你没有回答我的问题。何时调用“call”?在“call”方法中获取批量大小的推荐方法是什么?为什么我们甚至需要或需要第一维的动态大小?第一个维度不能直接显式传递吗? (3认同)