Есть ли способ, которым я могу превратить значения пикселей изображения в 4D-массив (включая 1 канал) вместо 3D-массива для Keras? - PullRequest
0 голосов
/ 17 июня 2020

Я создал CNN с нуля из python (или достаточно), используя самодельный алгоритм градиентного спуска. Именно из-за этого последнего пункта точность составила всего 50%. Итак, я использую keras, чтобы получить доступ к оптимизатору adam.

Для использования model.fit очевидно требуется массив с количеством изображений, двумя измерениями, а также количеством каналов. В следующем коде я не извлекаю каналы изображения, поэтому у меня есть только 3 измерения в массиве, и это не работает. Как добавить 4-е (канальное) измерение? Я использую следующий код atm.

import numpy as np
#%tensorflow_version 1.x

import tensorflow as tf
from tensorflow import keras

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
import glob
from PIL import Image

#!unzip not_dog4

images = []
image_data = []

for filename in glob.glob('not_dog/*.jpg'): 
  im = Image.open(filename)
  images.append(im)

for image in images:
  images2 = image.resize((28, 28))
  gs_image = images2.convert(mode='L')
  image_vector = np.array(gs_image)
  image_data.append(image_vector)

image_data = np.array(image_data)

image_data_normalised = []

image_data = image_data.astype('float32')
image_data_normalised = image_data / 255 - 0.5

y = [1]

filter_size = 3
pool_filter_size = 2

model = Sequential()
model.add(Conv2D(num_filters, filter_size, strides=(1, 1), input_shape=(28, 28, 1)))  
model.add(MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding='valid')) 
model.add(Flatten())  
model.add(Dense(1, activation = 'softmax'))  

#compile the model
model.compile('adam', loss = 'categorical_crossentropy')
model.fit(image_data_normalised, y, epochs=3)

В частности, ошибка: «Ошибка при проверке ввода: ожидалось, что conv2d_6_input будет иметь 4 измерения, но получил массив с формой (120, 28, 28)» Это 120 изображения, каждое 28 на 28, но это должно быть (120, 28, 28, 1) и указать, что у меня один канал. Как мне этого добиться?

Кстати, следующая часть - это ответ, или y. Я использую два класса, чтобы приготовить хот-дог, а не что-то вроде хот-дога. Следовательно, ответ на все изображения - один или с вероятностью 1 для моего y? Поэтому могу я просто поместить 1 в массив, и он вычислит убыток для оптимизатора на основе текущей вероятности и желаемой вероятности (1), как это сделал я?

1 Ответ

0 голосов
/ 18 июня 2020

Вы можете разжать другое измерение так:

image_data = np.array(image_data)[..., None]
...