Keras ConvLSTM2D Фильтры и входные каналы: ValueError: количество входных каналов не соответствует соответствующему размеру фильтра, 7! = 1 - PullRequest
1 голос
/ 28 мая 2019

Я пытаюсь построить сверточную нейронную сеть в Keras, которая включает в себя сверточный слой LSTM (ConvLSTM2D) в середине для обработки последовательности изображений GRAYSCALE, которые приходят из видео.Каждая форма кадра имеет вид (61,61,1), и их последовательности передаются вместе, поэтому общий ввод (num_movies, num_frames, frame_height, frame_width, 1).Сверточные слои предварительно обучаются для автоматического кодирования изображений в последовательности, поэтому остается только обучить рекуррентный слой LSTM.Когда у меня только один фильтр, сеть работает нормально.Вот сеть (все уровни, кроме уровня LSTM, распределены по времени).Цель сети состоит в том, чтобы предсказать будущие кадры в видео, учитывая текущие кадры (т.е. передать последовательность, переместить последовательность вперед на n кадров).Я обучил сверточную часть (автокодер; см. Код ниже) отдельно, чтобы автоматически кодировать отдельные кадры, и теперь пытаюсь добавить в LSTM выполнение предсказаний последовательности.

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
time_distributed_1 (ZeroPad) (None, 34, 64, 64, 1)     0         
_________________________________________________________________
time_distributed_2 (Conv2D) (None, 34, 64, 64, 16)    160       
_________________________________________________________________
time_distributed_3 (MaxPool) (None, 34, 32, 32, 16)    0         
_________________________________________________________________
time_distributed_4 (Conv2D) (None, 34, 32, 32, 8)     1160      
_________________________________________________________________
time_distributed_5 (MaxPool) (None, 34, 16, 16, 8)     0         
_________________________________________________________________
time_distributed_6 (Conv2D) (None, 34, 16, 16, 8)     584       
_________________________________________________________________
time_distributed_7 (MaxPool) (None, 34, 8, 8, 8)       0         
_________________________________________________________________
time_distributed_8 (Conv2D)  (None, 34, 8, 8, 8)       584       
_________________________________________________________________
time_distributed_9 (MaxPool)  (None, 34, 4, 4, 8)       0         
_________________________________________________________________
time_distributed_10 (Conv2D) (None, 34, 4, 4, 1)       73        
_________________________________________________________________
rnn (ConvLSTM2D)             (None, 34, 4, 4, 1)       36        
_________________________________________________________________
time_distributed_11 (Conv2D) (None, 34, 4, 4, 4)       40        
_________________________________________________________________
time_distributed_12 (UpSample) (None, 34, 8, 8, 4)       0         
_________________________________________________________________
time_distributed_13 (Conv2D) (None, 34, 8, 8, 8)       296       
_________________________________________________________________
time_distributed_14 (UpSample) (None, 34, 16, 16, 8)     0         
_________________________________________________________________
time_distributed_15 (Conv2D) (None, 34, 16, 16, 8)     584       
_________________________________________________________________
time_distributed_16 (UpSample) (None, 34, 32, 32, 8)     0         
_________________________________________________________________
time_distributed_17 (Conv2D) (None, 34, 32, 32, 16)    1168      
_________________________________________________________________
time_distributed_18 (UpSample) (None, 34, 64, 64, 16)    0         
_________________________________________________________________
time_distributed_19 (Conv2D) (None, 34, 64, 64, 1)     145       
_________________________________________________________________
time_distributed_20 (UpSample) (None, 34, 61, 61, 1)     0         
=================================================================
Total params: 4,830
Trainable params: 36
Non-trainable params: 4,794
_________________________________________________________________

Все выполняется, когда количество фильтров в ConvLSTM2Dслой один.Однако, когда я пытаюсь настроить количество фильтров в слое ConvLSTM2D, я получаю ошибку:

"ValueError: количество входных каналов не соответствует соответствующему размеру фильтра, 7! = 1"

где 7 - количество фильтров, которые я пытаюсь использовать.

