"BOKU"のITな日常

62歳・文系システムエンジニアの”BOKU”は日々勉強を楽しんでます

LSTM(Long Short-Term Memory)ユニットでSINカーブトレース/Neural Network Consoleの使い方

前回、elman_netでやってみた「予測みたいなこと」をLSTMでやってみたら、どうなるのかをやってみます。

f:id:arakan_no_boku:20190326212937j:plain

2017/12/02追記

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

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

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

 

なんでやろうと思ったか?

 

ニューラルネットワークコンソールのGoogleグループで「long_short_term_memory(LSTM).sdcprojに定義されたネットワークをそのままUNITSにした高次のレイヤーを要望したら、既に「あるよ!」とのご返事をいただきました。

groups.google.com

それで、そのLSTM(Long Short-Term Memory)ユニットを使ってみたくなったというだけです。

 

予測みたいなこと?

 

前にも書きましたが、今回やるのも、「予測」ではなく、「予測みたいなこと」です。 

予測をするには、入力(x)に対して、結果(y)を推論します。

ですが、今回は入力(x)に対して、途中経過の出力(x')で評価してます。

なので「予測みたいなこと」です。

実際のところ、Auto_Encoderみたいに学習結果を元に生成している感じに近いです。

そんなことをしている理由は「手軽に予測している雰囲気を味わう」ためです。

厳密に見たら、ツッコミところ満載と思いますが、そこはご容赦を。

ちなみに、過去の数値のトレンドから未来の数値を推測してみる・・みたいな・・もう少し「予測っぽい」アプローチは以下の記事で試みてます。

arakan-pgm-ai.hatenablog.com

 

 

 

ちょっと複雑なSINカーブデータを準備する

 

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

arakan-pgm-ai.hatenablog.com

 ただ、ちょっと数字を適当に加工して、こんな感じの複雑なカーブにしてみました。

f:id:arakan_no_boku:20171022214036j:plain

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

 

データセット作成

 

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

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

ニューラルネットワークコンソールで新規プロジェクト

 

ニューラルネットワークコンソールを起動し、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

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

今回は、LSTMユニットを使ってます。

SONYの小林さんは以下のGoogleグループで「現状LSTMユニットは実験的に用意されているもので、実用的にはLSTMの中身を書き下した状態での利用をおすすめしています。」とコメントされていますが・・まあ、実用性のカケラもないお遊びなので(笑)いいとしましょう。

groups.google.com 

 

DATASETタブ

 

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

f:id:arakan_no_boku:20171022220144j:plain

 

TrainingとValidationの両方に同じデータを設定する理由

 

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

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

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

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

ここで、論理的・数学的に「なぜなら・・」と証明できたらカッコいいのですけどね。

自分の場合は、基本、いろいろ試行錯誤してたら、このやり方が一番うまくいったのでそうしている・・という以上のことを言えません(笑)

そのへんはご容赦くださいね。

 

DATASETタブにおける注意点

 

さて、話を戻します。 

今回、データ・セット用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レイヤーで主として変更する必要があるのは、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」にします。

AutoEncoderっぽくやるためです。

f:id:arakan_no_boku:20171022232910j:plain

 

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%でした。  

まあ、こんなもんですかね。

 

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

 

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

 

size=1の時

 

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

エラーにはなりません。 

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

f:id:arakan_no_boku:20171023194909j:plain

 

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

f:id:arakan_no_boku:20171023195120j:plain

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

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