如何修复'ValueError:检查目标时出错:预期density_1具有2维,但数组的形状为(373,2,2)

时间:2019-06-30 15:13:26

标签: python machine-learning keras computer-vision conv-neural-network

这是我的第一次图像分类,我尝试对具有2类的图像进行分类。我的图像数据集是128 * 128,我使用RGB,所以我认为尺寸是128、128、3。代码是

import cv2
import glob
import numpy as np
import matplotlib.pyplot as plt

train = []
train_label = []

train_files_1 = glob.glob('/Users/filmer2002/Desktop/real_rash_project/train_images/Atopic_Dermatitis/*.jpg')
for files in train_files_1:
    image = cv2.imread(files)
    train.append(image)
    train_label.append([0., 1.]) 

train_files_2 = glob.glob('/Users/filmer2002/Desktop/real_rash_project/train_images/Contact_Dermatitis/*.jpg')
for files in train_files_2:
    image = cv2.imread(files, )
    train.append(image)
    train_label.append([1., 0.])

train_array = np.array(train, dtype='int')
train_label_array = np.array(train_label, dtype='int')

test = []
test_label = []

test_files = glob.glob('/Users/filmer2002/Desktop/real_rash_project/test_images/Atopic_Dermatitis/*.jpg')
for files in test_files:
    image = cv2.imread(files)
    test.append(image)
    test_label.append([0., 1.])

test_files_2 = glob.glob('/Users/filmer2002/Desktop/real_rash_project/test_images/Contact_Dermatitis/*.jpg')
for files in test_files_2:
    image = cv2.imread(files)
    test.append(image)
    test_label.append([1., 0.])

test_array = np.array(test, dtype='int')
test_label_array = np.array(test_array, dtype='int')

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten
from keras.utils import to_categorical

x_train = train_array
y_train = train_label_array

x_test = test_array
y_test = test_label_array

x_train = x_train.reshape(373, 128, 128, 3)
x_test = x_test.reshape(95, 128, 128, 3)

model = Sequential()

model.add(Conv2D(64, kernel_size = 3, activation = 'relu', input_shape = (128, 128, 3)))
model.add(Conv2D(32, kernel_size = 3, activation = 'relu'))
model.add(Conv2D(16, kernel_size = 3, activation = 'relu'))
model.add(Flatten())
model.add(Dense(10, activation = 'softmax'))

model.compile(optimizer = 'adam', 
              loss = 'categorical_crossentropy', 
              metrics = ['accuracy'])

model.fit(x_train, to_categorical(y_train), validation_data = (x_test, to_categorical(y_test)), epochs = 3)

运行代码后,它显示“ ValueError:检查目标时出错:期望density_1具有2维,但数组的形状为(373,2,2)”,我不知道如何解决它,您可以看到github中https://github.com/filmer2002/real_rash_project/blob/master/images_to_numpy_and_CNN_code.ipynb

上的代码

2 个答案:

答案 0 :(得分:0)

收到此错误的原因是,您将标签的形状与输出层不同,并赋予了网络进行训练。

galleryType需要2个参数,to_categorical()labelslen必须小于labels,小于dtype=int,并确保您的lentensorflow是最新的。

尝试

tensorboard
在这种情况下,给import cv2 import glob import numpy as np import matplotlib.pyplot as plt train = [] train_label = [] train_files_1 = glob.glob('/Users/filmer2002/Desktop/real_rash_project/train_images/Atopic_Dermatitis/*.jpg') for files in train_files_1: image = cv2.imread(files) train.append(image) train_label.append(1) train_files_2 = glob.glob('/Users/filmer2002/Desktop/real_rash_project/train_images/Contact_Dermatitis/*.jpg') for files in train_files_2: image = cv2.imread(files, ) train.append(image) train_label.append(0) train_array = np.array(train, dtype=int) train_label_array = np.array(train_label, dtype=int) test = [] test_label = [] test_files = glob.glob('/Users/filmer2002/Desktop/real_rash_project/test_images/Atopic_Dermatitis/*.jpg') for files in test_files: image = cv2.imread(files) test.append(image) test_label.append(1) test_files_2 = glob.glob('/Users/filmer2002/Desktop/real_rash_project/test_images/Contact_Dermatitis/*.jpg') for files in test_files_2: image = cv2.imread(files) test.append(image) test_label.append(0) test_array = np.array(test, dtype=int) test_label_array = np.array(test_array, dtype=int) from keras.models import Sequential from keras.layers import Dense, Conv2D, Flatten from keras.utils import to_categorical x_train = train_array y_train = train_label_array x_test = test_array y_test = test_label_array x_train = x_train.reshape(373, 128, 128, 3) x_test = x_test.reshape(95, 128, 128, 3) model = Sequential() model.add(Conv2D(64, kernel_size = 3, activation = 'relu', input_shape = (128, 128, 3))) model.add(Conv2D(32, kernel_size = 3, activation = 'relu')) model.add(Conv2D(16, kernel_size = 3, activation = 'relu')) model.add(Flatten()) model.add(Dense(10, activation = 'softmax')) model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy']) model.fit(x_train, to_categorical(y_train, 10), validation_data = (x_test, to_categorical(y_test, 10)), epochs = 3)

