Как применить LSTM с CNN - PullRequest
0 голосов
/ 30 июня 2019

Мой вход имеет форму (1, 12000, 250, 150, 3) с метками как (1, 12000, 2) для CNN.Другими словами, я тренирую CNN на изображениях 250x150x3 с 2 классами;[1,0] или [0,1].

Это в конечном итоге создать бота, чтобы играть в летучую птичку.Мне сказали, что добавление LSTM для одновременной классификации нескольких фреймов - это путь.До сих пор я получил 0,984 val_acc со следующей чисто архитектурой CNN.

model.add(Conv2D(32, 3, 3, border_mode='same', input_shape=(250,150,3), activation='relu'))
model.add(Conv2D(32, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(128, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())

model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))

model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))

#model.add(LSTM(100, input_shape=(32, 32, 19), return_sequences=True))
model.add(Dense(2))
model.add(Activation('sigmoid'))
model.summary()

Точность:

Epoch 15/100
12800/12800 [==============================] - 89s 7ms/step - loss: 0.0390 - acc: 0.9889 - val_loss: 0.1422 - val_acc: 0.9717
Epoch 16/100
12800/12800 [==============================] - 89s 7ms/step - loss: 0.0395 - acc: 0.9883 - val_loss: 0.0917 - val_acc: 0.9821ss: - ETA: 1s - loss: 0.0399 - acc:
Epoch 17/100
12800/12800 [==============================] - 89s 7ms/step - loss: 0.0357 - acc: 0.9902 - val_loss: 0.1383 - val_acc: 0.9816
Epoch 18/100
12800/12800 [==============================] - 89s 7ms/step - loss: 0.0452 - acc: 0.9871 - val_loss: 0.1153 - val_acc: 0.9750
Epoch 19/100
12800/12800 [==============================] - 90s 7ms/step - loss: 0.0417 - acc: 0.9892 - val_loss: 0.1641 - val_acc: 0.9668
Epoch 20/100
12800/12800 [==============================] - 90s 7ms/step - loss: 0.0339 - acc: 0.9904 - val_loss: 0.0927 - val_acc: 0.9840

Я пытался добавить слой LSTM, но я не уверен, чтоидет не так:

ValueError                                Traceback (most recent call last)
<ipython-input-6-59e402ac3b8a> in <module>
     26 model.add(Dropout(0.5))
     27 
---> 28 model.add(LSTM(100, input_shape=(32, 19), return_sequences=True))
     29 
     30 model.add(Dense(2))

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\engine\sequential.py in add(self, layer)
    179                 self.inputs = network.get_source_inputs(self.outputs[0])
    180         elif self.outputs:
--> 181             output_tensor = layer(self.outputs[0])
    182             if isinstance(output_tensor, list):
    183                 raise TypeError('All layers in a Sequential model '

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\layers\recurrent.py in __call__(self, inputs, initial_state, constants, **kwargs)
    530 
    531         if initial_state is None and constants is None:
--> 532             return super(RNN, self).__call__(inputs, **kwargs)
    533 
    534         # If any of `initial_state` or `constants` are specified and are Keras

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
    412                 # Raise exceptions in case the input is not compatible
    413                 # with the input_spec specified in the layer constructor.
--> 414                 self.assert_input_compatibility(inputs)
    415 
    416                 # Collect input shapes to build layer.

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\engine\base_layer.py in assert_input_compatibility(self, inputs)
    309                                      self.name + ': expected ndim=' +
    310                                      str(spec.ndim) + ', found ndim=' +
--> 311                                      str(K.ndim(x)))
    312             if spec.max_ndim is not None:
    313                 ndim = K.ndim(x)

ValueError: Input 0 is incompatible with layer lstm_2: expected ndim=3, found ndim=2

Keras docs говорит, что аргументами для LSTM являются (единицы измерения, форма ввода) и так далее.Я также где-то читал, что TimeDistributed () больше не нужен, поэтому я не включил его.Я сделал ошибку в вычислении входной формы для LSTM или я что-то упустил полностью?


