CHAPTER 2

逆伝播の仕組み

ニューラルネットワークと深層学習

What this book is about

On the exercises and problems

ニューラルネットワークを用いた手書き文字認識

逆伝播の仕組み

ニューラルネットワークの学習の改善

ニューラルネットワークが任意の関数を表現できることの視覚的証明

ニューラルネットワークを訓練するのはなぜ難しいのか

深層学習

Appendix: 知性のある シンプルな アルゴリズムはあるか?

Acknowledgements

Frequently Asked Questions


Sponsors


Resources

前章では、勾配降下法を用いてニューラルネットワークが重みとバイアスをどのように学習するかを説明しました。 しかし、その説明にはギャップがありました。具体的には、コスト関数の勾配をどのように計算するかを議論していません。これはとても大きなギャップです! 本章では、逆伝播と呼ばれる、コスト関数の勾配を高速に計算するアルゴリズムを説明します。

逆伝播アルゴリズムはもともと1970年代に導入されました。 しかし逆伝播が評価されたのは、 David RumelhartGeoffrey HintonRonald Williams による1986年の著名な論文が登場してからでした。 その論文では、逆伝播を用いると既存の学習方法よりもずっと早く学習できる事をいくつかのニューラルネットワークに対して示し、それまでニューラルネットワークでは解けなかった問題が解ける事を示しました。 今日では、逆伝播はニューラルネットワークを学習させる便利なアルゴリズムです。

本章は他の章に比べて数学的に難解です。 よほど数学に対し熱心でなければ、本章を飛ばして、逆伝播を中身を無視できるブラックボックスとして扱いたくなるかもしれません。 では、なぜ時間をかけて逆伝播の詳細を勉強するのでしょうか?

その理由はもちろん理解のためです。 逆伝播の本質はコスト関数$C$のネットワークの重み$w$(もしくはバイアス$b$)に関する偏微分$\partial C / \partial w$ ($\partial C / \partial b$)です。 偏微分をみると、重みとバイアスを変化させた時のコスト関数の変化の度合いがわかります。 偏微分の式は若干複雑ですが、そこには美しい構造があり、式の各要素には自然で直感的な解釈を与える事ができます。 そうです、逆伝播は単なる高速な学習アルゴリズムではありません。 逆伝播をみることで、重みやバイアスを変化させた時のニューラルネットワーク全体の挙動の変化に関して深い洞察が得られます。 逆伝播を勉強する価値はそこにあるのです。

そうは言うものの、本章をざっと読んだり、読み飛ばして次の章に進んでも大丈夫です。 この本は逆伝播をブラックボックスとして扱っても他の章を理解できるように書いています。 もちろん次章以降で本章の結果を参照する部分はあります。 しかし、その参照部分の議論をすべて追わなくても、主な結論は理解できるはずです。

ウォーミングアップ:ニューラルネットワークの出力の行列を用いた高速な計算

逆伝播を議論する前に、ニューラルネットワークの出力を高速に計算する行列を用いたアルゴリズムでウォーミングアップしましょう。 私達は 前章の最後のあたり で既にこのアルゴリズムを簡単に見ています。 しかしその時はざっと書いていたので、ここで立ち戻って詳しく説明しようと思います。 特にこれまで説明して慣れた文脈で逆伝播で使用する記号に慣れるのに、このウォーミングアップは良い方法です。

ニューラルネットワーク中の重みを曖昧性なく指定する表記方法からまず始めましょう。 $w^l_{jk}$で、$(l-1)$番目の層の$k$番目のニューロンから、$l$番目の層の$j$番目のニューロンへの接続に対する重みを表します。 例えば下図は、2番目の層の4番目のニューロンから、3番目の層の2番目のニューロンへの接続の重みを表します。

この表記方法は最初は面倒で、使いこなすのにある程度の練習が必要かもしれません。 しかし、少し頑張ればこの表記方法は簡単で自然だと感じるようになるはずです。 この表記方法で若干曲者なのが、$j$と$k$の順番です。 $j$を入力ニューロン、$k$を出力ニューロンとする方が理にかなっていると思うかもしれませんが、 実際には逆にしています。 奇妙なこの記述方法の理由は後程説明します。

ニューラルネットワークのバイアスと活性についても似た表記方法を導入します。 具体的には、$b^l_j$で$l$番目の層の$j$番目のニューロンのバイアスを表します。 また、$a^l_j$で$l$番目の層の$j$番目のニューロンの活性を表します。 下図はこれらの表記方法の利用例です。

