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

Posted

技术标签:

【中文标题】检查输入时出错:预期 input_1 有 4 个维度,但得到了形状为 (224, 224, 3) 的数组【英文标题】:Error when checking input: expected input_1 to have 4 dimensions, but got array with shape (224, 224, 3) 【发布时间】:2019-09-03 14:56:14 【问题描述】:

我正在尝试使用我自己的数据来训练 CNN,以解决二进制分类问题。但是我认为输入的预期大小有问题,我认为是(224,224,3)。我搜索了这个案例,发现有人说可以通过将图像大小从 (224,224,3) 重塑为 (1,224,224,3) 来修复它,但它不起作用。

这是我的代码:

import scipy.io
import tensorflow as tf
import cv2

# Parameters
img_height = 224
img_width = 224
img_depth = 3
classes = 2

# Load Data
db_name = 'polo'
db_path = 'D:/databases/' + db_name + '/'
db_data = scipy.io.loadmat(db_path + 'db_py.mat')
db_size = len(db_data['db']['images'][0][0][0])
faces_path = 'data/' + db_name + '/faces/'
images = []
labels = [0] * db_size
for i in range(0,db_size):
    filename = 'data/' + db_name + '/faces/' + db_data['db']['images'][0][0][0][i][2][0]
    image = cv2.imread(filename)
    image = cv2.resize(image, (img_height, img_width))
    images.append(image)
    labels[i] = db_data['db']['subjects'][0][0][0][i][4][0][0][0][0][0]

inputs = tf.keras.layers.Input(shape=(img_height,img_width,img_depth))
layers = tf.keras.layers.Conv2D(32, (3, 3), padding="same")(inputs)
layers = tf.keras.layers.Activation("relu")(layers)
layers = tf.keras.layers.BatchNormalization(axis=-1)(layers)
layers = tf.keras.layers.Conv2D(32, (3, 3), padding="same")(layers)
layers = tf.keras.layers.Activation("relu")(layers)
layers = tf.keras.layers.BatchNormalization(axis=-1)(layers)
layers = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(layers)
layers = tf.keras.layers.Dropout(0.25)(layers)
layers = tf.keras.layers.Conv2D(64, (3, 3), padding="same")(layers)
layers = tf.keras.layers.Activation("relu")(layers)
layers = tf.keras.layers.BatchNormalization(axis=-1)(layers)
layers = tf.keras.layers.Conv2D(64, (3, 3), padding="same")(layers)
layers = tf.keras.layers.Activation("relu")(layers)
layers = tf.keras.layers.BatchNormalization(axis=-1)(layers)
layers = tf.keras.layers.MaxPooling2D(pool_size=(2, 2))(layers)
layers = tf.keras.layers.Dropout(0.25)(layers)
layers = tf.keras.layers.Flatten()(layers)
layers = tf.keras.layers.Dense(512)(layers)
layers = tf.keras.layers.Activation("relu")(layers)
layers = tf.keras.layers.BatchNormalization()(layers)
layers = tf.keras.layers.Dropout(0.5)(layers)
layers = tf.keras.layers.Dense(classes)(layers)
layers = tf.keras.layers.Activation("softmax")(layers)

InitialLearnRate = 0.03
MaxEpochs = 30
MiniBatchSize = 32
opt = tf.keras.optimizers.SGD(lr=InitialLearnRate, decay=InitialLearnRate / MaxEpochs)
model = tf.keras.Model(inputs, layers , name="net")
model.compile(loss="categorical_crossentropy", optimizer=opt,
    metrics=["accuracy"])
model.summary()
H = model.fit(images, labels,
    batch_size=MiniBatchSize, epochs=MaxEpochs, verbose=1,steps_per_epoch=10)

【问题讨论】:

是的,你必须重塑为 (1,224,224,3),并告诉我们为什么它不起作用。我在你的代码中没有看到你在任何地方这样做。 【参考方案1】:

如果你去官方documentation 搜索conv2d input shape 你会看到:

具有形状的 4D 张量: (batch, channels, rows, cols) 如果 data_format 为 "channels_first" 或 具有形状的 4D 张量: (batch, rows, cols, channels) if data_format is "channels_last"

或者,这里是关于输入格式的详细 answer。

如果您有多个图像,则在您的情况下,您将输入大小为 (batch_size, 244,244, 3) 的输入。我看到你做的是创建一个包含所有这些图像的列表。我会尝试:

images = np.empty(batch_size, 244, 244, 3)

for i in range(0,db_size):
    filename = ('data/'
                + db_name
                + '/faces/'
                + db_data['db']['images'][0][0][0][i][2][0])
    image = cv2.imread(filename)
    images[i]  = cv2.resize(image, (img_height, img_width))

如果这没有帮助,您收到的错误消息可以帮助其他人回答您的问题。

【讨论】:

他可以通过添加images = np.array(images) 来修复错误,然后再将其提供给模型进行训练。但实际上该错误是由提供列表 images 而不是 numpy 数组引起的。 我按照你说的做了:images = np.empty((db_size, img_height, img_width, img_depth)) 和 images[i] = image bt 我收到了这个新错误:ValueError: Error when checks model目标:您传递给模型的 Numpy 数组列表不是模型预期的大小。预计会看到 1 个数组,但得到了以下 1000 个数组的列表:[5, 8, 10, 14, 16, 18, 19, 22, 28, 29, 33, 40, 43, 43, 2, 3, 4, 5, 7, 12, 15, 16, 18, 20, 21, 23, 26, 29, 31, 36, 38, 18, 20, 23, 25, 35, 38, 47, 49, 51, 58, 60, 61, 19, 21, 26, 28, 30, 37, 40, 48, 51...

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

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

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

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

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

ValueError:检查输入时出错:预期dense_1_input有2维,但得到了形状为(60000、28、28)的数组

ValueError:检查输入时出错:预期 lstm_16_input 有 3 个维度,但得到的数组形状为 (836, 400, 3, 1)