アラカン"BOKU"のITな日常

文系システムエンジニアの”BOKU”が勉強したこと、経験したこと、日々思うことを書いてます。

LSTMユニットというものを見つけたので試しに使ってみる/使い方17:ニューラルネットワークコンソール

LSTM(Long Short-Term Memory)ユニットで、予測みたいなことをやってみます。

 

2018/04/01追記の訂正(ここから)

>以下の記事は、NNC1.00の時に、EVALUATIONした結果として、0_0000フォルダのCSVには、「x'」が出力されていたのを利用しています。

f:id:arakan_no_boku:20180329200234j:plain

>2018/03/29の追記で「ですが、NNC1.10だと「y'」が出力されるようになってます。」と書いていましたが、これは間違いでした。すいません。

>SquaredErrorのT.Datasetのところを、デフォルトのyからxにちゃんと変更していれば、x'で出力されます。

>yのままにしていると、y'がファイルに出力されるというだけでした。

f:id:arakan_no_boku:20180329200421j:plain

>なので、以下の記事の前提がなりたたないわけではありません。

>でも、xを指定してx'を出力する・・だけだと、予測みたいなこと・・にもならない正しくないアプローチの可能性がたかいです。

>一応、それを念頭において、「こんな風に試してみたら、なんとなくSinカーブをコピー的にトレースすることはできました・・」的な記事として参照ください^^;

2018/04/01追記(ここまで) 

 

実は、LSTMだけは、long_short_term_memory(LSTM).sdcprojに定義されたネットワークをそのままUNITSにした高次のレイヤーが用意されています。 

などと・・偉そうに書いてますが、つい最近まで気づいてませんでした。 

恥ずかしながら、ニューラルネットワークコンソールのGoogleグループで要望して、「あるよ!」と教えられて気がついたんですけどね。

groups.google.com

見るからに使いやすく見えますので、早速やってみます。

 

2017/12/02追記

>以降の説明の画像は、Version1.00のものです。

>Version1.10でアイコン等のデザインが一部変更になっています。

>しかし、見ればわかる程度と判断して特に貼り替えてません。

 

時系列データを準備する

データは前回、シンプルRNNのケースで使ったものを使いまわします。 

ただ、あんまりきれいなデータだと面白くないので、ちょっと加工して、こんな感じの複雑なカーブにしてみました。

f:id:arakan_no_boku:20171022214036j:plain

 

グラフだとわかりにくいですけど、なだらかに見えるところも、細かいノイズを入れました。 

データの作り方自体は前回のシンプルRNNのケースと同じです。 

もとになるEXCELの数字をいじくっただけなので、作り方自体は、前回の記事およびCSVテキストベースのデータの作り方をテーマにした記事を参照してもらえればと思います。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

LSTMを使ってネットワークを組む

ニューラルネットワークコンソールを起動し、New Project を開き、適当な名前をつけて保存します。

f:id:arakan_no_boku:20171022215455j:plain

 

そこに、以下の順番でレイヤーをドロップします。

  1. Input
  2. LSTM
  3. Affine
  4. Tanh
  5. SquaredError

 

こんな感じです。

f:id:arakan_no_boku:20171022221538j:plain

 

ただ、デフォルトのままでは、だめなので、設定を変えていきます。

 

DATASETタブで先程作ったデータを設定する

 

Open Datasetボタンで一覧を開き、データの準備のところで保存したCSVファイルをTrainingとValidationの両方に選択します。

f:id:arakan_no_boku:20171022220144j:plain

 

TrainingとValidationの両方に同じデータを設定するのが、ちょっと違和感があるかもしれないので、補足します。 

分類問題なら「未知のデータを推論する」のが基本なので、こんなことはしません。 

でも、今回は学習済のパラメータを使って同じInputデータから推論した結果が、オリジナルとどの程度異なるのか?をためそうとしているわけです。 

なので、学習と評価で全く同じデータである必要があるわけです。 

さて、話を戻します。 

今回、"BOKU"は、データ・セット用CSVはsin_test.csvという前のままで、データの実態である、0.csv~7.csvの方だけを入れ替えるやり方をとりました。 

入れ替え後の状態です。

f:id:arakan_no_boku:20171022220757j:plain

f:id:arakan_no_boku:20171022221032j:plain

 ここで注意が必要なのが、上記図の赤枠のところです。 

今回のように並び順に意味があり、かつ、テキストデータの場合に、Image Normalizationや Shuffle(特に Validationの方)にチェックがついていると、よろしくない結果がおきますので、ちゃんとはずれているかを確認してください。

 

inputレイヤーを設定します

 

