【数式編】(逆伝播)出力層の重みとバイアスを更新する 1-(1)
誤差逆伝播(バックプロパゲーション)
ニューラルネットワークが正しい出力を得るようになるには、重みやバイアスなどのパラメータを調整する必要があります。
誤差逆伝播(バックプロパゲーション)という手法を使うことで、パラメータを調整することができます。
具体的には損失関数を調整したいパラメータで偏微分することで、調整値を求めていきます。
(誤差逆伝播の詳しい説明については他のWebサイトや書籍を参照してください。)
重みの更新式
まずは出力層の1つめのユニット ユニットo11 の重み を調整するための更新式を見ていきましょう。
(※ は学習率)
更新後の重みは、更新前の重みから損失関数の勾配( )に学習率を掛けた値を引くことで求めることができます。
(式の意味をわかりやすくするために ← で表現しています。)
学習率はある種の定数(ハイパーパラメータ)と考えてよいので、 を求めることができれば、重みを更新することができます。
損失関数の偏微分
は損失関数 を で偏微分することで求めることができます。
これは、連鎖率(チェインルール)によって、次の式で求めます。
まずは について見ていきましょう。
損失関数の式を再掲しておきます。
この式を で偏微分します。
左から第1項め、第2項め、第3項めとしてひとつずつ見ていきます。
・第1項めについて
まずは を見ていきます。
なので、
公式 を利用して、
よって、
公式 を利用すると
以上より、
・第2項めについて
次に を見ていきます。
第1項めと同様に、
なので、
よって、
公式 を利用して
は先ほど求めたので、
以上より、
・第3項めについて
最後に を見ていきます。
内容は第2項めとほとんど同じです。
なので、
よって、
公式 を利用して
以上より、
・まとめると…
を求めようとしていて、
とわかったので、
(※ 教師データは one-hot 表現としているため、)
まとめ: の更新式
以上((1)、(2))から、 を調整するための具体的な更新式は以下のようになります。(※ は学習率)
「(そのユニットの出力 - 該当する教師データ) × その重みに関係した入力値」になっていることがわかります。
【数式編】(損失関数)クロスエントロピー誤差
損失関数
前回の最終出力で がわかりました。
これらの値がそれぞれ、教師データの と同じ(か、ひじょうに近い値)であれば、期待した出力といえます。
しかし、重みやバイアスの初期値はいいかげん(ランダム)な値になっているため、初めから期待した出力になるわけではありません。
そこで、損失関数を使い、現時点での出力が期待する出力とどれだけ乖離しているか(誤差)を調べ、出力が期待する値になるように、重みやバイアスを調整していきます。
今回、出力層の活性化関数には を適用しているので、損失関数にはクロスエントロピー誤差(交差エントロピー誤差)を採用します。
教師データ
今回、教師データは one-hot 表現としています。
これは、正解のラベルが 1 でそれ以外は 0 となっているデータです。
例えば、 が正解ラベルの場合、次のようになります。
誤差の計算
具体的に誤差の計算をしてみましょう。
いま、期待する出力として、以下の出力を得たいとします。
つまり、りんごの出力(このニューラルネットワークでは )が最大になるようにしたいとします。
ところが、ニューラルネットワークの最終出力が次のような場合、損失関数の値はどのようになるでしょうか。
(出力層ではソフトマックス関数を適用しているので、出力の総和は 1 になっています。)
では、最終出力が次のようだった場合はどうなるでしょうか。
今回は、りんごの出力が最大になっています。
先ほどと比べて損失関数の値が小さくなっています。
さらに次のような場合はどうでしょうか。
今度はさらにりんごの出力値が大きくなっています。
先ほどと比べてさらに損失関数の値が小さくなっています。
まとめ
このように、正しい(期待する)出力に近ければ近いほど損失関数の値は小さくなっていきます。なので、損失関数の値が小さくなるような出力となるように、重みやバイアスなどのパラメータを調整すれば、正しい判断のできるニューラルネットワークになります。
また、ソフトマックス関数が出力を確率として求めていることを考えると、
2つめの例では 50% (0.5) の確率でりんごだと思っていて、
3つめの例では 90% (0.9) の確率でりんごだと思っている
と考えることができます。
損失関数の値は、ニューラルネットワークがどの程度(自信をもって)正しく判断しているかの目安になります。
【数式編】(順伝播)出力層のユニットの出力を求める
出力値の求め方
出力層のユニットの出力値の求め方は、隠れ層のユニットの出力値の求め方とほぼ同じですが、活性化関数を にしているため、その部分が異なります。
例として ユニットo11 の出力を求めてみます。
を求める
ユニットo11 の出力値 を求めるには、その前に を求める必要があります。
この に を適用すると が求まります。
Softmax(ソフトマックス)関数
の具体的な式は次のようになります。
に比べて複雑な感じの式ですが、やっていることはそれほど難しいことではありません。
問題:
ももが3個、りんごが5個、ぶどうが2個あります。ももの割合はどのくらいですか?
これは次の式で計算できますね。
先ほどの の式と比べると同じような構成になっていることがわかると思います。
さて、これは次のように考えることもできます。
問題:
ももが3個、りんごが5個、ぶどうが2個入っている袋があります。この袋からくだものを1つ取り出すとして、ももを取り出す確率はどのくらいですか?
10個のくだものから3個のももを取り出すので、答えは先ほど同様 ですね。
つまり、ソフトマックス関数では、その出力の確率がどのくらいかを求めているといってもいいでしょう。
そして、確率の総和は 1 になるので、ソフトマックス関数を適用した出力層のすべての出力の和も 1 になります。
具体的には
となります。
ももを取り出す確率 = 、りんごを取り出す確率 = 、ぶどうを取り出す確率 = で、
全部足すと
となることと同じです。
出力を求める式
他のユニットの式もあわせてまとめておきましょう。
ユニットo11
ユニットo12
ユニットo13
【数式編】(順伝播)隠れ層2層めのユニットの出力を求める
出力値の求め方
隠れ層2層めのユニットの出力値の求め方は、1層めのユニットとほぼ同じです。
ただし、入力値は1層めの該当するユニットの出力値()となります。
例として ユニットh21 の出力を求めてみます。
を求める
ユニットh21 の出力値 を求めるには、その前に を求める必要があります。
これに を適用して を求めます。
出力を求める式
他のユニットも同様です。
ユニットh21
ユニットh22
ユニットh23
ユニットh24
【数式編】(順伝播)隠れ層1層めのユニットの出力を求める
出力値の求め方
順伝播でのユニットの出力値は、そのユニットへの入力に対し、それぞれ対応する重みを掛けて足しあげたものにバイアス値を加え、その値に活性化関数を適用することで求めることができます。
図の ユニットh11 を例にとると、入力層の各ユニットからの出力に、それぞれに対応する重みを掛けて足し合わせたものにバイアス値を加えて を求め、 に活性化関数の を適用すると、 を求めることができます。
を求める
ユニットh11 の出力値 を求めるには、その前に を求める必要があります。まずは を求めていきましょう。
各入力値にそれぞれに対応する重みを掛けて足し合わせたものにバイアス値を加えるので、次のような式になります。
ちなみに、バイアス値には入力として常に 1 を掛けていて、実際には となっています。
入力として常に 1 を掛けるのは、行列計算の際の取り扱いが便利だからという理由によるものです。
この に を適用すると が求まります。
ReLU関数
引数を としたときの は
で表され、「引数が0以上のときはその値(引数の値をそのまま)、そうでないときには0を戻す」関数です。
グラフにするとこのような感じになります。
今回は のまま表現することにします。
これで ユニットh11 の出力が求まりました。
出力を求める式
隠れ層1層めの他のユニットについても、重みとバイアスが異なるだけで基本的な計算式は一緒です。
ユニットh11
ユニットh12
ユニットh13
今回扱うニューラルネットワーク
何をやるつもりか
- 数式ベースに順伝播、逆伝播の計算式を見ていく
- その後で、ExcelVBAでニューラルネットワークをフルスクラッチ
- 題材はよくあるアヤメの分類問題
何をやらないつもりか
- 汎用化の追求
- 精度の追求
今回扱うニューラルネットワーク
- 入力:4
- 出力:3
- 隠れ層の活性化関数:ReLU
- 出力層の活性化関数:Softmax
- 損失関数:クロスエントロピー
- 学習方法:教師あり学習
- 教師データ:one-hot 表現
- 扱う問題:分類問題
- データセット:アイリス データセット
こんな感じ。
はじめに
このブログの目的めいたもの
ニューラルネットワークの順伝播、逆伝播についてはじめは数式を中心に、その後でExcelVBAでの実装を目標に進めていきたいと思っています。
ただし、ニューラルネットワークの基本的な内容についてはあちこちで目にされていると思うので、詳しくは触れない方向で…
一応自己紹介めいたもの
なんだかんだでよくいじっている言語は ExcelVBA な人です。
ついおととしくらいまではAIとか機械学習とかは少しは興味がありましたが難しそうだしそれほど首を突っ込んでやろうとは思っていませんでした。Androidアプリを作るためにJavaをやってたのですが、その反動(?)でなにかスクリプト言語がやりたい!と悶々と思っていて、まぁ、いろいろ見ていったところ Python がよさげじゃない?と思って Python をやり始めたら、使っていた書籍に機械学習のサンプルがあったりしてよくわからないままいじったりしているうちにだんだんと興味がわいてきて、そんなとき『ニューラルネットワーク自作入門』を読んで、「これVBAで実装できるんじゃない?」と思って仕組みをよく理解しないまま実装してとりあえずちゃんと動いたのですが、やっぱり仕組みをちゃんと理解したいと思ってそれから数学をやり始めたり、やっぱり統計学をやらなきゃと思って統計学の勉強を始めてみたりして、いったいどこに向かっているのかは自分でもよくわかりませんが、とにかくニューラルネットワークの仕組みをスッキリと理解したい、ちゃんと人に説明できるようになりたい(説明する予定はありませんが…)と思ってきわめてゆっくりですが歩みを進めている、そんな感じです。