大学の実験で必要になって実装したのでメモしておきます。
Convolutional LSTM の説明
名前で完全にネタバレしてる感が否めないですが、Convolutional LSTM とは、LSTM の結合を全結合から畳み込みに変更したものです。
例えば画像を RNN に食わすときに、位置情報が失われないので便利です。
動画の次フレームの予測や天気予報などに使えます。
具体的には、以下のような構造になっています。
x は要素ごとの掛け算、 * は畳み込みを表します。
通常の LSTM との差分を赤で書きました。といっても、一部の掛け算が畳み込みになっているだけですが。
peephole の部分だけ要素ごとの掛け算になっていることに注意してください。
実装
Convolutinoal LSTM と、それをビルディングブロックとして使って画像予測のネットワークを実装しました。
レポジトリです。
python3.5.2
+ chainer 3.0.0
で開発しました。
画像予測のネットワークは以下のような構造をしています。([1] より抜粋)
左側のネットワーク(Convolutional LSTM を 2 層並べたもの)に、入力となる画像(例えば 1 フレーム目, 2 フレーム目, 3 フレーム目)を流し込んでいって、データの表現を得ます。
次に、左側の LSTM たちの内部状態を右側の LSTM たちにそれぞれコピーします。
最後に、右側のネットワークにゼロを入力して、出てきた値を concat して、それらを 1x1 で畳み込んで出力を得ることを繰り返します(例えばこれが 4 フレーム目の予測画像, 5 フレーム目の予測画像, 6 フレーム目の予測画像になります)
右側のネットワークの二回目以降の入力は、前回の出力を入れるという実装もありそうです。論文を読んだ限り特に書いてなさそうだったので、今回はゼロを入力するようにしました。
実験
Moving MNIST [2] で実験しました。
計算資源の都合上論文の実装より小さめのネットワークです。
具体的には 2 -> 5x5 Conv -> 128 -> 5x5 Conv -> 64 -> 5x5 Conv -> 64 -> 1x1 Conv -> 2 (右側の forecasting network) という感じです。
以下は生成された画像たちです。
まあいいんじゃないでしょうか。
Loss です。
もう少しちゃんとチューニングする必要がありそうですかね。
だいたい 20 epoch = 8750 iteration = 140000 images の訓練を p2.xlarge (GPU は K80) 上で行って 22 時間くらいでした。
最後に
何か間違いや質問などがあればお願いします。
最後まで読んでいただきありがとうございました。
参考文献
[1] Xingjian Shi, et. al. Convolutional LSTM network: A machine learning approach for precipitation nowcasting. In NIPS, 2015
[2] Moving MNIST