見出し画像

第29話 実装!回帰問題バックプロゲーション ソースコード解説編

前回は、回帰問題のバックプロゲーション実装例ということで、ソースコードとその出力結果を紹介しました。
今回はそのソースコードの詳細を解説していきます。

というのも、いきなり小難しいソースコードの詳細を解説されても読む気がしなくなると思って、先にソースコードと実行結果を示しました。
頂上の見える山登りと見えない山登りだったら、前者の方が良いでしょう?

さて、前回実装ニューラルネットワークは次のようなものでした。

画像2

 入力層:ニューロン数1
 中間層:1層、ニューロン数1(はじめは1で後から変える)
 出力層:ニューロン数1

 中間層の活性化関数:シグモイド関数
 出力層の活性化関数:恒等関数
 損失関数     :二乗和誤差
 最適化アルゴリズム:確率的勾配降下法
 バッチサイズ   :1

今回はこのネットワークを実現するソースコードについて解説します。
各層はクラスとして実装しましたので、それぞれについて説明します。
具体的には次のとおりです。
1. 出力層の実装
2. 中間層の実装
3. バックプロゲーションの実装
4. 全体のコード

それでは学習を始めましょう。
(参考図書「はじめてのディープラーニング」我妻幸長著)

1. 出力層の実装

出力層を4つに分割しました。それぞれについて解説していきます。

名称未設定

① 初期設定(コンストラクタ)
初期設定を行う部分です。
上の層(中間層のニューロン数)をn_upper、出力層のニューロン数をnと定義し、これらを引数にして渡しています。
重みself.wはn_upper×nの行列で、バイアスself.bは要素数nのベクトルにします。
重みとバイアスの初期値はrandom.randnにより正規分布に従う乱数で、
wb_widthはその正規分布の広がり具合を決めるパラメータです。
(重みとバイアスをランダムに設定する理由は後日学習します。)

② 順伝播
順伝播をforwardメソッドと定義します。
入力ベクトルと重み行列の行列積にバイアスベクトルを足し合わせて、これを活性化関数に渡して出力を計算します。
出力層の活性化関数は恒等関数ですので、self.y=uとなります。
逆伝播の演算でもこの時の入力x,出力yを使用するため、self.x,self.yという変数を使っています。

③ 逆伝播
逆伝播をbackwardメソッドと定義します。
正解tを引数として受け取り、deltaを計算します。
deltaは逆伝播のときにネットワークを遡上する変数です。
このdeltaを用いて重みの勾配grad_w、バイアスの勾配grad_b、この層の入力の勾配grad_xを計算します。
delta,grad_w,grad_b,grad_xの計算式は、下表のとおり第24回2項で導出した計算式です。

画像4

④ 重みとバイアスの更新
updateメソッドを定義し、ここで重みとバイアスの更新を行います。
最適化アルゴリズムは確率的勾配降下法ですので、これに従った計算式になっています。(確率的勾配降下法については第25話2項参照)

画像3

中間層の実装

次に中間層を説明します。
出力層とほとんど同じなので違うところを点線で示します。

名称未設定

中間層の活性化関数はシグモイド関数にしたので、順伝播のself.yと逆伝播のdeltaが出力層と変わってきます。

バックプロゲーションの実装

主役のバックプロゲーションによる学習は次のようなコードです。
最初に各層を初期化して学習を始めます。
途中の詳細は注釈の通りです。
最後に重みとバイアスの更新を行います。

名称未設定

全体のコード

これでコアの部分は揃いましたので、他の部分も含めて全体のコードを見ていきましょう。

画像7

画像8

画像9

画像10

名称未設定

これを実行すると次のようなgif画像が保存されます。

画像12

n_minを変えれば中間層のニューロン数が変わるので学習結果も変わります。
例えばn_min=3とすると出力はこのようになります。

画像13

他にもeta(学習係数)やepoch(学習回数)を変えることもできます。
興味のある方はやってみてください。



今回は回帰問題のバックプロゲーションのソースコードを解説しました。
私はせっかちな方なので学習を始めた3ヶ月程前には「なんでもいいから早くソースコードを見せてくれ!」という気持ちで学習を進めていたのですが、順伝播・逆伝播・学習アルゴリズムはたった数行で実装されていて、初めてAIに触れる人がいきなりソースコードを見ても読み解くのは無理だと思いました^^;
AI学習は1日にしてならず、ということですね。

でも3ヶ月くらいかけてコツコツ勉強すれば理解できるレベルには到達することもわかりました。
教科書も半分を消化し、ますます内容の難しいディープな・ニッチな世界に入っていきますが、なんとか楽しみながらやっていこうと思います。

次回は分類問題のバックプロゲーションの実装について学習します。
それではまた(^_^)ノシ

よろしければサポートお願いします!いただいたサポートは書籍代等に活用いたします!