これらの表記を用いると、$l$番目の層の$j$番目のニューロンの活性$a^l_j$は、$(l-1)$番目の層の活性と以下の式で関係付けられます(式 (4) と前章の周辺の議論を比較してください) \begin{eqnarray} a^{l}_j = \sigma\left( \sum_k w^{l}_{jk} a^{l-1}_k + b^l_j \right). \tag{23}\end{eqnarray} ここで、和は$(l-1)$番目の層の全てのニューロン$k$について足しています。 この式を行列で書き直すため、各層$l$に対し重み行列$w^l$を定義します。 重み行列$w^l$の各要素は$l$番目の層のニューロンを終点とする接続の重みです。 すなわち、$j$行目$k$列目の要素を$w^l_{jk}$とします。 同様に、各層$l$に対し、バイアスベクトル$b^l$を定義します。 おそらく想像できると思いますが、バイアスベクトルの要素は$b^l_j$達で、 $l$番目の層の各ニューロンに対し1つの行列要素が伴います。 最後に、活性ベクトル$a^l$を活性$a^l_j$達で定義します。

(23) を行列形式に書き直すのに必要な最後の要素は、$\sigma$などの関数のベクトル化です。 ベクトル化は既に前章で簡単に見ました。 要点をまとめると、$\sigma$のような関数をベクトル$v$の各要素に適用したいというのがアイデアです。 このような各要素への関数適用には$\sigma(v)$という自然な表記を用います。 つまり、$\sigma(v)$の各要素は$\sigma(v)_j = \sigma(v_j)$です。 例えば$f(x) = x^2$とすると、次のようになります。 \begin{eqnarray} f\left(\left[ \begin{array}{c} 2 \\ 3 \end{array} \right] \right) = \left[ \begin{array}{c} f(2) \\ f(3) \end{array} \right] = \left[ \begin{array}{c} 4 \\ 9 \end{array} \right]. \tag{24}\end{eqnarray} すなわち、ベクトル化した$f$はベクトルの各要素を2乗します。

この表記方法を用いると、式 (23) は次のような美しくコンパクトなベクトル形式で書けます。 \begin{eqnarray} a^{l} = \sigma(w^l a^{l-1}+b^l). \tag{25} \end{eqnarray} この表現を用いると、ある層の活性とその前の層の活性との関係を俯瞰できます。 我々が行っているのは活性に対し重み行列を掛け、バイアスベクトルを足し、最後に$\sigma$関数を適用するだけです。 *ところで、先ほどの$w^l_{jk}$という奇妙な表記を用いる動機はこの式に由来します。 もし、$j$を入力ニューロンに用い、$k$を出力ニューロンに用いたとすると、式 (25) は重み行列をそれの転置行列に置き換えなければなりません。 些細な変更ですが、煩わしい上に「重み行列を掛ける」と簡単に言ったり(もしくは考えたり)できなくなってしまいます。 この見方はこれまでのニューロン単位での見方よりも簡潔で、添字も少なくて済みます。 議論の正確性を失う事なく添字地獄から抜け出せる方法と考えると良いでしょう。 さらに、この表現方法は実用上も有用です。 というのも、多くの行列ライブラリでは高速な行列掛算・ベクトル足し算・関数のベクトル化の実装が提供されているからです。 実際、前章のコード では、ネットワークの挙動の計算にこの表式を暗に利用していました。

$a^l$の計算のために式 (25) を利用する時には、途中で$z^l \equiv w^l a^{l-1}+b^l$を計算しています。 この値は後の議論で有用なので名前をつけておく価値があります。 $z^l$を$l$番目の層に対する重みつき入力と呼ぶことにします。 本章の以降の議論では重みつき入力$z^l$を頻繁に利用します。 (25) をしばしば重み付き入力を用いて$a^l = \sigma(z^l)$とも書きます。 $z^l$の要素は$z^l_j = \sum_k w^l_{jk} a^{l-1}_k+b^l_j$と書ける事にも注意してください。 つまり、$z^l_j$は$l$番目の層の$j$番目のニューロンが持つ活性関数へ与える重みつき入力です。

コスト関数に必要な2つの仮定

