Keras Digit数据集错误:预期conv2d_input具有4维,但数组的形状为(60000,28,28)

时间:2019-10-27 03:40:35

标签: python tensorflow keras deep-learning

Keras Digit数据集中的错误:ValueError:检查输入时出错:预期conv2d_input具有4维,但数组的形状为(60000,28,28)。我不确定发生了什么,为什么

我需要4个尺寸?我很肯定他们是28x28的图片。我该怎么办?

   (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images/255
test_images = test_images/255

classes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

model = keras.Sequential([
    tf.keras.layers.Conv2D(56, (3, 3), activation='relu', input_shape=(28, 28)),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(56, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(784, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(train_images, train_labels, epochs=5)

test_loss, test_acc = model.evaluate(test_images, test_labels)

3 个答案:

答案 0 :(得分:1)

在将数据传递到网络之前,使用np.expand_dims将第四维(即通道维)添加到输入数据中。通过这种方式,您将可以使用Conv2D

train_images = np.expand_dims(train_images, axis=-1)
test_images = np.expand_dims(test_images, axis=-1)

print(train_images.shape()) # (60000, 28, 28, 1)
print(test_images.shape()) # (10000, 28, 28, 1)

答案 1 :(得分:1)

您需要进行两个小更改。 首先,您需要将图像转换为NHWC格式(批量大小,高度,宽度,通道)的4D张量,这是Conv2D所期望的。但是,当前图像数据集中没有通道尺寸。通道4的尺寸可以如下添加

train_images = np.expand_dims(train_images, axis=-1)  # (60000, 28, 28, 1)
test_images = np.expand_dims(test_images, axis=-1) # (10000, 28, 28, 1)

第二,您需要将input_shape更改为指定编号的模型。输入图像的通道数。由于您的图片具有单通道输入,因此图片的形状应为(28, 28, 1)

tf.keras.layers.Conv2D(56, (3, 3), activation='relu', input_shape=(28, 28, 1))

答案 2 :(得分:0)

感谢@ bit01指出了我的错误,我已经相应地更新了答案-

您不能在无深度或通道图像上使用2D方法。您的图像不包含任何具有28 X 28形状的通道,Conv2D是为具有grey_scale(256,256,1)或RGB(256,256,3)通道的图像或具有alpha通道(256,256,4)的png图像定义的。没有任何深度,它将无法用于2D矩阵。

所以您有两种方法可以解决此问题:

  1. 将卷积和最大池化层从2D方法切换到1D方法。

像这样-

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images/255
test_images = test_images/255

classes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

model = keras.Sequential([
    tf.keras.layers.Conv1D(56, 3, activation='relu', input_shape=(28, 28)),
    tf.keras.layers.MaxPooling1D(2, 2),
    tf.keras.layers.Conv1D(56, 3, activation='relu'),
    tf.keras.layers.MaxPooling1D(2, 2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(784, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(train_images, train_labels, epochs=5)

test_loss, test_acc = model.evaluate(test_images, test_labels)
  1. 向数据集中添加一个额外的尺寸(使其为28 X 28-> 28 X 28 X1)。

像这样-

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

train_images = np.expand_dims(train_images, axis=-1)  # (60000, 28, 28, 1)
test_images = np.expand_dims(test_images, axis=-1) # (10000, 28, 28, 1)

train_images = train_images/255
test_images = test_images/255

#train_images.shape, test_images.shape
classes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']


input_layer = keras.layers.Input(shape=(28, 28, 1), name='image_input')
conv1 = keras.layers.Conv2D(56, (3,3), activation='relu')(input_layer)
pool1 = keras.layers.MaxPooling2D(2, 2)(conv1)
conv2 = keras.layers.Conv2D(56, (3,3), activation='relu')(pool1)
pool2 = keras.layers.MaxPooling2D(2, 2)(conv2)
flatten = keras.layers.Flatten()(pool2)
dense1 = keras.layers.Dense(784, activation='relu')(flatten)
output_layer = keras.layers.Dense(10, activation='softmax')(dense1)

model = keras.models.Model(inputs=input_layer, outputs=output_layer, name='my_model')
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(train_images, train_labels, epochs=5)

test_loss, test_acc = model.evaluate(test_images, test_labels)