如何在Keras中Conv2D和Dense层中数据形状发生变化?

正如标题所述。只有在使用以下代码时才有效:

x = Flatten()(x)

在卷积层和全连接层之间。

import numpy as npimport kerasfrom keras.models import Sequential, Modelfrom keras.layers import Dense, Dropout, Flatten, Inputfrom keras.layers import Conv2D, MaxPooling2Dfrom keras.optimizers import SGD# 生成虚拟数据x_train = np.random.random((100, 100, 100, 3))y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)#构建模型input_layer = Input(shape=(100, 100, 3))x = Conv2D(32, (3, 3), activation='relu')(input_layer)x = Dense(256, activation='relu')(x)x = Dense(10, activation='softmax')(x)model = Model(inputs=[input_layer],outputs=[x])#编译网络sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)model.compile(loss='categorical_crossentropy', optimizer=sgd)#训练网络model.fit(x_train, y_train, batch_size=32, epochs=10)

否则,我会收到以下错误:

Traceback (most recent call last):File "/home/michael/practice_example.py", line 44, in <module>    model.fit(x_train, y_train, batch_size=32, epochs=10)File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1435, in fit    batch_size=batch_size)File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1315, in _standardize_user_data    exception_prefix='target')File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 127, in _standardize_input_data    str(array.shape))ValueError: Error when checking target: expected dense_2 to have 4 dimensions, but got array with shape (100, 10)

为什么在没有flatten()层的情况下输出会有4个维度?


回答:

根据Keras文档,

Conv2D输出形状

如果data_format=’channels_first’,则为形状为(samples, filters, new_rows, new_cols)的4D张量;如果data_format=’channels_last’,则为形状为(samples, new_rows, new_cols, filters)的4D张量。由于填充,rows和cols的值可能会发生变化。

由于您使用的是channels_last,层输出的形状将是:

# shape=(100, 100, 100, 3)x = Conv2D(32, (3, 3), activation='relu')(input_layer)# shape=(100, row, col, 32)x = Flatten()(x)# shape=(100, row*col*32)    x = Dense(256, activation='relu')(x)# shape=(100, 256)x = Dense(10, activation='softmax')(x)# shape=(100, 10)

错误解释(已编辑,感谢@Marcin)

使用Dense层将4D张量(shape=(100, row, col, 32))连接到2D张量(shape=(100, 256))仍然会形成一个4D张量(shape=(100, row, col, 256)),这不是您想要的。

# shape=(100, 100, 100, 3)x = Conv2D(32, (3, 3), activation='relu')(input_layer)# shape=(100, row, col, 32)x = Dense(256, activation='relu')(x)# shape=(100, row, col, 256)x = Dense(10, activation='softmax')(x)# shape=(100, row, col, 10)

当输出4D张量与目标2D张量不匹配时,就会发生错误。

这就是为什么您需要一个Flatten层来将其从4D展平到2D。

参考资料

Conv2DDense

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注