len是10,因为您的输出层有to_categorical

还要确保图像和标签的数量相等,请通过以下方式进行测试:

shape == (10,)

最后一条注释:x_train.shape[0] == to_categorical(y_train, 10).shape[0] True #should be True if everything is ok 与张量i一起使用。 e。 n维数组,在使用训练数据时不要使用列表,大多数情况下应使用numpy数组。

编辑: 对于tensorflow,只有一维数组或由int值组成的列表是可以的。

请勿尝试在to_categorical()中使用由[0,1]组成的列表,它将不起作用,只需使用1 to_categorical()即可将其转换为[0,1]元素

您的错误是将列表用作to_categorical()的标签,to_categorical()仅接受一维int数组作为第一个参数,即您给定的形状(number_of_labels,2),当它仅适用于shape ==(number_of_labels,)。

OR

如果您要使用由[0,1]之类的元素组成的列表/数组,并且模型输出形状为2,则根本不使用to_categorical()

答案 1 :(得分:0)

这应该可以,如果没有,则数据不一致。

import cv2
import glob
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow.keras as keras

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten
from tensorflow.keras.utils import to_categorical

#assert tf.__version__ == '1.14.0'

train = np.zeros((1, 128, 128, 3))
train_label = []

train_files_1 = glob.glob('/path/to/your/folder/with/data/*.jpg')
for files in train_files_1:
    image = cv2.imread(files)
    img = np.array(image).astype(int).reshape(128, 128, 3)

    train = np.concatenate((train, [img]), axis=0)

    train_label.append(1) 

train_files_2 = glob.glob('/path/to/your/folder/with/data/*.jpg')
for files in train_files_2:
    image = cv2.imread(files)
    img = np.array(image).astype(int)

    train = np.concatenate((train, [img]), axis=0)

    train_label.append(0)

x_train = train[1:]
y_train = to_categorical(train_label, 2)

test = np.zeros((1, 128, 128, 3))
test_label = []

test_files = glob.glob('/path/to/your/folder/with/data/*.jpg')
for files in test_files:
    image = cv2.imread(files)
    img = np.array(image).astype(int)

    test = np.concatenate((test, [img]), axis=0)

    test_label.append(1)

test_files_2 = glob.glob('/path/to/your/folder/with/data/*.jpg')
for files in test_files_2:
    image = cv2.imread(files)
    img = np.array(image).astype(int)

    test = np.concatenate((test, [img]), axis=0)

    test_label.append(0)

x_test = test[1:]
y_test = to_categorical(test_label, 2)

print ('train', x_train.shape)
print ('test', x_test.shape)
print ('test labels', y_test.shape)
print ('train labels', y_train.shape)

assert x_train.shape == (len(train[1:]), 128, 128, 3)
assert x_test.shape == (len(test[1:]), 128, 128, 3)

assert y_train.shape == (len(train_label), 2)
assert y_test.shape == (len(test_label), 2)

# if you get an error about one of the asserts above => your data is not consistant

model = Sequential()

model.add(Conv2D(64, kernel_size=3, activation='relu', input_shape=(128, 128, 3)))
model.add(Conv2D(32, kernel_size=3, activation='relu'))
model.add(Conv2D(16, kernel_size=3, activation='relu'))
model.add(Flatten())
model.add(Dense(2, activation='softmax'))

model.compile(optimizer='adam', 
              loss='categorical_crossentropy', 
              metrics=['accuracy'])

model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=3)

print ('all good, all done!')

注意:混合使用python列表和numpy数组是非常糟糕的主意