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

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

シンプルRNNをもう少し。予測みたいなことをやってみる:使い方16/ニューラルネットワークコンソール

シンプルRNN(Recurrent Neural Network)のサンプル「elman_net.sdcprj」をちょっと変更して、・・予測みたいな・・こと・・をやってみます。 

深層学習(ディープラーニング)で予測は、分類に並んで常に期待される用途の一つなんですけど、意外に文系人間にとっては、わかりづらい概念なんです。 

正直、過去のデータを時系列に学習したら、あとは予言者みたいに、未来のことを予測してくれる・・そんなのを想像してしまいますが、そんなことはありません。 

ざっくり言ってしまえば、過去の結果を時系列の連続データとして学習したパラメータでインプットデータを変更して出力するだけです。 

ただ、その出力は過去の時系列での変化量を学習した結果なので、インプットの時間よりひとつ進んだ時間における状態で出力されるはずだということなんですね。 

だから、その出力された値をマージして、再度インプットに使っていけば未来の予測も可能である・・と、まあ、そういう理屈です。 

今回は、そんな予測(みたいなこと)をやってみようかなと思ってます。 

といっても、ニューラルネットワークコンソールの現バージョンでは、出力結果を再度マージしてインプットにもっていくようなレイヤーを見つけられませんでした。 

なので、手作業をまじえて確認することにします。 

確認したいことは、SIN()カーブのデータを時系列データとして与えて、正解とRNNによる予測(みたいなこと)とが、どの程度一致しているものなのかです。

 

2017/12/01追記

>以降の説明の画面はVersion1.00のものを使っています。

>Version1.10で一部のアイコンのデザインが変わってます。

>ですが、見たらわかる程度と考えて貼り替えはしてません。

 

時系列データの作成

 

今回はトイプログラムとして、SINカーブデータを時系列データにします。 

こういうデータはEXCELで作るのが簡単です。

f:id:arakan_no_boku:20171015083238j:plain

 

角度は、0から5度ずつ増える連続データを作り、B列でラジアンを計算(例:=(PI()/180)*A2)し、さらにSIN値を計算(例:=IF(MOD(A2,180)=0,0,SIN(B2)))して、200個ほどのデータを作ります。 

そして、C列のSIN値の数値の部分だけを、CSVデータにするわけです。 

この時、25行ずつの8つのファイルにわけておきます。 

ファイル名は、0.csv ~ 7.csv みたいに数字の連番にするのがやりやすいです。 

ちなみに、0.csvから始める理由は、後で確認する結果のアウトプットが0.csvからできていくので、対応するファイルを見つけやすいというだけの理由なので、そこが問題なければ、1.csvからはじめても、他の名前付け規則でもなんでもいいです。 

その8つのファイルをデータ・セットのフォルダに置きます。 

今回は、「sample_dataset」フォルダの下に適当なサブフォルダを切って、その下に配置してみます。

ニューラルネットワークコンソールインストールフォルダ}\samples\sample_dataset

 

そのフォルダへのパスとファイル名を記述したCSVファイルを作ります。

f:id:arakan_no_boku:20171015084913j:plain

 

このCSVファイルを同様に保存(上でデータ用の8ファイルを保存したフォルダに一緒においては駄目ですよ)してから、ニューラルネットワークコンソールを立ち上げて、DATASETタブに追加しておきます。 

この辺のやり方の説明は以下の記事に詳しく書いてますので、わからない場合は、こちらを参考にしてください。

arakan-pgm-ai.hatenablog.com

 

以上で、データの準備はOKですが、ちょっと整理しておきます。 

1ファイルに複数行(今回なら25行)のCSVファイルを作れば、それが行方向に時系列のデータとして扱えます。 

注意点としては、行数✕列数をすべてのファイルでそろえないと駄目なことです。(上記の例だと、25行1列で8ファイルすべてそろえてます) 

なお、ここでは1つの時系列データを25行にしています。 

理由は、いろんな行数で試してみて、25行のときが一番成績がよかったからです。 

念のため。

 

シンプルRNNを組む

 

ニューラルネットワークコンソールでの作業にうつります。 

elman_net.sdcprj を選択して開き、適当な別の名前をつけて保存します。f:id:arakan_no_boku:20171015135303j:plain

 

elman_net.sdcprjは、MNISTの分類問題を行うように構成されていますので、ここから以下の順番に変更を加えていきます。

  1. Inputを上で作成した時系列のテキストデータに変更します。
  2. RecurrentOutput以下を、Affine+Tanh+SquareErrorに変更します。
  3. Inputの変更にあわせて、各レイヤーのIn・Outの値を調整します。
  4. ConfigタブでBatchSizeを小さくする

 

Inputを上で作成した時系列のテキストデータに変更します 

 

DATASETタブを開いて、データ・セット一覧を表示(下図赤丸のボタン)して、さきほど追加したCSVファイルを選択します。 

もし、まだ一覧に追加していな場合は、OpenDataset(下図赤四角のボタン)を押して、フォルダからCSVファイルを選択して追加します。