25行1列のテキストデータを使うので、sizeを「25,1」に変更します。

f:id:arakan_no_boku:20171022221707j:plain

 

LSTMレイヤーを設定する

LSTMレイヤーは、今のところレイヤーリファレンスに記載されていないんですよね。 

だから、Googleグループのコメント等を参考にして、試行錯誤してみました。 

LSTMレイヤーで主として変更する必要があるのは、sizeとaxisの2つみたいです。 

axisは、時系列の方向が、0=行方向 か 1=列方向かを指定するみたいです。 

今回は行数で時系列をあらわしているので、0ですね。 

sizeは、LSTM内のニューロンの要素数・・という事なのですが、いくつが適切かの基準がよくわからなかったので、色々と数字を変えて試してみた結果、もっとも成績のよかった「25」でやってます。 

その結果は以下の通りです。

f:id:arakan_no_boku:20171022232337j:plain

 

AffineレイヤーとTanhレイヤーの設定

Affineは、OutShapeだけを変更しました。

f:id:arakan_no_boku:20171022232614j:plain

Inputと同じ「25,1」を指定しています。 

ここを変えると、Tanhの設定も自動的に調整されるので、そっちはさわりません。

 

SquaredErrorの設定

こちらは例によって、T.Datasetの変数名をInputと同じ「x」にします。

f:id:arakan_no_boku:20171022232910j:plain

デフォルトは「y」になってます。 

ここが「y」のままで学習と評価はエラーなく終わるのですが、0_0000フォルダはできません。 

必ず変更してください。

 

CONFIGタブの設定

BatchSizeを小さくするのを忘れないようにしてください。 

デフォルトで64ですが、そんなにデータ数がないので、いきなりエラーになって動きません。 

とりあえず、「1」にしとけば動くので、そうしておきます。

f:id:arakan_no_boku:20171022233941j:plain

 

これで上書き保存します。 

これで準備はできました。

 

学習と評価の実行

学習を実行します。 

学習にはそれなりに時間がかかります。 

結果のグラフはこんな感じです。

f:id:arakan_no_boku:20171022234421j:plain

LSTMは収束に時間がかかると聞いていたのですが、意外にすんなり収束しているように見えます。 

続けて評価を実行します。 

結果で、x'が表示されていれば、0_0000フォルダにファイルはできてます。

f:id:arakan_no_boku:20171022234801j:plain

 

予測みたいなことの結果を検証 

 

名前をつけて保存したプロジェクトを例えば、my_lstm.sdcprjという名前にしていたら、同じフォルダに「my_lstm.files」というフォルダができているはずです。 

そこでTRAININGまたはEVALUATIONの実行時の番号と同じフォルダの下にある、「0_0000」フォルダを開きます。

f:id:arakan_no_boku:20171022235321j:plain

 

そこに、0.csvから7.csvというファイルができて、1行25列でデータができているので、それを比較用に、行列を入れ替えて貼り付けます。 

そうすると、オリジナルと出力の比較ができます。 

今回の最終結果のグラフはこんな感じです。

f:id:arakan_no_boku:20171022235745j:plain

 ほとんど、重なりあっててわかりにくいですが、微妙に点線がずれているところがあるので、オリジナルと予測の2つの線があることがわかります。 

ちなみに、別途数字の比較で平均誤差率も計算したのですが、0.56%でした。 

前回のシンプルRNNより、複雑なデータで条件が悪いわりに、良好な結果です。 

LSTMの実力ってことですかね・・。

 

おまけ・・Sizeパラメータ決定までの試行錯誤

前の方で、LSTMのパラメータの「size」を試行錯誤の結果、25に設定したと書いたのですけれど、 じゃあ・・sizeの数値が適切でないと、どんな結果になるのか?も、ついでに書いておきます。 

極端な例の方が面白いので、size=1でやった時の例です。 

エラーにはなりません。 

でも、学習の結果はこんな感じで、収束が遅くなります。

f:id:arakan_no_boku:20171023194909j:plain

 

この状態で評価した結果はこうです。

f:id:arakan_no_boku:20171023195120j:plain

 学習がちゃんとできてないですよね。 

ということで、パラメータの指定でエラーになってくれるとわかりやすいですが、こんな風に、エラーにはならないけど、結果が悪い・・こともあります・・という、おまけでした。

 

関連情報

ニューラルネットワークコンソールカテゴリの記事一覧はこちらです。

arakan-pgm-ai.hatenablog.com

NNablaカテゴリの記事一覧はこちらです。

arakan-pgm-ai.hatenablog.com

f:id:arakan_no_boku:20171115215731j:plain