Как получить данные тренировки для Keras Sequential CNN в правильной форме тензора? - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть 4-мерный тензор данных пикселей изображения (красный (высота, ширина), зеленый (высота, ширина), синий (высота, ширина), 14000 примеров) и файл CSV, содержащий координаты ограничивающих рамок, которыеу каждого изображения есть, т. е. (Имя изображения, X1, Y1, X2, Y2), оно имеет 14000 строк, по одной на каждый пример.

Как передать эти данные в мою нейронную сеть?В настоящее время, если я пытаюсь подать тензор, он пропускает весь массив из 14000 примеров в одну строку (X1, Y1, X2, Y2) {он должен был пройти один массив для одной строки из x1, y1, x2, y2}.

Есть идеи, как это исправить?

Вот код и соответствующая ошибка:

train_csv = pd.read_csv('datasets/training.csv').values
test_csv = pd.read_csv('datasets/test.csv').values

y_train = train_csv[:,[1,2,3,4]]   #done
x_train_names = train_csv[:,0]     #obtained names of images in array

#### load images into an array ####
X_train = []
path = "datasets/images/images/"
imagelist = listdir(path)
for i in range(len(x_train_names)):
img_name = x_train_names[i]
img = Image.open(path + str(img_name))
arr = array(img)
X_train.append(arr) 


#### building a very basic classifier, just to get some result ####
classifier = Sequential()
classifier.add(Convolution2D(64,(3,3),input_shape=(64,64,3), activation = 
'relu')) 
classifier.add(Dropout(0.2))
classifier.add(MaxPooling2D((4,4)))
classifier.add(Convolution2D(32,(2,2), activation = 'relu')) 
classifier.add(MaxPooling2D((2,2)))
classifier.add(Flatten())
classifier.add(Dense(16, activation = 'relu'))
classifier.add(Dropout(0.5))
classifier.add(Dense(4))
classifier.compile('adam','binary_crossentropy',['accuracy'])
classifier.fit(x=X_train,y=y_train, steps_per_epoch=80, batch_size=32, 
epochs=25)

Ошибка:

ValueError: Ошибка при проверке ввода модели: список массивов Numpy, передаваемых вашей модели, отличается от ожидаемого размера модели.Предполагается увидеть 1 массив (ов), но вместо этого получил следующий список из 14000 массивов:

[array([[[141, 154, 144],
         [141, 154, 144],
         [141, 154, 144],
         ...,
         [149, 159, 150],
         [150, 160, 151],
         [150, 160, 151]],

        [[140, 153, 143],
         […

EDIT : я преобразовал все свои изображения в оттенки серого, чтобы не получитьошибка памятиЭто означает, что мой X_train должен иметь 1 измерение по числу каналов (ранее, RGB).Вот мой отредактированный код:

y_train = train_csv[:,[1,2,3,4]]   #done
x_train_names = train_csv[:,0]     #obtained names of images in array

# load images into an array
path = "datasets/images/images/"
imagelist = listdir(path)

img_name = x_train_names[0]

X_train = np.ndarray((14000,img.height,img.width,1))

for i in range(len(x_train_names)):
img_name = x_train_names[i]
img = Image.open(path + str(img_name)).convert('L') 
##converting image to grayscale because I get memory error else 
X_train[i,:,:,:] = np.asarray(img)

ValueError: не удалось передать входной массив из фигуры (480 640) в фигуру (480 640,1)

(в строке X_train[i,:,:,:] = np.asarray(img))

1 Ответ

0 голосов
/ 09 февраля 2019

Первый шаг - всегда выяснить, какую форму ввода ожидает ваш первый слой свертки.Документация tf.nn.conv2d гласит, что ожидаемая форма входного тензора 4D равна [batch, in_height, in_width, in_channels].

Для загрузки данных мы можем использовать numpy ndarray.Для этого мы должны знать количество изображений, которые вы хотите загрузить, а также размеры изображений:

path = "datasets/images/images/"
imagelist = listdir(path)

img_name = x_train_names[0]
img = Image.open(path + str(img_name))

X_train = np.ndarray((len(imagelist),img.height,img.width,3))

for i in range(len(x_train_names)):
 img_name = x_train_names[i]
 img = Image.open(path + str(img_name))
 X_train[i,:,:,:] = np.asarray(img)

Свойство shape вашего тензора X_train должно дать вам тогда:

print(X_train.shape)
> (len(x_train_names), img.height, img.width, 3)

РЕДАКТИРОВАТЬ:

Чтобы загрузить изображения в несколько пакетов, вы можете сделать что-то вроде этого:

#### Build and compile your classifier up here here ####

num_batches = 5
len_batch = np.floor(len(x_train_names)/num_batches).astype(int) 

X_train = np.ndarray((len_batch,img.height,img.width,3))

for batch_idx in range(num_batches):
    idx_start = batch_idx*len_batch
    idx_end = (batch_idx+1)*len_batch-1
    x_train_names_batch = x_train_names[idx_start:idx_end]

    for i in range(len(x_train_names_batch)):
        img_name = x_train_names_batch[i]
        img = Image.open(path + str(img_name))
        X_train[i,:,:,:] = np.asarray(img)

    classifier.fit(x=X_train,y=y_train, steps_per_epoch=num_batches, batch_size=len(x_train_names_batch), epochs=2)
...