逆伝播の目標はニューラルネットワーク中の任意の重み$w$またはバイアス$b$に関するコスト関数$C$の偏微分、すなわち$\partial C / \partial w$と$\partial C / \partial b$の計算です。 逆伝播が機能するには、コスト関数の形について2つの仮定を置く必要があります。 それらの仮定を述べる前に、コスト関数の例を念頭に置くのが良いでしょう。 前章でも出てきた2乗コスト関数(参考:式(6))をここでも考えます。 前章の記法では、2乗コスト関数は以下の様な形をしていました \begin{eqnarray} C = \frac{1}{2n} \sum_x \|y(x)-a^L(x)\|^2. \tag{26}\end{eqnarray} ここで、$n$は訓練例の総数、和は個々の訓練例$x$について足しあわせたもの、$y = y(x)$は対応する目標の出力、$L$はニューラルネットワークの層数、$a^L = a^L(x)$は$x$を入力した時のニューラルネットワークの出力のベクトルです。

では、逆伝播を適用するために、コスト関数$C$に置く仮定はどのようなものでしょうか。 1つ目の仮定はコスト関数は個々の訓練例$x$に対するコスト関数$C_x$の平均 $C = \frac{1}{n} \sum_x C_x$で書かれているという事です。 2乗コスト関数ではこの仮定が成立しています。 それには1つの訓練例に対するコスト関数を$C_x = \frac{1}{2} \|y-a^L \|^2$とすれば良いです。 この仮定はこの本で登場する他のコスト関数でも成立しています。

この仮定が必要となる理由は、逆伝播によって計算できるのは個々の訓練例に対する偏微分$\partial C_x / \partial w$、$\partial C_x / \partial b$だからです。 コスト関数の偏微分$\partial C / \partial w$、$\partial C / \partial b$は全訓練例についての平均を取ることで得られます。 この仮定を念頭に置き、私達は訓練例$x$を1つ固定していると仮定し、コスト$C_x$を添字$x$を除いて$C$と書くことにします。最終的に除いた$x$は元に戻しますが、当面は記法が煩わしいので暗に$x$が書かれていると考えます。

コスト関数に課す2つ目の仮定は、コスト関数はニューラルネットワークの出力の関数で書かれているという仮定です。

例えば、2乗誤差関数はこの要求を満たしています、それは1つの訓練例$x$に対する誤差は以下のように書かれるためです \begin{eqnarray} C = \frac{1}{2} \|y-a^L\|^2 = \frac{1}{2} \sum_j (y_j-a^L_j)^2. \tag{27}\end{eqnarray} もちろんこのコスト関数は目標とする出力$y$にも依存しています。 コスト関数を$y$の関数とみなさない事を不思議に思うかもしれません。 しかし、訓練例$x$を固定する事で、出力$y$も固定している事に注意してください。 つまり、出力$y$は重みやバイアスをどのように変化させた所で変化させられる量ではなく、ニューラルネットが学習するものではありません。 ですので、$C$を出力の活性$a^L$単独の関数とみなし、$y$は関数を定義するための単なるパラメータとみなすのは意味のある問題設定です。

アダマール積 $s \odot t$

逆伝播アルゴリズムは、ベクトルの足し算やベクトルと行列の掛け算など、一般的な代数操作に基づいています。 しかし、その中で1つあまり一般的ではない操作があります。 $s$と$t$が同じ次元のベクトルとした時、$s \odot t$を2つのベクトルの要素ごとの積とします。つまり、$s \odot t$の要素は$(s \odot t)_j = s_j t_j$です。 例えば、 \begin{eqnarray} \left[\begin{array}{c} 1 \\ 2 \end{array}\right] \odot \left[\begin{array}{c} 3 \\ 4\end{array} \right] = \left[ \begin{array}{c} 1 * 3 \\ 2 * 4 \end{array} \right] = \left[ \begin{array}{c} 3 \\ 8 \end{array} \right] \tag{28}\end{eqnarray} です。 この種の要素ごとの積はしばしばアダマール積、もしくはシューア積と呼ばれます。 私達はアダマール積と呼ぶことにします。 よく出来た行列ライブラリにはアダマール積の高速な実装が用意されており、逆伝播を実装する際に手軽に利用できます。

逆伝播の基礎となる4つの式

逆伝播は重みとバイアスの値を変えた時にコスト関数がどのように変化するかを把握する方法です。 これは究極的には$\partial C / \partial w^l_{jk}$と$\partial C / \partial b^l_j$とを計算する事を意味します。 これらの偏微分を計算する為にまずは中間的な値$\delta^l_j$を導入します。 この値は$l$番目の層の$j$番目のニューロンの誤差と呼びます。 逆伝播の仕組みを見ると$\delta^l_j$を計算手順と$\delta^l_j$を$\partial C/ \partial w^l_{jk}$や$\partial C / \partial b^l_j$と関連づける方法が得られます。

