これでLSTMとして合ってるのでしょうか?

748 views
Skip to first unread message

モグ

unread,
Jul 9, 2021, 7:00:43 AM7/9/21
to Neural Network Console Users (JP)
相変わらずの全くの素人で恐縮です。
11項目、480日分を1データとした時系列のデータです。
図1がLSTMとして作ったもので、図2がそれを基に構造自動探索にて出来たものです。

Q1.これでLSTMとして合ってるのでしょうか?
 Accuracy精度も余り芳しくありません。
  修正する箇所なども教えてください。

Q2.LSTMの特性として、時系列の日数(現在は480日)を長くするほどAccuracy精度も上がるのでしょうか?
 今現在はその傾向にありますし、必要とすればデータ数も有り余るほどあります。
図1.JPG
図2.JPG

yoshida.hi...@gmail.com

unread,
Jul 15, 2021, 9:25:18 PM7/15/21
to Neural Network Console Users (JP)
ちょっと時間が経っていますが、どなたも反応していないので、コメントしてみます。

Q1ですが、LSTMには色々な改善案があるので、「これでLSTMとして合っているか」という質問の意図にもよります。
以下はWikipediaの画像ですが、これが一般的なLSTMですので、「この形になっているか」、ということだとしてお答えします。

これと図1.JPGを比較すると、以下の3点が合っていません。
・隠れ層の出力を 回帰結合していません。Wikipediaの図では、左下でh_(t-1)とx_tを合流させています。
 図1.JPGで言うと、RecurrentOutputへの入力を分岐させてDelayに入れ、RecurrentInputの出力とConcatenateしてから、メインルートと各ゲートに配給する形になります。
 ただ、隠れ層の出力を 回帰結合しないバージョンの"LSTM"もあるようです。
・Cellをそのまま出力しています。Wikipediaの図では、tanhを通してからh_tを出力しています。
 図1.JPGで言うと、Tanhを通してからRecurrentOutputへ入力します。
・Outputゲートがありません。Wikipediaの図では、tanhの後にもう一つゲートを設置しています。
 図1.JPGで言うと、ForgetGateの右にもう一組ゲートを設けて、上記のTanhとRecurrentOutputの間でMul2を使って合流させます。
 ただし、Outputゲートが無いバージョンの"LSTM"もあるようです。

Wikipediaの図とは関係無いのですが、もう一点、気になることがあります。
RecurrentOutputの次のSliceで380日分を切り取って、AveragePoolingとAffineに入れていますね。
RNNの訓練データとしては、毎日の正解ラベルがある場合と、当日の正解ラベルしか無い場合とがありますが、この例ではSoftmaxが1次元なので後者ですね。その場合、通常はSliceで最後の日だけを切り取って、出力層に繋げるのが普通です。
毎日の正解ラベルがある場合は、Sliceしないで2次元のSoftmax(480×3)で出力して480日分の正解を与えます。
この例のように、出力層に380日分の隠れ層出力を入れるのは、必ずしも間違っているとは言えないとは思いますが、LSTMの中でせっかく480日分の特徴量を抽出して当日分にAdd2しているのに、そのあとでもう一度380日分のデータを使う意味があるのか疑問です。

そもそもRNNは、前日記憶した隠れ層のデータ c_(t_1)、h_(t_1)と、当日のデータx_tだけから当日を予測するものです。
そのためには、推論用にはRecurrentInputとRecurrentOutputを外して当日データだけを入力するネットワークに変更するのですが、図1.JPGのネットワークではそのようには変更できないように思います。

図2.JPGは、回帰結合がそもそも無いので、これはLSTMとはまったく言えないと思います。
構造自動探索は、ランダムサーチでパラメタ数がより少ない構造を主に探す機能なので、元のネットワークの意図とは違うものを発見することがあります。
それはそれで悪いことではなく、LSTMのような複雑な構造を使わなくても十分に解ける問題だったことがわかる場合もあるわけです。
ただし、図2.JPGのネットワークでは、常に480日分のデータを入力しなければなりません。
逆に言えば、それができなくて、前日と当日のデータしか入力できない場合に使うのが本来のRNN/LSTMだと言えるかもしれません。

次にQ2ですが、一般的にはYesだと思います。
ただしLSTMは、この例では過去480日間に起こった出来事を50次元の特徴量として記憶しているわけですので、解こうとしている問題が480日以上前の出来事とはあまり関係が無いのであれば、長くしてもあまり精度は上がらないでしょう。

2021年7月9日金曜日 20:00:43 UTC+9 モグ:
Message has been deleted

yoshida.hi...@gmail.com

