https://github.com/toyowa/jautoencoder
で公開しているプログラムの覚書を書いておこうと思う。これから、ロボットのセンサーを増やす作業に入るので、どういうプログラムだったか忘れてしまいそうなので。この(1)では、全体的なことを書いておく。
1。データに関して
データのフォーマットは、
https://github.com/huangzehao/SimpleNeuralNetwork
のサイトのプログラムを参考にさせてもらった。(プログラムは、独立に私が自分で書いたものだ。プログラムは参考にするほど理解できなかったが、自分で書かないと使えないだろうと思ったから)
データの最初の1行は、
topology: 784 400 10
のようにネットワーク構造を書く。ここで、784が入力レイヤーのニューロン数。以下出力ユニットまで、にゅう論数を書いていく。レイヤーの数にもニューロン数にも制限はない。
その後に続いて、in:とout:の接頭語に続いて、交互に、入力データと出力データを空白を区切って書いていく。
MNISTの手書き数字データに関しては、データの読み取りは、
http://nonbiri-tereka.hatenablog.com/entry/2014/09/18/100439
を参考にさせていただいて、それを上記のデータフォーマットに書き直したものだ。
https://github.com/toyowa/jautoencoder/tree/master/MNIST
に変換用のプログラムをおいてある。
データプログラムは、実行時オプション -dataで指定できる。
2。ウェイトファイル
学習後にウェイトデータを吐き出し、テストの時はそのファイルを実行時オプション -weights で指定して読み込むことになる。ただし、ウェイトファイル名は、wgtのさフィックスがないと拒否するようにしている。データと間違わないように。データのさフィックスは特にチェックせずに読み込む。
吐き出されたウェイトファイル名には、そのファイルが作成された日時が秒までつくので、識別できると思う。ウェイトファイルの頭の部分に、その学習のネットワーク構造やパラメータや、繰り返し数などが書かれている。
-------------------
File name: [ weight_170603192205.wgt ]
Iteration: 179997
InputData: trainingData.txt
Topology: 784 300 150 10
Adjusting: 0.15
Label: Pre_neuron No. -> Layer No. : Neuron No. = Weight
Weight: 0 -> 1 : 0 = 0.0003876341
Weight: 1 -> 1 : 0 = 0.0011203298
Weight: 2 -> 1 : 0 = 0.0004425993
Weight: 3 -> 1 : 0 = 0.0007930749
...........
...........
---------------------------------
なお、テストじゃない時にウェイトファイルを指定すると、そのウェイトを読み込んで、そこに書かれているそれまでの学習の実行の続きをやることになる。何回かに分けてやりたいとか、中間状態を見たい時には、そのような方法もできる。プログラムのデバッグの時は、一回だけ学習させるということもやった。実行時ぷションの、-maxiterで1を指定すると一回だけやる。
なお、-maxiterを指定しないと、データがある限り学習を続ける。
3。テスト
テストの時は、できたウェイトファイルとテスト用データの両方を実行時オプションで指定して、-test オプションを付け加えれば良い。当たり前だが、ウェイトファイルとテスト用データは、ネットワーク構造に関して整合的でなければならない。-weightsでウェイトを指定しないと、当然だが、ランダムに与えたウェイトでテストしてしまうので、テストは無意味だ。チェックして排除するようにすべきだったかもしれない。テスト結果はコンソールに出力される。
4。オートエンコーダー(Autoencoder):深層学習
実行時オプションで -auto をつけると、オートエンコーダーとバックプロパゲーションで学習する。オートエンコーダーとは、隠れ層へのウェイトを1層ずつ、一つの圧縮符号化器のように作っていくことだ。例えば、MNISTで、入力784ニューロン、300と150の隠れ層、出力層が10ニューロンだとしよう。それぞれのレイヤー(層)にA,B,C,Dという名前をつけよう。
まず、ABにA'というAと同じニューロン数のレイヤーをつけて、A'の学習データとして、Aと同じものを使うという作業をする。そして、ウェイトをバックプロパゲーションで形成するという作業をする。一見無意味なようだが、よく考えてみると重要な意味を持っている。AがA'で再現されるんだが、BはAよりもニューロン数が少ない。それが再現されるということは、Bの出力は、Aから入力されるデータの特色をすでになんらかの形で組み込んでいるということである。つまり、ニュー力データだけで、すでに学習してしまっているのである。これでAからBへのウェイトをまず作る。次にそこで最終的に得た出力を利用して、BCB'というネットワークを作成し、その先のネットワーク出力で、自己学習させるのである。Bの入力と、学習用のB'のデータはまた同じである。もちろんニューロン数も同じである。そうすると、BC間のウェイトがまたCで特徴が凝縮されるように形成される。最終的にこのようにできたAB間のウェイトBC間のウェイトを使って、元のABCDのネットワークを元々の学習用出力で学習させる。この時,CD間のウェイトは、私の場合、ランダムに作成したものにしているが、正解かどうかの確信はない。でも多分正しいだろう。これが、オートエンコーダーである。
少なくとも、MNISTのデータについては、うまく機能している。
-autoを指定すると、元のネットワークトポロジーが、5層でもそれ以上でも、同じようにやってくれる。試してないが、はずである。