Редактировать 1: Я удалил слой flatten () и переместил слой LSTM сразу после слоев конвоя, дофк слои.Я также добавил reshape (), чтобы изменить 4 dim-вывода 4-го слоя conv на 3 dim, которые затем можно будет вводить в слой LSTM.

model.add(Conv2D(32, 3, 3, border_mode='same', input_shape=(250,150,3), activation='relu'))
model.add(Conv2D(32, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
output_1 = model.output_shape

model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
output_2 = model.output_shape

model.add(Conv2D(128, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(128, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
output_3 = model.output_shape

model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
output_4 = model.output_shape

model.add(Reshape((15, 9)))
output_5 = model.output_shape
model.add(LSTM(100, input_shape=(15, 9, 256), return_sequences=True))

Это формы каждого вывода:

Conv_1: (None, 125, 75, 32)
Conv_2: (None, 62, 37, 64)
Conv_3: (None, 31, 18, 128)
Conv_4: (None, 15, 9, 256)

Когда я попытался изменить форму conv_4, чтобы получить 3 тусклый ввод в LSTM, произойдет следующее:

ValueError                                Traceback (most recent call last)
<ipython-input-21-7f5240e41ae4> in <module>
     22 output_4 = model.output_shape
     23 
---> 24 model.add(Reshape((15, 9)))
     25 output_5 = model.output_shape
     26 model.add(LSTM(100, input_shape=(15, 9, 256), return_sequences=True))

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\engine\sequential.py in add(self, layer)
    179                 self.inputs = network.get_source_inputs(self.outputs[0])
    180         elif self.outputs:
--> 181             output_tensor = layer(self.outputs[0])
    182             if isinstance(output_tensor, list):
    183                 raise TypeError('All layers in a Sequential model '

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
    472             if all([s is not None
    473                     for s in to_list(input_shape)]):
--> 474                 output_shape = self.compute_output_shape(input_shape)
    475             else:
    476                 if isinstance(input_shape, list):

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\layers\core.py in compute_output_shape(self, input_shape)
    396             # input shape known? then we can compute the output shape
    397             return (input_shape[0],) + self._fix_unknown_dimension(
--> 398                 input_shape[1:], self.target_shape)
    399 
    400     def call(self, inputs):

E:\Applications\Anaconda3\envs\pygpu\lib\site-packages\keras\layers\core.py in _fix_unknown_dimension(self, input_shape, output_shape)
    384             output_shape[unknown] = original // known
    385         elif original != known:
--> 386             raise ValueError(msg)
    387 
    388         return tuple(output_shape)

ValueError: total size of new array must be unchanged

Любая помощь приветствуется.


Ответы [ 2 ]

0 голосов
/ 01 июля 2019

Если бы я прокрутил немного больше, я бы нашел ConvLSTM2D в документации, и это должно решить мою проблему. Попробую сейчас

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

во-первых, я не вижу lstm в вашей модели, это просто 4 convo к 3 полному подключению, верно?Почему у вас есть 2 Conv2D сразу после друг друга?

LSTM через кадры, которые я бы сделал вместо первого полного подключения сразу после выравнивания.

Я не знаю в Keras, но ввод в любую ячейку RNNэто трехмерный массив, например: (размер пакета, максимальная последовательность, элементы) или (max_sequence, bach_size, items), второй формат довольно странный.

Полученная ошибка: expected ndim=3, found ndim=2

так что я предполагаю, что вы вводите 2D-массив вместо 3D

Вы должны изменить свой Flatten для создания правильного 3D-ввода.Это можно сделать, например, с помощью ввода 5d, но 2d convo, например: bach size = 100, frames = 3, channel = 3, items = 28,28 (высота, ширина), сгладить до (100, 3, -1), где-1 означает отдых.

Мне нужно самому попробовать подобное, но я делаю в pytorch ...

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