この質問はgithub issueとしても存在します。 私は、2次元畳み込みとLSTMレイヤの両方を含むKerasにニューラルネットワークを構築したいと考えています。Keras:lstmとconvを接続するための再構成
ネットワークはMNISTを分類する必要があります。 MNISTのトレーニングデータは、0〜9の手書き数字の60000グレースケール画像です。各画像は28x28ピクセルです。
イメージを4つの部分(左/右、上/下)に分割し、4つの順序で並べ替えてLSTMのシーケンスを取得しました。小サブ画像の
| | |1 | 2|
|image| -> ------- -> 4 sequences: |1|2|3|4|, |4|3|2|1|, |1|3|2|4|, |4|2|3|1|
| | |3 | 4|
つの寸法を有する14 X 14 4つのシーケンスは、(幅または高さかどうかは問題ではありません)の幅に沿って互いに積層されています。
これは形状のベクトルを作成し、[60000、4、1、56、14]:サンプル
- 60000(#時間ステップ)の
- 1は、色の深さがKerasモデルに与えられるべきである(グレースケール)
- 56及び14の幅であり、高さは今、この
あります。 問題は、CNNとLSTMの間の入力ディメンションを変更することです。 私はオンラインで検索して、この質問を見つけました:Python keras how to change the size of input after convolution layer into lstm layer
ソリューションは、画像を平坦化するが、(BATCH_SIZE以外のすべてを崩壊してしまう平坦化層とは反対に)タイムステップを保持リシェープ層であるように思われます。
ここに私のコードは、これまでのところです:
nb_filters=32
kernel_size=(3,3)
pool_size=(2,2)
nb_classes=10
batch_size=64
model=Sequential()
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1],
border_mode="valid", input_shape=[1,56,14]))
model.add(Activation("relu"))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Reshape((56*14,)))
model.add(Dropout(0.25))
model.add(LSTM(5))
model.add(Dense(50))
model.add(Dense(nb_classes))
model.add(Activation("softmax"))
このコードは、エラーメッセージを作成します。
ValueError: total size of new array must be unchanged
はどうやらリシェープ層への入力が正しくありません。別の方法として、私はあまりにも、形状変更層にタイムステップを渡そうとしました:
model.add(Reshape((4,56*14)))
をこれは右感じていないし、いずれにしても、エラーは同じままです。
これは正しい方法ですか? ReshapeレイヤはCNNとLSTMを接続する適切なツールですか?
この問題にはかなり複雑なアプローチがあります。 このように: https://github.com/fchollet/keras/pull/1456 タイムディストリビューションされたレイヤーで、次のレイヤーからタイムステップディメンションを隠しているようです。
またはhttps://github.com/anayebi/keras-extra CNNとLSTMを組み合わせるための特別なレイヤのセット。
シンプルな変形(Reshape)がそのトリックを行うなら、なぜ複雑(少なくとも彼らは私にとっては複雑に見えます)のソリューションはありますか?
UPDATE:
あきれるほど、あまりにも、畳み込みを、私は寸法がプールで変更されることを忘れて(パディングの不足のため)。 kgrmは、model.summary()
を使用して寸法を確認するように指示されました。
リシェイプレイヤーの前のレイヤーの出力が(None, 32, 26, 5)
, に変更されました。model.add(Reshape((32*26*5,)))
に変更されました。
今とValueErrorが消えて、代わりにLSTMは文句:
Exception: Input 0 is incompatible with layer lstm_5: expected ndim=3, found ndim=2
私はネットワーク全体を通じてタイムステップ寸法を渡す必要があるように思え。どうやってやるの ?私はコンボリューションのinput_shapeにそれを追加した場合、それはあまりにも、文句:Convolution2D(nb_filters, kernel_size[0], kernel_size[1], border_mode="valid", input_shape=[4, 1, 56,14])
Exception: Input 0 is incompatible with layer convolution2d_44: expected ndim=4, found ndim=5