f:id:arakan_no_boku:20171015141604j:plain

 

今回は、trainingとvalidationの両方に同じデータをセットします。(今回は上記のCSVを、sin_test.csvという名前にしてます)

f:id:arakan_no_boku:20171015142149j:plain

 

trainingとvalidationの両方に同じデータをセットするのが違和感があると思うので、保存しておきます。 

今回は、オリジナルのサインカーブを学習させたパラメータを使って、オリジナルと同じデータをINPUTにした時の結果が描くカーブが、どれくらい、オリジナルに近いのか?を検証しようとしているわけです。 

なので、学習と評価は同じデータをINPUTにする必要があります。 

この辺、分類問題と全く考え方が違うので注意してください。 

さて、話を戻します。 

それから、EDITタブで、inputレイヤーのサイズを、25,1(25行1列)に変更します。

f:id:arakan_no_boku:20171015142420j:plain

 inputレイヤーの変更は、これで終わりです。

 

RecurrentOutput以下を、Affine+Tanh+SquareErrorに変更します

 

もとの、SigmoidとBinaryCrossEntropyErrorを消して、TahnとSquaredErrorに差し替えます。

f:id:arakan_no_boku:20171015142841j:plain

 

このとき、SquaredErrorのT.DataSetを、inputと同じ「x」に変更することを忘れないようにします。(でないと、学習時にエラーがでます)

 

Inputの変更にあわせて、各レイヤーのIn・Outの値を調整します

 

全部、もとは28.28の画像にあわせた値になっているので、変更しないと学習ができません。 

まず、RecurrentInputレイヤーのinputを「25,1」にして、Axisを0にします。

f:id:arakan_no_boku:20171015143623j:plain

 

続けて、AffineのOutShapeを「25」、Tanhのinputを「25」、DelayのSizeを「25」にします。 

そうすると、こんな感じになるはずです。

f:id:arakan_no_boku:20171015144345j:plain

 

あと、ResurrentOutput以降のAffineのOutShapeを「25,1」にします。 

そうすると、以下のようになります。

f:id:arakan_no_boku:20171015144531j:plain

レイヤーの設定は、これでOKです。

 

ConfigタブでBatchSizeを小さくする

 

最後にCONFIGタブを開いて、BatchSizeが64になっているのを、「1」に変更します。

f:id:arakan_no_boku:20171015144912j:plain

 

これをやっておかないと、学習時にデータサイズよりバッチサイズが大きいと怒られてしまいますから。 

さて、これでレイヤーの設定は終わりです。

 

学習と評価をやってみる

 

学習してみます。 

結果はこんな感じですが、学習自体はうまくいってそうに見えます。

f:id:arakan_no_boku:20171015145346j:plain

 

さて評価をします。 

普通に評価ボタンを押すだけです。 

 分類問題みたいに、結果が正解率みたいにでるわけではありません。 

評価が終わっても、こんな感じで、ただデータ・セットが表示されるだけです。

f:id:arakan_no_boku:20171015150625j:plain

 

今のところ、ニューラルネットワークコンソールには、こういう予測結果をビジュアルに表示する機能はありませんので、ここからは、手作業になります。

 

予測結果をEXCELのグラフに落としてみる

 

 以下のように学習・評価した結果には番号が付与されています。

f:id:arakan_no_boku:20171015151220j:plain

 

ニューラルネットワークコンソールのインストールフォルダの下の、今学習・評価を実行しているプロジェクト名のフォルダの下に、この番号と同じ名前のフォルダがあるので、その下に行きましょう。

f:id:arakan_no_boku:20171015151243j:plain

 

そうすると、「0_0000」というフォルダがあります。

f:id:arakan_no_boku:20171015151435j:plain

 

この「0_0000」フォルダの下に0.csv から始まるCSVファイルができてます。

f:id:arakan_no_boku:20171015151858j:plain

 

ここに、Output=inputから予測した結果がはいっています。 

なので、理屈上は、この予測結果のファイルをValidationのデータにまわして、評価させていけば、未来の予測もできるということになるのですが、面倒なので、そこまではやってません。 

単純に、その予測結果をデータを作成したEXCELに手作業で貼り付けて、結果を比較しています。 

結果はこんな感じです。

f:id:arakan_no_boku:20171015152337j:plain

 

平均して誤差率は3%前後でした。 

でもグラフで比較してみると、ほとんど重なってます。f:id:arakan_no_boku:20171015152557j:plain

 

まあ、ノイズも何もはいっていないデータなので、この位の結果は当たり前ではあるのですけど、まあまあ、いい感じではないかなと、個人的には思います。

 

2018/04/04追記

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

arakan-pgm-ai.hatenablog.com

 

2017/12/02追記

Version1.10でアイコンデザインが変更になった部分はこのあたりです。

f:id:arakan_no_boku:20171130202351j:plain

関連情報

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

arakan-pgm-ai.hatenablog.com

 

NNabla(Neural Network Libraries)関連の記事一覧はこちらです。

arakan-pgm-ai.hatenablog.com

f:id:arakan_no_boku:20171115215731j:plain