Как исправить 'ValueError: Ошибка при проверке цели: ожидалось, что плотность_1 имеет 2 измерения, но получил массив с формой (373, 2, 2)' - PullRequest
0 голосов
/ 30 июня 2019

Это моя первая классификация изображений, я попытался классифицировать изображения, которые имеют 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: Ошибка при проверке цели:ожидал, что плотность_1 имеет 2 измерения, но получил массив с формой (373, 2, 2) ', и я не знаю, как это исправить, вы можете увидеть код в github на https://github.com/filmer2002/real_rash_project/blob/master/images_to_numpy_and_CNN_code.ipynb

Ответы [ 2 ]

0 голосов
/ 30 июня 2019

Это должно сработать, и если это не так, у вас есть противоречивые данные.

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 - очень плохая идея

0 голосов
/ 30 июня 2019

Вы получаете эту ошибку, потому что у вас есть метки с формой, отличной от вашего выходного слоя, переданные в сеть для обучения.

to_categorical() нужны 2 параметра, labels и len,labels должно быть dtype=int и меньше len, и убедитесь, что ваши tensorflow и 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, присвоенное to_categorical, в данном случае равно 10, потому что ваш выходной слой имеет shape == (10,)

Также убедитесь, что у вас есть равное количество изображений и меток для них, вы можете проверить это с помощью:

x_train.shape[0] == to_categorical(y_train, 10).shape[0]
True                 #should be True if everything is ok

И еще одно последнее замечание: tensorflow работает с тензорами, т. Е. С n-мерными массивами, не использует списки при работе с обучающими данными, большую часть времени следует использовать с пустыми массивами.

EDIT: Только * одномерные массивы или списки, состоящие из значений int, подходят для to_categorical().

Не пытайтесь использовать списки, состоящие из [0, 1] в to_categorical(), это не будет работать, простоиспользование 1 to_categorical() преобразует его для вас в [0, 1] элементы.

Ваша ошибка заключалась в использовании списков в качестве labels для to_categorical(), to_categorical() принимает только 1-мерные массивы int в качестве первого параметра, форма, в которой вы его задали (number_of_labels, 2), когда он работает только с shape == (number_of_labels,).

ИЛИ

Если вы хотите использовать списки / массивы, состоящие из таких элементов, как [0, 1], а выходная форма вашей модели равна 2, то просто не используйте to_categorical().

...