Gauche:バックプロパゲーション
- Gauche を使って、バックプロパゲーションによる学習を行ってみました。
ソース一式は、以下に置いてあります。
https://github.com/Hamayama/backprop-test
- 出典は以下になります。
「はじめてのディープラーニング」 我妻幸長 SB Creative 2018
(「5.9 バックプロパゲーションの実装 -回帰-」)
- 内容は、バックプロパゲーションによって、
ニューラルネットワークの重みとバイアスのパラメータを更新して、
sin 関数の学習を行うものです。
- 最終結果をグラフにしたものを、以下のページに置いています。
https://drive.google.com/open?id=1CyYuqu66ZHT9qySN0OarFxHbO2bNZG_wiDMcQkbHaXo (V1)
https://drive.google.com/open?id=181qX5J1A5pdydF6f8dpxpxmgWrc2_YRPhEAxmr0oge8 (V2)
(シート名がファイル名の番号に対応しています)
- いくつか改造したものも作ってみました。
入力の正規化を止めたり、活性化関数をシグモイド関数から ReLU 関数に変えたりしてみました。
なかなか誤差を減らすのは難しいようです。
- また、何度か実行していると、うまく学習できないことがありました。
(最終結果が完全にランダムになる)
入力をシャッフルしてから計算をするので、確率的なものかと思いますが、
よく分かりませんでした (Python版でも発生します) 。
- 実装については、gauche.array を使用しています。
f64arraysub.scm という補助モジュールを作成して、できる範囲で高速化しました。
また、eigenmat モジュール ( https://github.com/Hamayama/eigenmat ) が存在すれば、
使用します。
- 実行時間は、自分の PC だと、eigenmat なしで 190 sec 程度、
eigenmat ありで 37 sec 程度でした。
ただ、本に載っていた Anaconda + Jupyter Notebook の環境だと 10 sec 程度なので、
まだ何かうまい方法がありそうですが。。。
- その後、少し調整して、eigenmat ありで 27 sec になりました。
https://github.com/Hamayama/backprop-test/blob/master/V1/backprop1001.scm
実行時間の 40 % が行列の生成でかかっているので、
破壊的変更に切り換えれば、もう少し速くなりそうです。
hamayama(2019/03/02 15:33:35 UTC)
- その後、破壊的変更版を作成したところ、eigenmat ありで 15 sec になりました。
しかし、プログラムは、だいぶ分かりにくくなってしまいました。
https://github.com/Hamayama/backprop-test/blob/master/V1/backprop1051.scm
数式が複雑になると、途中の結果を保存しておく行列が必要になり、
それをループ内で毎回作成したくないため、事前に作成しておくことになり、
その結果として、ややこしくなっています。
hamayama(2019/03/05 11:39:24 UTC)
- その後、V2 を作成して、本体とパラメータ設定ファイルを分離しました。
古いファイルは、V1 フォルダに移動しました (2019/03/13)。
- その後、Gauche:行列演算モジュール の f2arrmat + eigenmat + blasmat を使用して、
gosh backprop_main.scm backprop1001.scm が 9 sec 程度になりました (2019/03/23)。
hamayama(2019/03/01 15:20:24 UTC)(2019/03/02 15:33:35 UTC)
(2019/03/05 11:39:24 UTC)(2019/03/13 14:24:47 UTC)
(2019/03/22 20:26:18 UTC)