誤差の定義方法を理解する為にニューラルネットワークの中にいる悪魔を想像してみましょう。

悪魔は$l$番目の層の$j$番目のニューロンに座っているとします。 ニューロンに入力が入ってきた時、悪魔はニューロンをいじって、重みつき入力に小さな変更$\Delta z^l_j$を加えます。 従って、ニューロンは$\sigma(z^l_j)$の代わりに、$\sigma(z^l_j+\Delta z^l_j)$を出力します。 この変化はニューラルネット中の後段の層に伝播し、最終的に全体のコスト関数の値は$\frac{\partial C}{\partial z^l_j} \Delta z^l_j$だけ変化します。

ここで、この悪魔は善良な悪魔で、コスト関数を改善する、つまりコストを小さくするような$\Delta z^l_j$を探そうとするとします。 $\frac{\partial C}{\partial z^l_j}$が大きな値(正でも負も良いです)であるとします。 すると、$\frac{\partial C}{\partial z^l_j}$と逆の符号の$\Delta z^l_j$を選ぶことで、この悪魔はコストをかなり改善させられます。 逆に、もし$\frac{\partial C}{\partial z^l_j}$が$0$に近いと悪魔は重みつき入力$z^l_j$を摂動させてもコストをそれほどは改善できません。 悪魔が判断できる範囲においてはニューロンは既に最適に近い状態だと言えます* *もちろんこれが正しいのは$\Delta z^l_j$が小さい場合に限ってです。悪魔は微小な変化しか起こせないと仮定しています。 つまり、ヒューリスティックには、$\frac{\partial C}{\partial z^l_j}$はニューラルネットワークの誤差を測定しているという意味を与える事ができます。

この話を動機として、$l$番目の層の$j$番目のニューロンの誤差$\delta^l_j$を以下のように定義します \begin{eqnarray} \delta^l_j \equiv \frac{\partial C}{\partial z^l_j}. \tag{29}\end{eqnarray}. 慣習に沿って、$\delta^l$で$l$番目の層の誤差からなるベクトルを表します。 逆伝播により、各層での$\delta^l$を計算し、これらを真に興味のある$\partial C / \partial w^l_{jk}$や$\partial C / \partial b^l_j$と関連付けることができます。

悪魔はなぜ重みつき入力$z^l_j$を変えようとするのかを疑問に思うかもしれません。 確かに、出力活性$a^l_j$を変化させ、その結果の$\frac{\partial C}{\partial a^l_j}$を誤差の指標として用いる方が自然かもしれません。 実際そのようにしても、以下の議論は同じように進められます。 しかし、やってみるとわかるのですが、誤差逆伝播の表示が数学的に若干複雑になってしまいます。 ですので、我々は誤差の指標として$\delta^l_j = \frac{\partial C}{\partial z^l_j}$を用いることにします* *MNISTのような分類問題では、誤差(error)という言葉はしばしば誤分類の割合を意味します。 例えばニューラルネットが96.0%の数字を正しく分類できたとしたら、"error"は4.0%です。 もちろん、これは$\delta$ベクトルとは全く異なる意味です。 実際の文脈ではどちらの意味かで迷うことはないでしょう。

攻略計画 逆伝播は4つの基本的な式を基礎とします。 これらを組み合わせると、誤差$\delta^l$とコスト関数の勾配を計算ができます。 以下でその4つの式を挙げていきますが、1点注意があります:これらの式の意味をすぐに消化できると期待しない方が良いでしょう。 そのように期待するとがっかりするかもしれません。 逆伝播は内容が豊富であり、これらの式は相当の時間と忍耐がかけて徐々に理解できていくものです。 幸いなことに、ここで辛抱しておくと後々何度も報われることになります。 この節の議論はスタート地点に過ぎませんが、逆伝播の式を深く理解する過程の中で役に立つもののはずです。

誤差逆伝播の式をより深く理解する方法の概略は以下の通りです。 まず、 これらの式の手短な証明を示します。 この証明を見ればなぜこれらの式が正しいのかを理解しやすくなります。 その後、これらの式を擬似コードで書き直し、 その擬似コードをどのように実装できるかを実際のPythonのコードで示します。 本章の最後の節では、誤差逆伝播の式の意味を直感的な図で示し、ゼロからスタートしてどのように誤差逆伝播を発見するかを見ていきます。 その道中で、我々は何度も4つの基本的な式に立ち戻ります。 理解が深まるにつれ、これらの式が快適で、美しく自然なものとさえ思えるようになるはずです。

