LoginSignup
53
32

More than 5 years have passed since last update.

【機械学習】誤差逆伝播法による速度改善(その2)

Last updated at Posted at 2017-01-30

前回のブログでは、手書き文字データの速度改善を行うにあたって、誤差逆伝播法に触れました。

その中では計算グラフや連鎖率のお話、また加算ノードや乗算ノードでの逆伝播がどのようなオペレーションになるのか確認しました。

今回はその続きで、ニューラルネットワークでの以下の演算ノードが、逆伝播でどのような処理になるのかを確認します。

・シグモイド関数(活性化関数)
・Softmax関数
・交差エントロピー誤差(損失関数)
・Affine変換(行列の内積とバイアスの和)

\def\textlarge#1{%
  {\rm\Large #1}
}
\def\textsmall#1{%
  {\rm\scriptsize #1}
}

シグモイド関数の逆伝播

シグモイド関数は以下のような形の関数でした。

y = \frac{1}{1+e^{-x}}

これを計算グラフで表現してみます。
シグモイド関数自体が、加算、除算、指数計算の複合計算なので、計算ノードが複数組み合わさったものになります。
順伝播は以下のような形です。

sigmoid_graph.png

逆伝播ですが、まずは最後の除算ノードに着目します。
除算は、y=1/x という演算処理なので、偏微分は以下の計算になります。

\frac{\partial y}{\partial x} = -\frac{1}{x^2} = -y^2

その手間の3つめの加算ノードは前回お話ししたとおり、そのまま値を流すだけです。

その次の指数計算「exp」ノードについては、偏微分計算は以下の通りです。

\frac{\partial y}{\partial x} = e^x

つまり、この場合はexp(-x)をかけて逆伝播します。

最後の逆伝播は一番手前の乗算ノードになりますが、前回お話しした通り、
入力ノードをひっくり返して掛ければ良いので、この場合は-1をかけてやれば良いことになります。

整理すると以下のような計算グラフになります。
sigmoid_graph2.png

逆伝播の最後の出力は、以下のように表現を変えることができます。

y^2e^{-x}\frac{\partial E}{\partial y}=y\frac{e^{-x}}{1+e^{-x}}\frac{\partial E}{\partial y}= y(1-y)\frac{\partial E}{\partial y} 

なので、シグモイド関数のノードでは、順伝播で出力された値yに対して、y(1-y)倍した値を
逆伝播で渡してやれば良いことになります。
sigmoid_graph3.png

Softmax関数の逆伝播

Softmax関数はこのような形をしていました。


y_{k}=σ(k)=\frac{e^{x_{k}}}{\sum_{i=0}^9(e^{x_{i}})}

計算グラフは、このような形になります。
softmax_graph5.png

逆伝播については、若干複雑です。
今まで出てきた加算/乗算/除算/指数のノードを組み合わせるとできるわけですが、結果から先に記載すると、インデックスk番目に着目した計算結果は以下の通りです。

y_{k}(\frac{\partial E}{\partial y_{k}}-{\sum_{i=0}^9 y_{i}\frac{\partial E}{\partial y_{i}}})

逆伝播のフローを赤線で記載すると以下のような計算結果になります。
softmax_graph6.png

入出力だけに着目して表現するとSoftmaxノードは以下のような表現になります。
softmax_graph4.png

Softmaxの逆伝播の形は、この後に説明する「交差エントロピー誤差」の逆伝播と組み合わせると、実は非常にスッキリした形になります。
話を進めていきます。

交差エントロピー誤差関数の逆伝播

交差エントロピー誤差の関数はこのような形をしていました。


E=\sum_{n=1}^N(-log(y_{n,t_n}))

この表現は、n番目の入力データをx$\textsmall{n}$とし、それに対する正解データをt$\textsmall{n}$(=0,1,2,...,9)、
そしてその時に出力層からの10個の数値y$\textsmall{n,k}$(k=0,1,2,...9)で定義したときの形でした。

上記はN個のバッチデータを扱う表現ですが、逆伝播を考えるときは、1つの入力データを入力したケースを考えます。
つまり、入力データをx(ベクトル)、 出力データをy(ベクトル)、正解データをt(スカラー)としたときの表現は以下のようになります。


E=-log(y_{t})

ここでの正解データtはスカラー値ですが、正解のインデックスが1で他は0という「one-hot表現」ベクトルを用いてみます。

たとえば、正解が3である場合には、正解データtは以下のようなベクトル値で表現します。


t=(0,0,0,1,0,0,0,0,0,0)

one-hot表現を用いた場合の、交差エントロピー誤差は以下のような表現となります。

E=\sum_{k=0}^9(-t_{k}log(y_{k}))

対数関数の微分は以下の通りです。


