番目のユニットの計算を表したのが式(1)、(2)です。ユニットごとに定義される点に注意してください。層のユニットの番号とします。変数の右肩に付けました。番目のユニットを結んだ層間結合の重みを意味します。活性化関数と呼ばれるもので、ユニットへの総入力にこの関数を適用してユニットの出力を得ます。次の層への入力値として使われることになります。繰り返して計算します。関する計算式が式(3)のようにシンプルになります。本稿で実装するプログラムもこの形式で計算することにします。ユニットへの入力値から出力値を計算する関数です。function)を利用します。function)や式(6)の双曲線正接関数が使われてきましたが、近年はその単純さと最終的な結果の良さにより、正規化線形関数が良く利用されます。本稿の実装も中間層には正規化線形関数を利用しています。出力層の活性化関数は一般に中間層の活性化関数とは違うものを用います。問題の性質により利用する関数は異なるのですが、本稿では多クラス分類を扱う順伝播ニューラルネットワークを解説することにします。式(7)のようなソフトマックス関数と呼ばれる関数が使用されます。番目の層、つまり出力層を表します。番目のクラスが選択される「確率」を計算していると考えます。(7)誤差関数ニューラルネットワークではネットワークの目標値、つまり正解値と実際の出力値との間の関係を誤差関数という関数で表します。誤差関数は通常、損失関数と呼ばれることが多いですが、本稿では参考文献に倣い、誤差関数とさせていただきます。この関数を最小化するのが学習の目標になります。式(8)は多クラス分類における誤差関数です。難しい形をしていますが、後述の誤差逆伝播時の微分計算では単純な計算式に変形できるので便利です。この式の導出については参考文献をご参照下さい。(8)多クラス分類では学習時に入力値と目標値のセットをネットワークに入力します。極小値を探索する方法はいくつか考えられますが、多層ニューラルネットワークでは勾配降下法が用いられることが多いようです。階微分ですので複雑なネットワークになることの多い多層ニューラルネットワークでは勾配降下法の方がよく使われます。入力データをサンプリングします。することでローカルな極小解にトラップされることを防いだり、計算時間を短縮できます。微分したもので、これを勾配と呼びます。学習係数と呼ばれるものです。この値を小さくすると勾配の更新が細かくなり、極小値が発見されやすくなりますが、反面収束のスピードが遅くなります。逆にこの値を大きくすると、学習スピードは速くなりますが、収束しない危険性が増してきます。いくつかの方法が提案されていますが、本稿のプログラムでは学習前に決め打ちで指定することにします。(12)は確率的勾配降下法を用いたパラメータの更新を表します。分割した入力データ群の番号を意味します。確率的にデータを選択して学習することで、学習スピードが速くなり、学習がうまく進むケースが多くなります。理論的な詳細については参考文献をご参照下さい。しています)で微分します。この場合、出力層に近ければ微分はそれほど困難ではないのですが、出力層から離れて入力層に近くなる(深くなる)ほど微分計算は困難になります。層の勾配を求めようとする場合、その層における出力は式(13)で表されますがネットワークが多層になるとこの入れ子の数は非常に多くなり、微分の連鎖法則を何度も適用する必要があります。従ってプログラミングも煩雑なものとなります。バイアスのベクトルとしています。(13)勾配計算の困難さを緩和するために、多層ニューラルネットワークにおける勾配の計算には誤差逆伝播法を用います。考え方は、出力層から入力層に向けて、前後の層の値を利用しながら勾配を計算していくものです。出力層の勾配をまず求めて、それをもとに一つ前の層の勾配を計算し、さらに前の勾配を計算するといった連鎖的な計算を行います。影響をあたえることから連鎖法則により式(14)と展開できます。全てに影響しており、かつ他には影響していないことにより、連鎖法則によって式(15)のように展開できます。(15)ここで式(16)のようにデルタを定義します。(17)式(16)、(17)により、式(15)は式(18)のように表せます。項は式(19)の関係により、式(20)と表せます。よる微分は式(21)で表すことができます。(21)また、出力層のデルタについては式(22)で表せます。対する微分を合計した式(23)を勾配としてパラメータの更新を行います。したがって、式(22)のデルタは式(25)のようになります。この部分の詳細な導出は参考文献をご参照下さい。等しいことを利用すると、式(25)は式(27)で表すことができます。出力層のデルタはユニットの出力値と目標値との差にまで簡便化されることになります。後はこの値からスタートして誤差逆伝播法により任意の層のユニットにおけるデルタを計算すれば良くなります。層のユニット分加算すれば誤差逆伝播の計算ができることになります。これにより、任意の層のデルタを求めることができますので、式(14)から任意の重みを更新できます。入力データはそのままの値を使うより、正規化という処理を施す方が学習がうまく行くことが多いようです。本稿で扱うプログラムも、内部でデータの正規化処理を行っています。式(28)で平均値を計算し、式(29)で標準偏差を計算します。次に式(30)でデータの値から平均値を引いた値を標準偏差で割る形で正規化処理を行っています。本稿では事前学習を使いません。従って、重みの初期値については何らかの値を与える必要があります。この場合、全ての重みに一定の値を与えるとうまく学習できません。従って乱数を与えることになりますが、この場合でも正規乱数を与える方が良い結果が出ます。標準で正規乱数を生成するライブラリがありませんので、独自に実装する必要があります。今回は実装が簡単なボックス・ミュラー法を使うことにします。ボックス・ミュラー法による計算は式(31)または(32)で与えられます。