Здесь я строю авто-кодер.

    autoencoder = Sequential()

    autoencoder.add(ZeroPadding2D(((2,1),(2,1)), input_shape = image_shape))  # (61,61, 1) --> (64,64, 1)

    autoencoder.add(Conv2D(16, (3,3), activation='relu', padding='same'))         # (64, 64, 1) --> (64, 64, 16) 
    autoencoder.add(MaxPooling2D((2,2), padding='same'))                          # (64, 64, 16) --> (32, 32, 16)
    autoencoder.add(Conv2D(8, (3,3), activation = 'relu', padding = 'same'))      # (32,32, 16) --> (32,32, 8)
    autoencoder.add(MaxPooling2D((2,2), padding = 'same'))                        # (32, 32, 8) --> (16,16, 8)
    autoencoder.add(Conv2D(8, (3,3), activation = 'relu', padding = 'same'))      # (16,16,8) --> (16,16,4)
    autoencoder.add(MaxPooling2D((2,2), padding = 'same'))                        # (16, 16, 4) --> (4, 4, 4)
    autoencoder.add(Conv2D(8, (3,3), activation = 'relu', padding = 'same'))      # (16,16,8) --> (16,16,4)
    autoencoder.add(MaxPooling2D((2,2), padding = 'same'))                        # (16, 16, 4) --> (4, 4, 4)
    autoencoder.add(Conv2D(1, (3,3), activation = 'relu', padding = 'same'))      # (4,4,4) --> (4,4,1)


    # decode the lower dimensional representation back into an image
    model.add(Conv2D(4,(3,3), activation = 'relu', padding = 'same')) # (4,4,1) --> (4,4,4)
    autoencoder.add(UpSampling2D((2,2)))                                    # (4,4,4) -> (16,16,4)
    autoencoder.add(Conv2D(8,(3,3), activation = 'relu', padding = 'same')) # (4,4,1) --> (4,4,4)
    autoencoder.add(UpSampling2D((2,2)))                                    # (4,4,4) -> (16,16,4)
    autoencoder.add(Conv2D(8,(3,3), activation = 'relu', padding = 'same')) # (16,16,4) --> (16,16,8)
    autoencoder.add(UpSampling2D((2,2)))                                    # (16,16,8) -> (32,32,8)
    autoencoder.add(Conv2D(16, (3,3), activation = 'relu', padding='same'))# (32,32,8) -> (32,32,16)
    autoencoder.add(UpSampling2D((2,2)))                                    # (32,32,16) -> (64,64,16)
    # want to use sigmoid as our final activation function to make the output more
    autoencoder.add(Conv2D(1, (3,3), activation='sigmoid', padding='same')) # (64,64,16) -> (64,64, 1)

    autoencoder.add(Cropping2D(((2,1),(2,1)))) # (64,64,1) -> (61,61, 1)

После того, как авто-кодер собран, я обучаю его задаче авто-кодирования идобавьте в слой LSTM.


      num_layers = len(autoencoder.layers)

      model = Sequential()
      for i in range(num_layers // 2): 
          model.add(TimeDistributed(autoencoder.layers[i]))


      out_shape = autoencoder.layers[num_layers//2 - 1].output_shape

     # Convolutional LSTM 
     num_filters = 7 
     kernel_shape = (2,2)
     model.add(ConvLSTM2D(filters=num_filters, 
                         kernel_size=kernel_shape,
                         activation='tanh',
                         padding='same',
                         return_sequences = True,
                         name='rnn'))


     ''' #SimpleRNN
      model.add(TimeDistributed(Flatten()))
     model.add(SimpleRNN(rnn_size, 
                   return_sequences = True,
                   activation = 'tanh',
                    name='rnn'))
     # NOTE: since the RNN changes size of output of the final Conv2D layer in encoding section, we somehow have
     #       to map the dimension back down. This is what the Dense layer below does
     model.add(TimeDistributed(Dense(out_shape[1] * out_shape[2], activation = 'relu', name = 'ff')))
     model.add(TimeDistributed(Reshape((out_shape[1], out_shape[2], 1))))
     '''

      for i in range(num_layers//2, num_layers):
          model.add(TimeDistributed(autoencoder.layers[i]))

      # set non-reccurent layers to untrainable; we already trained these to be autoencoders, so the RNN
      # just has to learn how to move the object in the low dimensional space
      for layer in model.layers:
~         if not (layer.name == 'rnn' or layer.name == 'ff'):
              layer.trainable = False


Когда я заменяю количество фильтров на что-то кроме одного, я сразу получаю эту ошибку:

ValueError: количество входных каналов не соответствует соответствующему измерениюof filter, 7! = 1

Я не понимаю, почему количество фильтров должно быть привязано к количеству входных каналов?Разве у нас не может быть несколько фильтров, каждый с разными ядрами на одном входе?

Я попробовал некоторые общие исправления, такие как установка 'data_format = channel_last'

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