我正在建立一个图像分类器模型,该模型使用CNN对手写数字MNIST 28x28灰度图像进行分类 这是我的图层定义
model = keras.Sequential()
model.add(keras.layers.Conv2D(64,(3,3),activation='relu',input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D((2,2)))
model.add(keras.layers.Conv2D(64,(3,3),activation='relu'))
model.add(keras.layers.MaxPool2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(200,activation='relu'))
model.add(keras.layers.Dense(10,activation='softmax'))
但是当我拟合模型时出现此错误
ValueError: Input 0 of layer sequential_6 is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: [32, 28, 28]
我也想知道为什么我们应该在Conv2D图层的input_shape中提到1。图像的形状是28x28,但是我们应该在那里提到1。
答案 0 :(得分:2)
应该起作用的最小更改是更改行:
model.add(keras.layers.Conv2D(64,(3,3),activation='relu',input_shape=(28,28,1)))
为此,删除1
:
model.add(keras.layers.Conv2D(64,(3,3),activation='relu',input_shape=(28,28)))
出现错误的原因是您输入的图像为28x28,并且您投放到网络中的批量大小为32张图像,因此是一个数组[32,28,28]。不幸的是,我看不到您如何将输入提供给网络。但是您当前的代码期望的是一个尺寸为[32,28,28,1]的数组。如果那是您可以操纵的numpy数组,只需将reshape()
设置为这样的维度就可以解决问题。
我上面建议的是反过来做,让网络期望尺寸为[28,28]的2D数组而不是尺寸为[28,28,1]的3D数组的每个图像
更新:
您提供了以下代码更改来使其起作用:
train_image=train_image.reshape(60000, 28, 28, 1)
train_image=train_image / 255.0
test_image = test_image.reshape(10000, 28, 28, 1)
test_image=test_image/255.0
这是因为您的输入图像位于一个巨大的numpy数组中,并且您直接将其与模型拟合。模型拟合功能将从其数组的第一个维度中选择“张量”,并为每个训练步骤创建一批。批处理大小为32,因此它将隐式创建一个形状数组(32、28、28、1)并将其向下传递到各层。仅从原始数组复制第二到第四维。
reshape()
命令用于更改数组的尺寸。重整前的原始数组为(60000,28,28),如果将其按单个数字序列进行布局,则将有6000x28x28个浮点数。 reshape()
要做的是拾取这些数字并将它们填充到(60000,28,28,1)数组中,该数组期望60000x28x28x1个数字,以便可以准确填充。