unread,
Jul 18, 2021, 10:24:38 PM7/18/21
to Neural Network Console Users (JP)
新しい図1.JPGを拝見しました。隠れ層は典型的なLSTMにきちんとなっているように思います。
※配置方法が、小林さんのYouTube動画の通りに見えますが、参考にされていますか?

入力層にReshapeがありますが、これはInputが480×11の2次元になっていれば不要ではないでしょうか。
Reshapeが必要なのは入力データが1項目しかなく480の1次元の場合で、Reshapeで480×1に変換します。

問題は、RecurrentOutputの直後にあるAffineです。
ここにこの形のAffineを置く例が、Qiitaの記事や一部の参考書に散見されるのですが、これは問題だと思っています。
この形だと全体としてRNNとは言えない、と考えますので、説明します。

まず、RNNとは何かで意見が分かれると面倒なので、小林さんの以下のYouTube動画の1:40あたりにある「Recurrent Neural Networksによる時系列データの認識」という図にあるもののことだ、としてください。
「S」「O」「N」の次の文字は「T」ではなく「Y」であることを認識する例です。
この図では、入力層も、隠れ層も、出力層もそれぞれ4つあります。
4つの隠れ層は同一の重み、4つの出力層も同一の重みを持ち、隠れ層が時系列順に結線されています。
これがRNNの基本構造です。
この図は4時刻ですが、480時刻あるととても大変でし、さらにLSTMを使うと隠れ層が複雑になりますが、基本構造はこの形です。

そして、この基本構造のままだと学習が面倒なので、NNCはRecurrentInput/Outputという部品を提供していて、入力データや正解データを配列で渡して、隠れ層と出力層を1つだけにして、4時刻分とか480時刻分とかをまとめて学習できるようにしています。

次に同じ動画の3:25あたりで解説されていますが、時系列データを入力して一つの答えを出力するMany to One、時系列データを入力して同じ長さの時系列データを出力するMany to Many(1)などのバリエーションがあります。

さて、モブさんの場合ですが、出力層のSoftmaxで3項目にしているので、Many to Oneの形ですね。
小林さんの別の動画(以下)の1:15あたりで説明されているのがMany to One型のRNNです。

この動画では小さくて見にくいと思いますが、右側の学習用ネットワークではRecurrentOutputの次にSliceを入れ、最後の時刻のものだけを取り出して、出力層に入れています。
モブさんの図1.JPGはSliceが無くていきなりAffineに100×480を入れていますが、この形だと左側の基本形ネットワークと同じ構造にならず、480日分の隠れ層のすべてのデータを出力層に入れていることになります。
動画の左側の基本形ネットワークで言えば、中ほどにたくさん並んでいるTanhすべてから、下のAffineに結線がある形になります。
なので、これではRNNにする意味が無いと思います(なぜかは後述)。

本来のRNNの形にするためには、RecurrentOutputとAffineの間にSliceを入れて、Start=0, 479、Stop=100, 480、Step=1, 1とすればいいだろうと思います(プロパティの設定は間違っているかもしれないのでレイヤーリファレンスで確認してください)。

ちなみに、正解ラベルを毎日提供できる場合は、Many to Many(1)の形のRNNが作れます。
上記の「S」「O」「N」「Y」の形のネットワークになります。
この場合でも、RuccurentOutputの後にAffine(Outshape=480, 3)を接続すると、RNNではなくなってしまいます。
上記の「S」「O」「N」「Y」ネットワークで言えば、出力層が4つではなくて、1つになってしまい、4つのTanhと全結合している形です。
これだと、「S」「O」「N」「?」という4データを入力して、「SONY」という1データを出力するネットワークです。

Many to One、Many to Manyのどちらの場合でも、RecurrentOutputにAffineを直接接続すると、その出力層は480日分の全データを参照することになるので、隠れ層でわざわざ時系列順にデータを後ろに回して記憶している意味がありません。つまりRNNを使う意味が無い、ということです。
最後に全時刻分を使えるのであれば、LSTMで頑張って忘れたり記憶したりスイッチしている意味がありません。

Many to Manyの場合は、同じ重みの出力層が480個ある形にする必要があるので、出力層全体(Affine、BatchNormalization、Softmax)をRecurrentOutputの前に置くことになります。
この時、AffineのOutShapeは3です。Recurrentの中にあるのでこれで×480,3になります。
RecurrentOutputの出力は480×3になるので、これをCategoricalCrossEntropyで480x3の正解ラベルと比較することになります。

