检查模型输入时出错:预期的 convolution2d_input_1 有 4 个维度,但得到了形状为 (32, 32, 3) 的数组

Posted

技术标签:

【中文标题】检查模型输入时出错:预期的 convolution2d_input_1 有 4 个维度,但得到了形状为 (32, 32, 3) 的数组【英文标题】:Error when checking model input: expected convolution2d_input_1 to have 4 dimensions, but got array with shape (32, 32, 3) 【发布时间】:2017-05-24 15:23:00 【问题描述】:

我想从以下层开始训练一个深度网络:

model = Sequential()
model.add(Conv2D(32, 3, 3, input_shape=(32, 32, 3)))

使用

history = model.fit_generator(get_training_data(),
                samples_per_epoch=1, nb_epoch=1,nb_val_samples=5,
                verbose=1,validation_data=get_validation_data()

使用以下生成器:

def get_training_data(self):
     while 1:
        for i in range(1,5):
            image = self.X_train[i]
            label = self.Y_train[i]
            yield (image,label)

(验证生成器看起来很相似)。

在训练期间,我收到错误:

Error when checking model input: expected convolution2d_input_1 to have 4 
dimensions, but got array with shape (32, 32, 3)

第一层怎么会这样

 model.add(Conv2D(32, 3, 3, input_shape=(32, 32, 3)))

?

【问题讨论】:

你是怎么解决的? 只需在图像数据列表周围添加 np.asarray() 即可。这会将您提供的列表调整为预期的大小。即使您正在预测单个图像数据,也将其包含在列表和 np.asarray() 中。 【参考方案1】:

您定义的输入形状是单个样本的形状。模型本身需要一些样本数组作为输入(即使它是一个长度为 1 的数组)。

您的输出确实应该是 4-d,第一个维度来枚举样本。即对于单个图像,您应该返回 (1, 32, 32, 3) 的形状。

您可以在“Convolution2D”/“输入形状”下找到更多信息here

编辑:根据 Danny 在下面的评论,如果您希望批量大小为 1,可以使用以下方法添加缺少的维度:

image = np.expand_dims(image, axis=0)

【讨论】:

@AbhishekBhatia 你应该以同样的方式改变 x_ip_shape。 更改输入大小会导致错误更改为“输入 0 与层 conv2d_1 不兼容:预期 ndim=4,发现 ndim=5”。有人有帮助吗? 使用image = np.expand_dims(image, axis=0)) 添加额外的维度【参考方案2】:

遇到了同样的问题,没有一个答案对我有用。经过大量调试,我发现一张图像的大小小于32。这会导致损坏的数组具有错误的维度和上述错误。

要解决此问题,请确保所有图像具有正确的尺寸。

【讨论】:

【参考方案3】:

是的,它接受四个参数的元组, 如果您的训练图像数(或其他)=6000, 图像尺寸=28x28 和灰度图像 您的参数为 (6000,28,28,1)

最后一个参数是 1 表示灰度图像,3 表示彩色图像。

【讨论】:

【参考方案4】:

我在使用 mnist 数据集时遇到了同样的错误,看起来像 X_train 的维度有问题。我添加了另一个维度,它解决了这个目的。

X_train,X_test,\ y_train,y_test = train_test_split(X_reshape, y_labels, train_size = 0.8, random_state = 42)

X_train = X_train.reshape(-1,28, 28, 1)

X_test = X_test.reshape(-1,28, 28, 1)

【讨论】:

【参考方案5】:

您应该简单地将以下转换应用于您的输入数据数组。

input_data = input_data.reshape((-1, image_side1, image_side2, channels))

【讨论】:

【参考方案6】:

可能非常微不足道,但我只是通过将输入转换为 numpy 数组来解决它。

对于神经网络架构,

    model = Sequential()
    model.add(Conv2D(32, (5, 5), activation="relu", input_shape=(32, 32, 3)))

输入时,

    n_train = len(train_y_raw)
    train_X = [train_X_raw[:,:,:,i] for i in range(n_train)]
    train_y = [train_y_raw[i][0] for i in range(n_train)]

我收到了错误,

但是当我把它改成,

   n_train = len(train_y_raw)
   train_X = np.asarray([train_X_raw[:,:,:,i] for i in range(n_train)])
   train_y = np.asarray([train_y_raw[i][0] for i in range(n_train)])

它解决了这个问题。

【讨论】:

【参考方案7】:

这取决于您实际订购数据的方式,如果它首先基于渠道,那么您应该重塑您的数据: x_train=x_train.reshape(x_train.shape[0],channel,width,height)

如果它的频道最后: x_train=s_train.reshape(x_train.shape[0],width,height,channel)

【讨论】:

【参考方案8】:

就像添加一个维度一样简单,所以我正在阅读 Siraj Rawal 在 CNN 代码部署教程中教授的教程,它在他的终端上运行,但相同的代码在我的终端上不运行,所以我对此进行了一些研究并解决了,我不知道这是否适合你们所有人。在这里我想出了解决方案;

给你带来问题的未解决的代码行:

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    print(x_train.shape)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols)
    input_shape = (img_rows, img_cols, 1)

解决的代码:

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    print(x_train.shape)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

如果对您有用,请在此处分享反馈。

【讨论】:

【参考方案9】:
x_train = x_train.reshape(-1,28, 28, 1)   #Reshape for CNN -  should work!!
x_test = x_test.reshape(-1,28, 28, 1)
history_cnn = cnn.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))

输出:

训练 60000 个样本,验证 10000 个样本 纪元 1/5 60000/60000 [===============================] - 157s 3ms/步 - 损失:0.0981 - acc: 0.9692 - val_loss :0.0468 - val_acc:0.9861 纪元 2/5 60000/60000 [===============================] - 157s 3ms/步 - 损失:0.0352 - acc: 0.9892 - val_loss : 0.0408 - val_acc: 0.9879 时代 3/5 60000/60000 [===============================] - 159s 3ms/步 - 损失:0.0242 - acc: 0.9924 - val_loss :0.0291 - val_acc:0.9913 时代 4/5 60000/60000 [===============================] - 165s 3ms/步 - 损失:0.0181 - acc: 0.9945 - val_loss : 0.0361 - val_acc: 0.9888 纪元 5/5 60000/60000 [===============================] - 168s 3ms/步 - 损失:0.0142 - acc: 0.9958 - val_loss : 0.0354 - val_acc: 0.9906

【讨论】:

请描述你做了什么以及为什么。

以上是关于检查模型输入时出错:预期的 convolution2d_input_1 有 4 个维度,但得到了形状为 (32, 32, 3) 的数组的主要内容,如果未能解决你的问题,请参考以下文章

检查输入时出错:预期 lstm_input 有 3 个维度,但得到了形状为 (160, 1000) 的数组

Keras 嵌入层 - ValueError:检查输入时出错:预期有 2 个维度,但得到了 (39978, 20, 20)

ValueError:检查输入时出错:预期dense_1_input的形状为(180,),但数组的形状为(1,)

检查输入时出错:预期 lstm_1_input 的形状为 (71, 768) 但得到的数组形状为 (72, 768)

model.fit 给出 ValueError :检查输入时出错:预期的 conv2d 得到了形状为 () 的数组

ValueError:检查输入时出错:预期 conv2d_input 有 4 个维度,但得到的数组具有形状(无,1)