出力層での誤差$\delta^L$に関する式: $\delta^L$の各要素は \begin{eqnarray} \delta^L_j = \frac{\partial C}{\partial a^L_j} \sigma'(z^L_j). \tag{BP1}\end{eqnarray} です。 これはとても自然な表式です。右辺の第1項の$\partial C / \partial a^L_j$はコストが$j$番目の出力活性の関数としてどの程度敏感に変化するかの度合いを測っています。 例えば、$C$が出力層の特定のニューロン(例えば$j$番目とします)にそれほど依存していなければ、我々の期待通り$\delta^L_j$は小さくなります。 一方、右辺の第2項の$\sigma'(z^L_j)$は活性関数$\sigma$が$z^L_j$の変化にどの程度敏感に反応するかの度合いを表しています。

ここで注目すべきなのは (BP1) 中の全ての項が簡単に計算できる事です。 ニューラルネットワークの挙動を計算する間に$z^L_j$を計算でき、さらに若干のオーバーヘッドを加えれば$\sigma'(z^L_j)$も計算できます。従って、第2項は計算できます。 第1項に関してですが、$\partial C / \partial a^L_j$の具体的な表式はもちろんコスト関数の形に依存します。しかし、コスト関数が既知ならば$\partial C / \partial a^L_j$を計算するのは難しくありません。 例えば、2乗誤差コスト関数を用いた場合、$C = \frac{1}{2} \sum_j (y_j-a_j)^2$なので、$\partial C / \partial a^L_j = (a_j-y_j)$という簡単に計算できる式が得られます。

(BP1) は$\delta^L$の各要素に対する表式です。 この表式自体は悪くはないのですが、逆伝播で欲しい行列を用いた表式ではありません。 この式を行列として書き直すのは容易で、以下の様に書けます \begin{eqnarray} \delta^L = \nabla_a C \odot \sigma'(z^L). \tag{BP1a}\end{eqnarray} ここで、$\nabla_a C$は偏微分$\partial C / \partial a^L_j$を並べたベクトルです。 $\nabla_a C$は出力活性に対する$C$の変化率とみなせます。 (BP1a)(BP1) は同値である事はすぐにわかります。ですので、以下では両者の式を参照するのに (BP1) を用いる事にします。 例として、2乗誤差コスト関数の例では$\nabla_a C = (a^L-y)$です。 従って行列形式の (BP1) は以下のようになります。 \begin{eqnarray} \delta^L = (a^L-y) \odot \sigma'(z^L). \tag{30}\end{eqnarray} 見ての通り、この表式内の全ての項がベクトル形式の表式となっており、Numpyなどのライブラリで簡単に計算できます。

誤差$\delta^{l}$の次層での誤差$\delta^{l+1}$に関する表式: これは以下の通りです \begin{eqnarray} \delta^l = ((w^{l+1})^T \delta^{l+1}) \odot \sigma'(z^l). \tag{BP2}\end{eqnarray} ここで、$(w^{l+1})^T$は$(l+1)$番目の層の重み行列$w^{l+1}$の転置です。 この式は一見複雑ですが、各要素はきちんとした解釈を持ちます。 $(l+1)$番目の層の誤差$\delta^{l+1}$番目が既知だとします。 重み行列の転置$(w^{l+1})^T$を掛ける操作は、直感的には誤差をネットワークとは逆方向に伝播させていると考える事ができます。 従って、この値は$l$番目の層の出力の誤差を測る指標の一種とみなすことができます。 転置行列を掛けた後、$\sigma'(z^l)$とのアダマール積を取っています。 これにより$l$番目の層の活性関数を通してエラーを更に逆方向に伝播しています。 その結果、$l$番目の層の重みつき入力についての誤差$\delta^l$が得られます。

(BP2)(BP1) と組み合わせる事で、ニューラルネットワークの任意の層$l$での誤差$\delta^l$を計算できます。 まず、$\delta^L$を式 (BP1) で計算します。 次に、式 (BP2) を適用して$\delta^{L-1}$を計算します。 その後、再び (BP2) を適用して、$\delta^{L-2}$を計算します。以下これを繰り返してニューラルネットワークを逆向きに辿る事ができます。