Qiitaの記事や一部の参考書で、(レイヤーリファレンスでは「使うな」と言っている)LSTM部品を使って、その直後にAffineを接続している例が散見されますが、LSTM部品は内部にRecurenntOutputを持っているので上記の問題(RNNとは言えない!)が生じていると考えます。
2021年7月16日金曜日 22:00:23 UTC+9 モグ:
yoshida.hi... 様
ご丁重なるご回答ありがとうございます。
詳しいご解説もいただき素人ながらも理解もできたような気がします。
試行錯誤と構造自動探索の末、このようにもなってもしまいましたが、改めて原点に戻り作成もしてみました。
お手数をお掛けし申し訳ございませんが再度お目通しもいただければ有難いです。
正解ラベルは480日×11項目を1データとしてのものともなってもいますしSliceについては削除も致しました
Q2については一般的にはYesとこと。
480日間と50次元との兼ね合いで調整もしてみることにします。

2021年7月16日金曜日 10:25:18 UTC+9 yoshida.hi...@gmail.com:
Message has been deleted

yoshida.hi...@gmail.com

unread,
Jul 27, 2021, 3:42:35 AM7/27/21
to Neural Network Console Users (JP)
私が「配置方法が、小林さんのYouTube動画の通りに見えます」と書いたのは、まさに 「Deep Learning入門:数式なしで理解するLSTM 」のことです。あの動画はとても参考になりますね。

さて、図3.JPGを見て気づいたのですが、結果ラベルが3択ならば、Softmaxへの入力は3つでなければいけません。Affine_2のOutShapeを「3」にしないと。
Softmaxは3つの入力を調整して、合計が1.0になるような出力(つまり3つの解の確率分布)を作ります。
そのあと、CategoricalCrossEntoropyが0,1,2のいずれかのラベルを見て、正解値の確率Pに対して-log(P)をエラー値とします。正解値の確率が1.0であれば、-log(1.0)=0.0となってエラーが0になるわけです。

構造自動探索の使い方も小林さんが動画で説明されていますが、同等の結果(か多少悪くても)をより少ない計算量・メモリ量で求められるネットワークを探すのに向いています。学習した結果をリソースが少ないスマホやマイコン上で動作させる時など。
そうでない時は使ってもあまり効果は得られないと思います。GPUを使うようなリッチな環境で使うことはあまりないので、もしかしたらバグが残っているのかもしれませんね。

2021年7月21日水曜日 0:37:01 UTC+9 モグ:
yoshida.hi... 様
このような超初心者にもかかわらず重ねてのお教え誠にありがとうございます。

当データは1日11項目の数値データを、時系列にて480日分集め、それを1パック一括りとし、それに対する3択での結果ラベルもつけ作成もしたもので、現状ではその全体数はおおよそ3,000パックほどもあり、それを学習と評価ファイルとに振り分けもし作成もし使ってもいます。

また先般の07/16 22:00 図1.JPGについても、下記を参考にもし作成もしたものですが、果たしてそれで合ってるかについては正直いささか未知なところもあります。
「Deep Learning入門:数式なしで理解するLSTM (Long short-term memory)」

今般添付の図3.JPGは、お教えもいただいたようにも修正もした積りのものです。
お目通しもいただけると有難いです。
ただ不思議なことには何故か、そこからの構造自動探索中には下記のようなメッセが出てもしまい、構造自動探索自体もストップもしてしまい、その先が進まないことにもなったりもすることもあります。(Windows版 Ver2.1.0)

C:\a\w\sDeepConsolePrototype\sDeepConsolePrototype\nnabla\src\nbla\computation_graph\function.cpp:83
Failed `input->allow_modify_data()`: Modifying data is prohibited by the parent function of the 0-th input data of 'Add2CudaCudnn' (depth=4). (Parent is 'SigmoidCudaCudnn').
(null)
(null)

モグ

unread,
Jul 27, 2021, 9:38:40 AM7/27/21
to Neural Network Console Users (JP)
ありがとうございます。
お手数をお掛けし申し訳ございません。

YouTube動画は同じだったのですね。
まだまだ分からぬままにもとても参考になります。

Affine_2のOutShapeは図4のようでよろしいのですね?
見直しましたが「3」にはなってました。

構造自動探索はそのようなこともあるのですね。
もう少し試行錯誤してみます。

2021年7月27日火曜日 16:42:35 UTC+9 yoshida.hi...@gmail.com:
図4.JPG

モグ

unread,
Aug 7, 2021, 5:51:30 AM8/7/21
to Neural Network Console Users (JP)
上にも書きましたように3択のラベルも付け学習から推論までをしています。
ところが実態に伴った推論がされる時もあれば、それとは明らかに真逆の推論がされる時があります。
Accuracy精度は0.7程度はあるのですが、まだ低いとのことなのでしょうか?
どのようなことでも構いません、お気づきの点などお教えのほどお願いします。

Reply all
Reply to author
Forward
0 new messages