Keras импортирует два изображения одного и того же объекта для ConvLSTM - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь использовать рекуррентные модели Keras (ConvLSTM2D здесь) для моей нейронной сети.Моя цель состоит в том, чтобы взять два изображения одного и того же объекта под разными углами, и на основе особенностей двух изображений попытаться определить, какой это тип объекта.

Изображения создаются и хранятся в отдельных папках, но пути одинаковы, так что

-dir1 -> class1 -> image001.jpg
      -> class2 -> image101.jpg

-dir2 -> class1 -> image001.jpg
      -> class2 -> image101.jpg

image001.jpg из dir1 и dir2 относятся к одному и тому же объекту и имеют разные углы,


Моя проблема :

ConvLSTM2D берет изображения с дополнительным измерением времени.Итак, мои изображения были (128,128,1), теперь я буду использовать np.stack, чтобы преобразовать их в (2,128,128,1).Однако я не знаю, как:

  1. Сопоставлять изображения при генерации
  2. Укладывать только изображения, а не метки

Мои попытки

Я пытался решить проблему, используя решение, описанное здесь .Насколько я понимаю, если оставить зерно одинаковым, два изображения будут одного и того же объекта (?).Однако проблема возникает, когда модель пытается использовать изображения.У Кераса есть следующее выходное сообщение:

ValueError: Error when checking model input: the list of Numpy arrays that you are 
passing to your model is not the size the model expected. Expected to see 1 array(s)
, but instead got the following list of 2 arrays: 
[array([[[[0.07843138],
     [0.02745098],
     [0.07450981],
     ...,
     [0.02745098],
     [0.03137255],
     [0.0509804 ]],

    [[0.05490196],
     [0.10980393],...

Это заставило меня подумать, что мне нужно сложить два изображения, используя numpy.stack, что я и попытался сделать дальше.Однако это привело к следующей ошибке:

ValueError: Error when checking input: expected conv_lst_m2d_1_input to have shape
 (2, 128, 128, 1) but got array with shape (100, 128, 128, 1)

Я могу понять эту ошибку, так как я указал, что мой ввод имеет размеры (Нет, no_of_images, ширина, высота, каналы).Поскольку это бимодальное изображение, 2 - это количество изображений.Фактический ввод, полученный моделью (100,128,128,1), где первый элемент - размер партии.Поэтому я думаю, что неправильно сложил два изображения в ось времени .

Это оставляет меня смущенным и потерянным в том, как решить эту проблему.Я хорошо определил свою модель так, чтобы входная форма была (samples = None, 2,128,128,1), но я не знаю, как привести два изображения в один и тот же формат.


Мой код

Модель

model = Sequential()
no_of_img = 2
#Adding additional convolution + maxpool layers 15/1/19
model.add(ConvLSTM2D(32, (5,5), batch_input_shape=(batch_size,no_of_img,img_width,img_height,1),return_sequences=True))
model.add(Activation('relu'))
model.add(Dropout(0.4))
model.add(TimeDistributed(MaxPooling2D((2,2))))


model.add(ConvLSTM2D(64, (3,3),return_sequences=True))
model.add(Activation('relu'))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2,2))))
model.add(Dropout(0.2))

model.add(ConvLSTM2D(128, (3,3),return_sequences=True))
model.add(Activation('relu'))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2,2))))
model.add(Dropout(0.2))

model.add(ConvLSTM2D(256, (3,3),return_sequences=True))
model.add(Activation('relu'))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2,2))))
model.add(Dropout(0.2))

model.add(Flatten())
#Possible dense layer with our 128x128 number of pixels is too much, too high. We should add a few convolutional and maxpool layers beforehand.

model.add(Dense(128,            #dimensionality of output space
                #input_shape=(128,128,1),        #Commented out as only the first layer needs input shape.
                ))
model.add(Activation('relu'))
                #model.add(Dropout(0.2))


                #model.add(Dense(num_classes, activation='softmax'))
model.add(Dense(num_classes,activation='softmax'))
model.compile(loss='categorical_crossentropy',optimizer='RMSProp',metrics=['accuracy'])

Текущая попытка подготовки данных

train_datagen = ImageDataGenerator(
                               rescale=1./255,                            
#Normalized inputs from 0-255 to 0-1
                               horizontal_flip=True,
                               vertical_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

def generate_generator_multiple(generator,dir1, dir2, batch_size, 
    img_width,img_height,subset):
    genX1 = generator.flow_from_directory(dir1,
                                      color_mode='grayscale',
                                      target_size= 
                                      (img_width,img_height),
                                      batch_size=batch_size,
                                      class_mode='categorical',
                                      shuffle=False,
                                      subset=subset,
                                      seed=1)
                                      #Same seed for consistency.

    genX2 = generator.flow_from_directory(dir2,
                                      color_mode='grayscale',
                                      target_size= 
                                      (img_width,img_height),
                                      batch_size=batch_size,
                                      class_mode='categorical',
                                      shuffle=False,
                                      subset=subset,
                                      seed=1)
    while True:
        X1i = genX1.next()
        X2i = genX2.next()
        yield numpy.stack((X1i[0],X2i[0])),X1i[1]    #Yields both images and their mutual label



train_generator = generate_generator_multiple(generator=train_datagen,
                                          dir1=train_data_dirA,
                                          dir2=train_data_dirB,
                                          batch_size=batch_size,
                                          img_width=img_width,
                                          img_height=img_height,
                                          subset='training')

validation_generator 
                =generate_generator_multiple(generator=test_datagen,
                                               dir1=train_data_dirA,
                                               dir2=train_data_dirB,
                                               batch_size=batch_size,
                                               img_width=img_width,
                                               img_height=img_height,
                                               subset='validation')

1 Ответ

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

Разобрался.Получается вывод после использования np.stack, выходящего в форме (время, batch_size, ширина, высота, каналы).Я переключил каналы времени и batch_size с помощью np.transpose, и изображения хорошо вводятся в модель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...