web-dev-qa-db-ja.com

keras(TensorFlow)を使用してConv2D + LSTMモデルを構築します

データは10本のビデオで、各ビデオは86フレームに分割され、各フレームには28 * 28ピクセルがあります。

video_num = 10
frame_num = 86
pixel_num = 28*28

Conv2D + LSDMを使用してモデルを構築し、各time_steps(= frame_num = 86)でモデル内のピクセルデータ(= INPUT_SIZE = 28 * 28)を送信したいので、以下はモデルに関する私のコードです

BATCH_SIZE = 2 (just try)
TIME_STEPS=frame_num (=86)
INPUT_SIZE=pixel_num (=28*28)

model = Sequential()
model.add(InputLayer(batch_input_shape=(BATCH_SIZE, TIME_STEPS,     
INPUT_SIZE)))
print (model.output_shape)

model.add(TimeDistributed(Conv2D(64,(1,3),strides=(1,1), padding='same', 
data_format='channels_last')))  ##always the error here
print (model.output_shape)

model.add(TimeDistributed(MaxPooling2D(pool_size=(2,2),padding='same')))
print (model.output_shape)

model.add(TimeDistributed(Conv2D(64,(1,3),strides=(1,1), 
data_format='channels_last', padding='same')))
print (model.output_shape)

model.add(TimeDistributed(MaxPooling2D(pool_size=(2,2),padding='same')))
print (model.output_shape)

model.add(TimeDistributed(Flatten()))
print (model.output_shape)

model.add(TimeDistributed(Dense(4096, activation='relu')))
print (model.output_shape)

model.add(LSTM(100, stateful=True, return_sequences=True))
print (model.output_shape)

model.add(Dense(1, activation='sigmoid'))
print (model.output_shape)

次の図は、コマンドラインからのエラーを示しています

https://imgur.com/a/yAPQO 「リストインデックスが範囲外です」と表示されます

エラーは、上位層(InputLayer())から入力を取得するTimeDistributed()の入力形状に関するものだと思いますが、どうすれば修正できるのかわかりません。 InputLayer()を削除して、

TimeDistributed(Conv2D(...), input_shape=(TIME_STEPS, INPUT_SIZE))

最初のレイヤーと同じですが、同じエラーが発生します...

誰かがこのエラーについて知っているなら、あなたの考えを共有してください、私は非常に感謝します。また、batch_input_shapeとinput_shapeの違いについてはまだよくわかりませんでしたが、以前にこれら2つを使用した人はいますか?ありがとう。

5
Edward Chang

_Conv2D_レイヤーには、3つではなく4つの次元が必要です。

  • _(batch_size, height, width, channels)_。

また、TimeDistributedには追加のディメンションが必要です。

  • _(batch_size, frames, height, width, channels)_

したがって、実際にTimeDistributed + _Conv2D_を使用する場合は、5つのディメンションが必要です。あなたのinput_shape=(86,28,28,3)またはあなたのbatch_input_shape=(batch_size,86,28,28,3)、ここではあなたがRGBビデオ(3色チャンネル)を持っていると仮定しました。

通常、入力形状をTimeDistributedに渡すだけです。

_model.add(TimeDistributed(Dense(....), input_shape=(86,28,28,3))
_

_batch_input_shape_ LSTMを使用する場合にのみ、_stateful=True_が必要になります。次に、input_shapeをbatch_input_shapeに置き換えるだけです。


畳み込み2Dレイヤーのみが、高さと幅の観点から画像を表示することに注意してください。 LSTMを追加するときは、データの形状を変更して、高さ、幅、およびチャネルを1つの次元にする必要があります。

形状(フレーム、h、w、ch)の場合:

_model.add(Reshape((frames,h*w*ch)))
_

また、これらのLSTMではTimeDistributedを使用せず、畳み込み層でのみ使用してください。

model.add(TimeDistributed(Flatten()))を使用するというアプローチは、形を変える代わりに問題ありません。


Kerasが最近_ConvLSTM2D_レイヤーを実装したことにも注意してください。これはあなたの場合に役立つかもしれません: https://keras.io/layers/recurrent/#convlstm2d

9
Daniel Möller