任意のバイアスに関するコストの変化率の式: 具体的には以下の通りです \begin{eqnarray} \frac{\partial C}{\partial b^l_j} = \delta^l_j. \tag{BP3}\end{eqnarray} すなわち、誤差$\delta^l_j$はコスト関数の変化率$\partial C / \partial b^l_j$と完全に同一です。 (BP1)(BP2) からこの値の計算方法は既にわかっているので、この事実はは好都合です。 (BP3) を簡潔に \begin{eqnarray} \frac{\partial C}{\partial b} = \delta \tag{31}\end{eqnarray} と書くことができます。ここで、$\delta$の各成分は同じニューロンのバイアス$b$で評価した値と解釈します。

任意の重みについてのコストの変化率: 具体的には以下の通りです。 \begin{eqnarray} \frac{\partial C}{\partial w^l_{jk}} = a^{l-1}_k \delta^l_j. \tag{BP4}\end{eqnarray} この式を見ると、偏微分$\partial C / \partial w^l_{jk}$を計算方法が既知の$\delta^l$と$a^{l-1}$を用いて計算できることがわかります。 この式はもう少し添字の軽い式で \begin{eqnarray} \frac{\partial C}{\partial w} = a_{\rm in} \delta_{\rm out}, \tag{32}\end{eqnarray} と書き直せます。ここで、$a_{\rm in}$は重み$w$を持つ枝に対する入力ニューロンの活性で、$\delta_{\rm out}$は同じ枝に対する出力ニューロンの持つ誤差です。 重み$w$とそれに接続する2つのニューロンだけに焦点を絞ると、この式は以下のように見ることができます:

(32) から$a_{\rm in}$が小さい($a_{\rm in} \approx 0$)時には、勾配$\partial C / \partial w$も小さくなる傾向があるという結論が得られます。 このような状態を重みの学習が遅いと表現します。その意味は、勾配降下法を行っている間、値が大きく変化しないという事です。 同じ事の言い換えですが、式 (BP4) の帰結の1つとして、活性の低いニューロンから入力を受けとる重みは学習が遅いとわかります。

(BP1) - (BP4) からわかる事は他にもあります。 出力層から見てみましょう。 (BP1) 内の$\sigma'(z^L_j)$の項に注目します。 前章のシグモイド関数のグラフを思い出すと、$\sigma(z^L_j)$が$0$か$1$に近づくとき関数$\sigma$はとても平坦になっていました。 これは$\sigma'(z^L_j) \approx 0$の状態です。 従って、出力ニューロンの活性が低かったり($\approx 0$)、高かったり($\approx 1$)すると、最終層の学習は遅い事がわかります。 このような状況を、出力ニューロンは飽和し、重みの学習が終了している(もしくは重みの学習が遅い)と表現するのが一般的です。 同様の事は出力ニューロンのバイアスに対しても成立します。

出力層より前の層でも似た考察ができます。特に (BP2) 内の$\sigma'(z^l)$の項に注目します。 この式は、ニューロンが飽和状態だと$\delta^l_j$は小さくなる傾向がある事を意味します。また、さらに飽和状態のニューロンに入力される重みの学習も遅くなることを意味します*。 *$(w^{l+1})^T \delta^{l+1}$が十分大きく、$\sigma'(z^l_j)$が小さくてもその埋め合わせができるならば、この推論は成り立ちません。ここでは一般的な傾向について述べています。

まとめると、入力ニューロンが低活性状態であるか、出力ニューロンが飽和状態(低活性もしくは高活性状態)の時には、重みの学習が遅いという事がわかりました。

これらの知見はどれも極端に驚くべき事ではありません。 しかし、これらの考察を通じてニューラルネットワークの学習過程に関するメンタルモデルの精緻にできます。 さらに、以上の考察を逆向きに利用する事ができます。 これら4つの基本方程式は任意の活性化関数について成立します (後述のように、証明に関数$\sigma$の特別な性質を用いていないからです)。 従って、これらの式を利用して好きな学習特性を持つ活性化関数を設計する事が可能です。 アイデアを示すために例を挙げると、例えば(シグモイドではない)活性化関数$\sigma$として$\sigma'$が常に正で、$0$に漸近しないものを選んだとします。 すると、通常のシグモイド関数を用いたニューロンが飽和した際に起こってしまう学習の減速を防ぐ事が可能です。 この本の後ろでは、この種の修正を活性化関数に対して施します。 (BP1) - (BP4) の4つの式を覚えておくと、なぜこのような修正を行うのか、修正でどのような影響が起こるかを説明するのに役立ちます。

問題