no-image

KerasでSimpleRNNとLSTMを使ってcos波を予想する

練習がてらKerasを使ってRNNを用いてcos波の予想をしてみた。

学習データとして以下の図のような少しノイズを加えたcos波を使います。

 

まずはお手並み拝見としてKerasのSimpleRNNを使って試してみます。

RNNを用いて再帰的にデータを学習して、cos波を予想しています。
つまり、学習初期は点線を教師データとして赤線を作っていき、
中盤か終盤にかけては、その赤線を教師データとして新たな赤線を作っています。

しかし、ひと目見たら分かる通り、上手く学習できていないようです。
また進めば進むほどノイズが顕著に学習されてしまっています。
何故そうなるかというと前回の記事にも書いたように(多分)勾配が消失しているのでしょうか。
どんなふうに勾配が変化したのか見てみたいですね・・。
これはまた今後やってみたいと思います。

それではこれを前回の記事に書いたLSTMを使って再学習してみます。
コードの変更点はたったの2箇所だけです。
import文とmodelを重ねる部分を「SimpleRNN」から「LSTM」に変えるだけです。とても簡単ですね。さすがKeras。

今回使用したハイパーパラメーターは以下のような感じです。

  • batch_size: 10
  • epoch: 50
  • 隠れ層の数: 1
  • 入力層のユニット数(n_in): 1
  • 隠れ層のユニット数(n_hidden): 25
  • 出力層のユニット数(n_out): 1
  • Activation function: linear
  • dropout: なし(0%)
  • Optimizer: Adam(パラメータは論文が推奨する値)
  • Loss function: mean_squared_error(平均二乗誤差関数)
  • maxlen(1つの時系列データの長さ): 50

ハイパーパラメーター調整の参考
再帰型ネットワークと長・短期記憶についての初心者ガイド – Deeplearning4j: Open-source, Distributed Deep Learning for the JVM
わかるLSTM ~ 最近の動向と共に – Qiita

 

最終的なlossは0.0016242796237329168でした。

lossの変化の様子を見ると、最初にグッと下がってそこからはあまり変化はないようです。

また出力を見てもわかるようにepoch50で回していますが、early_stoppingがうまく働いて39エポックでストップしています。

せっかくなので少しパラメータを変えて違いを観察してみました。
まずはエポックを5に極端に下げてみました。
ちょっとふにゃふにゃしてますが、この時点でも意外と優秀な結果が出ています。

 

 

次に、n_hidden(入力層の出力のノード数)を38にしてみました。

最初の結果よりも赤線が正規のcos波に重なっているように見えます。
最終的なlossは0.0010274603597021528となっていました。
若干ですがやはりさっきよりも良い値が出ています。

 

【機械学習】パラメータの重みの初期値 – Qiitaのサイトを見るとなんだかHeの初期値が良いみたいなので、重みの初期値にHe_normalを採用してみました。

lossは0.0010618205012250987でした。若干下がりましたね。
また、残念ながらKerasには現在「覗き穴結合」が実装されていないらしいです。
これをKeras上で用いるにはtensorflowのコードを書くか、RecurrendShopなどのKeras上のフレームワークを使う必要があるみたい。これは時間がかかりそうなので、この本を2周目したときに挑戦してみたいと思います。

matplotlibの凡例を日本語化はここを参考にしました。
matplotlibで、判例やグラフタイトルに日本語を使用する – Symfoware

メモ
2周目にすること
・勾配の推移を可視化
・TensorFlowコーディング
・LSTMCell(TensorFlow)
・GRUについて