"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

シンプルRNN「elman_net」をベースに予測みたいなことをやる:使い方16

前回、サンプルプロジェクト「elman_net.sdcprj」を試しに動かしてみたのですが、いまひとつ・・ピンときませんでした。

arakan-pgm-ai.hatenablog.com

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

なお、「予測」ではないです。

(なぜ、予測ではないかは、最後に追記してます)

 

今回やるのは、学習した特徴量を使って予測・・というと、学習データ量が沢山必要だったり、色々とハードルが高いので、少ない手間で予測の雰囲気を味わうには・・っていう観点で考えてみたものです。

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

 

予測という用途について 

 

ざっくりとさわりだけ。 

深層学習(ディープラーニング)での予測って、意外に文系人間にとっては、わかったようで、わかりづらい概念だなと思ってます。 

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

でも、そんなことはありません。

神様を作れるわけじゃないのですから(笑) 

ざっくり言ってしまえば。

ディープラーニングでできることは、過去の結果を時系列の連続データとして学習した特徴量をもとに計算した結果を出力するだけです。 

だから、その出力は過去の時系列での変化量を学習した結果を使い、インプットの時間よりひとつ進んだ時間における状態を予測したものになるはずだよな・・と考えるとイメージしやすいんじゃないかと思います。 

そして、その出力された値をマージして、再度インプットに使って繰り返していけば、未来の予測も可能になるはずだ・・てな感じです。 

 

SINカーブの予測みたいなこと?

 

そういう理屈が成り立つのかを確認できないかな・・と考えて、SINカーブの例をどっかで見たことを思い出しました。

SINカーブって曲線で、その変化を時系列と見たら、それを学習させた結果で、その先を予測させてみたら、答え合わせも容易だし良い確認になると思います。

で・・今回、やってみようと思います。 

ただ・・ですね。

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

(自部が見つけられなかっただけなら、すいません) 

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

 

 

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タブ

 

ニューラルネットワークコンソールを立ち上げて、DATASETタブに追加します。 

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

arakan-pgm-ai.hatenablog.com

 

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

 

1ファイル25行で8ファイルにわけた意味

 

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

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

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

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

念のため。

 

elman_net.sdcprjの改造

 

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

 

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

 

ニューラルネットワークコンソールの結果格納フォルダ

 

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

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に貼り付けてグラフ化

 

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

結果はこんな感じです。

f:id:arakan_no_boku:20171015152337j:plain

 

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

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

 

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

なんとなく、RNNの雰囲気(・・ぽい)はありますしね。

今回はこんなとこで。

ではでは。

 

追記(予測みたいなこと・・という理由)

 

入力のxに対して、x'で結果を評価しているところです。

LSTMというRNN (リカレントニューラルネットワーク)を使っているわけですが、通常のニューラルネットワークと隠れ層の扱いの違いはあっても、最終的に結果(y)を推論する点は同じなんだということなのです。

なのに、データ(x)に対して結果ラベル(y)を無視して、途中経過の出力であるx'だけを見るアプローチは、あくまで雰囲気を味わうための「予測みたいなこと」でしかないということです。

Googleグループでも同じ話題がコメントされてました。

groups.google.com

一応、補足しておきます。

 

2018/04/04追記

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

arakan-pgm-ai.hatenablog.com

 

2017/12/02追記

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

f:id:arakan_no_boku:20171130202351j:plain

 

f:id:arakan_no_boku:20171115215731j:plain