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

3

我正在尝试构建一个图像分类器,但遇到了这篇文章标题中提到的错误。以下是我正在使用的代码。如何将我的numpy数组转换为函数fit()所需的形状?该数组的形状为(8020,)。我尝试打印输入形状:train_img_array.shape[1:],但它给出了空形状:()

import numpy as np
img_train.shape
img_valid.shape
img_train.head(5)
img_valid.head(5)

(8020, 4)
(2006, 4)
         ID  index  class                                               data
8030  11596  11596      0  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
2152  11149  11149      0  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
550   10015  10015      0  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
1740   9035   9035      0  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
9549   8218   8218      1  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
         ID  index  class                                               data
3312   5481   5481      0  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
9079  10002  10002      0  [[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], ...
6129  11358  11358      0  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
1147   2613   2613      1  [[[255, 255, 255, 0], [255, 255, 255, 0], [255...
7105   5442   5442      1  [[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], ...

img_train.dtypes

ID        int64
index     int64
class     int64
data     object
dtype: object

train_img_array = np.array([])
train_id_array = np.array([])
train_lab_array = np.array([])
train_id_array = img_train['ID'].values
train_lab_array = img_train['class'].values
train_img_array =img_train['data'].values

train_img_array.shape
train_lab_array.shape
train_id_array.shape

(8020,)
(8020,)
(8020,)

# Importing the Keras libraries and other packages


#matplotlib inline
from __future__ import print_function

import keras
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
Using Theano backend.
WARNING (theano.tensor.blas): Using NumPy C-API based implementation for BLAS functions.

classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape = (256, 256, 3)))
classifier.add(Conv2D(32, (3, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Dropout(0.25))

classifier.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
classifier.add(Conv2D(64, (3, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))  
classifier.add(Dropout(0.25))

classifier.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
classifier.add(Conv2D(64, (3, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Dropout(0.25))

classifier.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
classifier.add(Conv2D(64, (3, 3), activation='relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Dropout(0.25))

classifier.add(Flatten())
classifier.add(Dense(units = 256, activation = 'relu'))
classifier.add(Dropout(0.25))
classifier.add(Dense(units = 1, activation = 'sigmoid'))    classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
classifier.summary()

batch_size = 32
epochs = 15


history = classifier.fit(train_img_array, train_lab_array, batch_size=batch_size, epochs=epochs, verbose=1, 
                   validation_data=(valid_img_array, valid_lab_array))
classifier.evaluate(valid_img_array, valid_lab_array)


ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (8020, 1)

编辑:----------------------------------------------------------- 根据Nassim的要求,本文添加了一些更多的细节:
print(train_img_array) 

[ array([[[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ..., 
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ..., 
        ..., 
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]]], dtype=uint8)
 array([[[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ..., 
        ..., 
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]]], dtype=uint8)]


print(list(train_img_array)) 

[array([[[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ..., 
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ..., 
        ..., 
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]]], dtype=uint8), array([[[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ..., 


print(np.array(list(train_img_array)))
throws the error:

ValueError: could not broadcast input array from shape (700,584,4) into shape (700,584)

你应该实际展示模型,而不仅仅是调用 createModel() - deeiip
我没有包含模型,因为我认为它对这个讨论没有影响。但现在我会把它包括进来。 - redwolf_cr7
根据 keras 文档conv2d 层的输入必须是 4 维的,类型为:(samples, channels, rows, cols)(samples, rows, cols, channels) - Dav2357
@Dav2357:谢谢Dav...但我的问题是如何将我的训练和验证数据转换成那个形状? - redwolf_cr7
你能打印出 print(type(train_img_array[0])),然后打印出 print(train_img_array[0].shape),最后再打印出 print(train_img_array[0]) 吗? - Nassim Ben
@NassimBen:对于格式的问题我感到很抱歉: { <type 'numpy.ndarray'> \n (700, 584, 4) \n array([[[255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0], ..., ..., [255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0]]], dtype=uint8) } - redwolf_cr7
1个回答

5

因此,在使用结果进行调试后:

> print(type(train_img_array[0]))
<type 'numpy.ndarray'>

> print(train_img_array[0].shape)
(700, 584, 4)

> print(rain_img_array[0])
array([[[255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0], ..., ..., [255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0]]], dtype=uint8)

我们发现当您执行以下操作时返回的内容为:
train_img_array =img_train['data'].values

实际上,它是一个形状为(8020,)的numpy数组,其中所有元素都是包含图像的其他numpy数组。基本上是两个嵌套的numpy数组。

所以你想要的是将这个嵌套数组结构展开成一个单一的数组对象。我会这样做,可能有点不正规但应该能行,具体如下:

train_img_array =img_train['data'].values
train_img_array = np.array(list(train_img_array))

基本上,将numpy数组的结构转换为numpy数组列表。然后,当您从numpy数组列表构建numpy数组时,您将获得(魔术般的)一个具有更多维度的numpy数组。
此操作后的形状应为(8020, 700, 584, 4)。
现在,我看到您可能会遇到另一个潜在问题,即图像的格式。您的图像通道维度是最后一个(这里有4个通道)。因此,在卷积层中,您应该指定:
conv2D(... , data_format="channels_last", )

此外,您的第一层输入形状为(700, 584, 4),而不是(256, 256, 3)。
希望它可以工作 :-)

哪一行出现了错误?我需要更多的信息 :) - Nassim Ben
print(train_img_array[0])[[[255 255 255 0] [255 255 255 0] [255 255 255 0] ..., [255 255 255 0] [255 255 255 0] [255 255 255 0]] - redwolf_cr7
打印(list(train_img_array[0])) [array([[255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0], ..., [255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0]], dtype=uint8), array([[255, 255, 255, 0], [255, 255, 255, 0], [255, 255, 255, 0], ..., - redwolf_cr7
打印(np.array(list(train_img_array[0]))) [[[255 255 255 0] [255 255 255 0] [255 255 255 0] ..., [255 255 255 0] [255 255 255 0] [255 255 255 0]] ... - redwolf_cr7
但我想看到其中的一部分...而不是第一个元素 :) 你能在你的问题中添加编辑并添加信息吗? - Nassim Ben
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接