\frac{d}{d x} ({log(x)}) = \frac{1}{x}

計算グラフは以下のようなフローになります。
cross-entropy-error_graph3.png

つまり、インデックスkでの逆伝播の出力は以下の通りです。


-\frac{t_{k}}{y_{k}}

「交差エントロピー誤差」ノードという括りで見たときには、インデックスkの入出力は以下のような表現になります。
cross-entropy-error_graph2.png

「Softmaxノード」と「交差エントロピー誤差ノード」の逆伝播結合

上記で計算した、「Softmaxノード」と「交差エントロピー誤差ノード」の逆伝播を結合してみます。

つまり、計算としては「Softmaxノード」の逆伝播の以下の結果に対して、

y_{k}(\frac{\partial E}{\partial y_{k}}-{\sum_{i=0}^9 y_{i}\frac{\partial E}{\partial y_{i}}})

これを以下の置換を行うことで計算できます。

\frac{\partial E}{\partial y_{k}} → -(\frac{t_{k}}{y_{k}})\frac{\partial E}{\partial y_{k}}\\
\frac{\partial E}{\partial y_{i}} → -(\frac{t_{i}}{y_{i}})\frac{\partial E}{\partial y_{i}}

つまり、「交差エントロピー誤差ノード」の逆伝播の出力を、「Softmaxノード」の入力値に与えてやります。

あと、one-hot表現している正解データtについては、k番目の要素が1で他は
0であることを注意して、計算してみると以下のようになります。

y_{k}\bigl((-\frac{t_{k}}{y_{k}})\frac{\partial E}{\partial y_{k}}-{\sum_{i=0}^9 y_{i}(-\frac{t_{i}}{y_{i}})\frac{\partial E}{\partial y_{i}}}\bigl) \\
=-t_{k}\frac{\partial E}{\partial y_{k}}+y_{k}\sum_{i=0}^9 t_{i}\frac{\partial E}{\partial y_{i}} \\
=-t_{k}\frac{\partial E}{\partial y_{k}}+y_{k}\frac{\partial E}{\partial y_{k}} \\
=(y_{k}-t_{k})\frac{\partial E}{\partial y_{k}}

上記の結果のとおり、「Softmaxノード」と「交差エントロピー誤差ノード」を結合した場合の、逆伝播は(y$\textsmall{k}$-t$\textsmall{k}$)倍して渡してやるだけという非常にシンプルな結果になりました。

実は、このような逆伝播の結果がシンプルな形になるように、Softmax関数、交差エントロピー誤差関数は設計されています。

プログラムを組む際のアルゴリズムも、この2つを1つのノードとして扱った方がシンプルになります。

ノードのイメージはこのような形になります。
cross-entropy-error_graph5.png

Affine変換の逆伝播

最後にAffine変換(行列の内積とバイアスの和)のノードの逆伝播を紹介します。

入力層をX、重み付けパラメータをW、バイアスをBとしたとき、出力Yは以下のような
演算であることを以前のブログで説明いたしました。

Y=X・W+B

上記のような行列の内積と和から成る演算がAffine変換ですが、これを計算グラフで表すと以下のようになります。
affine_graph.png

内積計算は「dot」ノードで表現しています。

入力層X、重み付けパラメータWに対応する逆伝播の計算ですが、計算の詳細は割愛しますが、
結果は以下のような形となります。

\frac{\partial E}{\partial X} = \frac{\partial E}{\partial Y}・W^T \\
\frac{\partial E}{\partial W} = X^T・\frac{\partial E}{\partial Y}

形としてはこちらも非常にシンプルな演算式となっています。

XとWの右上の「T」は転置行列であることを意味しています。
また、ここで∂E/∂X、∂E/∂W、∂E/∂Yなどは要素での偏微分の行列を表しています。
たとえば、∂E/∂Xについては以下のような形の勾配ベクトルになります。

\frac{\partial E}{\partial X}=(\frac{\partial E}{\partial X_{0}},\frac{\partial E}{\partial X_{1}},...)

逆伝播を加筆した計算グラフは以下の通りです。
affine_graph2.png


前回と今回のブログで、計算グラフという考えかたを導入して、
ニューラルネットワークの入力層から損失関数計算までの
各フェーズでの逆伝播を確認しました。

この議論の最初に、アルゴリズムの速度改善のためには、損失関数Eの最小値を、如何に早く計算するかが肝になってとお話ししましたが、
実は、損失関数として導入している「交差エントロピー誤差」自体が、
逆伝播で最小値を早く計算するために設計されています。

また、各計算ノードでの逆伝播はシンプルな局所計算で実現でき、
それらを組み合わせることで、速度改善につながるところも垣間見えます。


参考文献:『ゼロから作るDeep Learning』

53
32
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
32