密集层 Keras 中的输出维度
Dimension of output in Dense layer Keras
我有以下型号的样品
from tensorflow.keras import models
from tensorflow.keras import layers
sample_model = models.Sequential()
sample_model.add(layers.Dense(32, input_shape=(4,)))
sample_model.add(layers.Dense(16, input_shape = (44,)))
sample_model.compile(loss="binary_crossentropy",
optimizer="adam", metrics = ["accuracy"])
模型的IP:
sam_x = np.random.rand(10,4)
sam_y = np.array([0,1,1,0,1,0,0,1,0,1,])
sample_model.fit(sam_x,sam_y)
令人困惑的是 fit
应该抛出 shape mismatch
错误,因为 2nd Dense Layer
的 expected_input_shape
给出为 (None,44)
但是 output
对于 1st Dense Layer
(这是 2nd Dense Layer
的输入)将具有 (None,32)
的形状。但是它 运行 成功了。
我不明白为什么没有错误。任何澄清都会有所帮助
我认为 Keras 将创建(或保留创建)一个额外的输入层 - 但是当使用 model.add()
添加第二个密集层时,它将自动连接到之前的层,因此额外的输入层保持未连接并且 不是模型的一部分 。
(我同意 Keras 暗示未连接的层会很好,我有时会在使用功能 API 并更改输入时创建未连接的层。Keras 不会提醒我我已经跳了几层,我只是想知道为什么 summary()
这么短...)
input_shape
关键字参数仅对 Sequential
的第一层有效。其他层的输入形状将从它们的前一层导出。
tf.keras.layers.InputShape
的文档中暗示了该行为:
When using InputLayer with Keras Sequential model, it can be skipped by moving the input_shape parameter to the first layer after the InputLayer.
并在 the Sequential Model guide.
可以通过查看 Sequential.add
method 的来源来确认行为:
if not self._layers:
if isinstance(layer, input_layer.InputLayer):
# Case where the user passes an Input or InputLayer layer via `add`.
set_inputs = True
else:
batch_shape, dtype = training_utils.get_input_shape_and_dtype(layer)
if batch_shape:
# Instantiate an input layer.
x = input_layer.Input(
batch_shape=batch_shape, dtype=dtype, name=layer.name + '_input')
# This will build the current layer
# and create the node connecting the current layer
# to the input layer we just created.
layer(x)
set_inputs = True
如果模型中还没有层,则会将 Input
添加到模型中,其形状来自模型的第一层。 只有如果模型中还没有层,才会这样做。
该形状要么完全已知(如果 input_shape
已传递到模型的第一层),要么在模型构建后完全已知(例如,调用 model.build(input_shape)
).
问题是检查第一层模型的input shape
后,不会检查或处理里面声明的其他input shape
那个相同的模型。例如,如果您按以下方式编写模型
sample_model.add(layers.Dense(32, input_shape=(4,)))
sample_model.add(layers.Dense(16, input_shape = (44,)))
sample_model.add(layers.Dense(8, input_shape = (32,)))
程序将始终检查第一个声明的 input shape
层并丢弃其余层。所以,如果你用 input_shape = (44,)
开始你的第一层,你需要将准确的特征数字作为输入传递给你的模型,例如:
sam_x = np.random.rand(10,44)
sam_y = np.array([0,1,1,0,1,0,0,1,0,1,])
sample_model.fit(sam_x,sam_y)
此外,如果您查看 Functional API,与 Sequential 模型不同,您必须创建并定义一个指定输入数据形状的独立 Input
层。它不可学习,而只是一个规范层。它是模型输入数据的一种网关。这意味着即使我们在其他层中定义 input_shape
,它们也会被丢弃。例如:
nputs = keras.Input(shape=(4,))
dense = layers.Dense(64, input_shape=(8,)) # dicard input_shape
x = dense(inputs)
x = layers.Dense(64, input_shape=(16,))(x) # dicard input_shape
outputs = layers.Dense(10)(x)
model = keras.Model(inputs=inputs, outputs=outputs, name="mnist_model")
这是一个使用 Conv2D
和 MNIST 的更复杂的示例。
encoder_input = keras.Input(shape=(28, 28, 1),)
x = layers.Conv2D(16, 3, activation="relu", input_shape=[32,32,3])(encoder_input)
x = layers.Conv2D(32, 3, activation="relu", input_shape=[64,64,3])(x)
x = layers.MaxPooling2D(3)(x)
x = layers.Conv2D(32, 3, activation="relu", input_shape=[224,321,3])(x)
x = layers.Conv2D(16, 3, activation="relu", input_shape=[420,32,3])(x)
x = layers.GlobalMaxPooling2D()(x)
out = layers.Dense(10, activation='softmax')(x)
encoder = keras.Model(encoder_input, out, name="encoder")
encoder.summary()
Model: "encoder"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_15 (InputLayer) [(None, 28, 28, 1)] 0
_________________________________________________________________
conv2d_8 (Conv2D) (None, 26, 26, 16) 160
_________________________________________________________________
conv2d_9 (Conv2D) (None, 24, 24, 32) 4640
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 8, 8, 32) 0
_________________________________________________________________
conv2d_10 (Conv2D) (None, 6, 6, 32) 9248
_________________________________________________________________
conv2d_11 (Conv2D) (None, 4, 4, 16) 4624
_________________________________________________________________
global_max_pooling2d_2 (Glob (None, 16) 0
_________________________________________________________________
dense_56 (Dense) (None, 10) 170
=================================================================
Total params: 18,842
Trainable params: 18,842
Non-trainable params: 0
def pre_process(image, label):
return (image / 256)[...,None].astype('float32'),
tf.keras.utils.to_categorical(label, num_classes=10)
(x, y), (_, _) = tf.keras.datasets.mnist.load_data('mnist')
encoder.compile(
loss = tf.keras.losses.CategoricalCrossentropy(),
metrics = tf.keras.metrics.CategoricalAccuracy(),
optimizer = tf.keras.optimizers.Adam())
encoder.fit(x, y, batch_size=256)
4s 14ms/step - loss: 1.4303 - categorical_accuracy: 0.5279
我有以下型号的样品
from tensorflow.keras import models
from tensorflow.keras import layers
sample_model = models.Sequential()
sample_model.add(layers.Dense(32, input_shape=(4,)))
sample_model.add(layers.Dense(16, input_shape = (44,)))
sample_model.compile(loss="binary_crossentropy",
optimizer="adam", metrics = ["accuracy"])
模型的IP:
sam_x = np.random.rand(10,4)
sam_y = np.array([0,1,1,0,1,0,0,1,0,1,])
sample_model.fit(sam_x,sam_y)
令人困惑的是 fit
应该抛出 shape mismatch
错误,因为 2nd Dense Layer
的 expected_input_shape
给出为 (None,44)
但是 output
对于 1st Dense Layer
(这是 2nd Dense Layer
的输入)将具有 (None,32)
的形状。但是它 运行 成功了。
我不明白为什么没有错误。任何澄清都会有所帮助
我认为 Keras 将创建(或保留创建)一个额外的输入层 - 但是当使用 model.add()
添加第二个密集层时,它将自动连接到之前的层,因此额外的输入层保持未连接并且 不是模型的一部分 。
(我同意 Keras 暗示未连接的层会很好,我有时会在使用功能 API 并更改输入时创建未连接的层。Keras 不会提醒我我已经跳了几层,我只是想知道为什么 summary()
这么短...)
input_shape
关键字参数仅对 Sequential
的第一层有效。其他层的输入形状将从它们的前一层导出。
tf.keras.layers.InputShape
的文档中暗示了该行为:
When using InputLayer with Keras Sequential model, it can be skipped by moving the input_shape parameter to the first layer after the InputLayer.
并在 the Sequential Model guide.
可以通过查看 Sequential.add
method 的来源来确认行为:
if not self._layers:
if isinstance(layer, input_layer.InputLayer):
# Case where the user passes an Input or InputLayer layer via `add`.
set_inputs = True
else:
batch_shape, dtype = training_utils.get_input_shape_and_dtype(layer)
if batch_shape:
# Instantiate an input layer.
x = input_layer.Input(
batch_shape=batch_shape, dtype=dtype, name=layer.name + '_input')
# This will build the current layer
# and create the node connecting the current layer
# to the input layer we just created.
layer(x)
set_inputs = True
如果模型中还没有层,则会将 Input
添加到模型中,其形状来自模型的第一层。 只有如果模型中还没有层,才会这样做。
该形状要么完全已知(如果 input_shape
已传递到模型的第一层),要么在模型构建后完全已知(例如,调用 model.build(input_shape)
).
问题是检查第一层模型的input shape
后,不会检查或处理里面声明的其他input shape
那个相同的模型。例如,如果您按以下方式编写模型
sample_model.add(layers.Dense(32, input_shape=(4,)))
sample_model.add(layers.Dense(16, input_shape = (44,)))
sample_model.add(layers.Dense(8, input_shape = (32,)))
程序将始终检查第一个声明的 input shape
层并丢弃其余层。所以,如果你用 input_shape = (44,)
开始你的第一层,你需要将准确的特征数字作为输入传递给你的模型,例如:
sam_x = np.random.rand(10,44)
sam_y = np.array([0,1,1,0,1,0,0,1,0,1,])
sample_model.fit(sam_x,sam_y)
此外,如果您查看 Functional API,与 Sequential 模型不同,您必须创建并定义一个指定输入数据形状的独立 Input
层。它不可学习,而只是一个规范层。它是模型输入数据的一种网关。这意味着即使我们在其他层中定义 input_shape
,它们也会被丢弃。例如:
nputs = keras.Input(shape=(4,))
dense = layers.Dense(64, input_shape=(8,)) # dicard input_shape
x = dense(inputs)
x = layers.Dense(64, input_shape=(16,))(x) # dicard input_shape
outputs = layers.Dense(10)(x)
model = keras.Model(inputs=inputs, outputs=outputs, name="mnist_model")
这是一个使用 Conv2D
和 MNIST 的更复杂的示例。
encoder_input = keras.Input(shape=(28, 28, 1),)
x = layers.Conv2D(16, 3, activation="relu", input_shape=[32,32,3])(encoder_input)
x = layers.Conv2D(32, 3, activation="relu", input_shape=[64,64,3])(x)
x = layers.MaxPooling2D(3)(x)
x = layers.Conv2D(32, 3, activation="relu", input_shape=[224,321,3])(x)
x = layers.Conv2D(16, 3, activation="relu", input_shape=[420,32,3])(x)
x = layers.GlobalMaxPooling2D()(x)
out = layers.Dense(10, activation='softmax')(x)
encoder = keras.Model(encoder_input, out, name="encoder")
encoder.summary()
Model: "encoder"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_15 (InputLayer) [(None, 28, 28, 1)] 0
_________________________________________________________________
conv2d_8 (Conv2D) (None, 26, 26, 16) 160
_________________________________________________________________
conv2d_9 (Conv2D) (None, 24, 24, 32) 4640
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 8, 8, 32) 0
_________________________________________________________________
conv2d_10 (Conv2D) (None, 6, 6, 32) 9248
_________________________________________________________________
conv2d_11 (Conv2D) (None, 4, 4, 16) 4624
_________________________________________________________________
global_max_pooling2d_2 (Glob (None, 16) 0
_________________________________________________________________
dense_56 (Dense) (None, 10) 170
=================================================================
Total params: 18,842
Trainable params: 18,842
Non-trainable params: 0
def pre_process(image, label):
return (image / 256)[...,None].astype('float32'),
tf.keras.utils.to_categorical(label, num_classes=10)
(x, y), (_, _) = tf.keras.datasets.mnist.load_data('mnist')
encoder.compile(
loss = tf.keras.losses.CategoricalCrossentropy(),
metrics = tf.keras.metrics.CategoricalAccuracy(),
optimizer = tf.keras.optimizers.Adam())
encoder.fit(x, y, batch_size=256)
4s 14ms/step - loss: 1.4303 - categorical_accuracy: 0.5279