Керас: Интернет CNN-LSTM.Ошибка с указанием размера пакета для Stateful LSTM - PullRequest
1 голос
/ 18 апреля 2019

Я хочу сделать триггер видео события, который выдает 1 при обнаружении изменения в событии и 0 для других кадров. Я использую CNN, за которым следует LSTM, чтобы сделать это. Оба CNN и LSTM находятся в одной модели и должны быть обучены вместе. Каждый функциональный кадр кодируется CNN, и этот вывод предоставляется LSTM.

Проблема в том, что для обработки онлайн-видео мне нужен онлайновый LSTM с состоянием и работающим с размером пакета 1. Даже после этого Keras выдает мне ошибку:

ValueError: Если RNN имеет состояние, ему нужно знать размер пакета. Укажите размер пакета ваших входных тензоров: - Если используется последовательная модель, укажите размер пакета, передав аргумент batch_input_shape первому слою. - Если вы используете функциональный API, укажите размер пакета, передав аргумент batch_shape вашему входному слою.

Мне нужно знать, где я иду не так и что может быть решением.

Я попытался включить размер пакета во всех слоях. начиная с входного слоя в CNN и даже в LSTM. Модель компилируется, если я не использую stateful = 'True' в LSTM и не упоминаю размер пакета

Я прилагаю полный код.

import time
import matplotlib.pyplot as plt
import numpy as np
from keras.constraints import maxnorm
from keras.models import Sequential,Model
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers import LSTM,Input,TimeDistributed
from keras.layers import Activation
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.utils import np_utils




'''
DAP will get triggered whenever it receives a frame with optical flow 
very different from the previous opticalflow.It uses the optical flow
to determine whether a new event has started to occur in the videoframe
or not.

The CNN is responsible for extracting the optical flow. The RNN/LSTM is
used to trigger the event change by tracking the sequence of online
optical flow frames, being feeded from the CNN at every timestep.

NOTE: Keras does not support summary of a TimeDistributed Model without
specifying inputoutput dimension. Hence this coding approach had to be
incorporated , specifying layer names and seggregating the input output
layers. First we  define the model. The separately define the CNN.
Then add the CNN to the model. And then add the LSTM. This is the only
approach to incorporate online video frame (which doesn't require 
specifying the frame no or the third dimension of the LSTM).

An alternate, and perhaps easier to read, approach is to wrap each layer 
in the CNN model in a TimeDistributed layer when adding it to the main 
model.



INPUT: an 80x80 RGB image
OUTPUT: a sequence of 0 and 1s . 

1 implies an event trigger. 0 implies continuation of the current event

'''

model=Sequential()

#--------------CNN----------------------------------------
x_input =  Input(shape=(80,80,3))
c1=Conv2D(32, (3, 3), padding='same' )(x_input)
a1=Activation('relu')(c1)
c2=Conv2D(32,(3, 3))(a1)
a2=Activation('relu')(c2)
p1=MaxPooling2D(pool_size=(2, 2))(a2)
d1=Dropout(0.25)(p1)
c2=Conv2D(64, (3, 3), padding='same')(d1)
a3=Activation('relu')(c2)
c3=Conv2D(64, (3,3))(a3)
a4=Activation('relu')(c3)
p2=MaxPooling2D(pool_size=(2, 2))(a4)
d2=Dropout(0.25)(p2)
#FCN-----------------------------------------------------
f=Flatten()(d2)
d=Dense(512)(f)
a5=Activation('relu')(d)
x_output=Dropout(0.5)(a5)
#model.add(Dense(2))
#model.add(Activation('softmax'))
#---------------------------------------------------------
cnn = Model(x_input,x_output)
print("CNN SUMMARY")
cnn.summary()

#-----------------LSTM-------------------------------------
model.add(TimeDistributed(cnn,input_shape=(1,80,80,3)))
#model.add(cnn)
#batch size=1,
model.add(LSTM(128,batch_input_shape= 
(1,512),stateful='True',activation='relu'))
model.add(Dense(1,activation='sigmoid'))
#----------------------------------------------------------

model.compile(loss='categorical_crossentropy', optimizer='adam')
print("DAP summary")
model.summary()
return model

Также мне нужно знать, является ли это правильным подходом к кодированию онлайн LSTM.

Общая модель должна вводить 1 кадр видео и выводить 0 или 1 для этого кадра, для каждого кадра видео. (один к одному)

...