TechFULの中の人

triple-four’s blog

はじめての人工知能(バックプロパゲーション編)

こんにちは!TechFULでアルバイトしているあたかです。 今回はニューラルネットワークがどのように学習しているのかを中心に解説します!


バックプロパゲーションとは

バックプロパゲーション(backpropagation)とは、誤差逆伝播法(ごさぎゃくでんぱほう)とも呼ばれるニューラルネットワークを学習させるために使われるアルゴリズムです。
学習させるときには、入力と正解のセットをあらかじめ用意しておきます。この入力値に対してはこの出力値が正しいと定めておきます。 ニューラルネットワークは入力された値に対して重みをかけて足し合わせるということを繰り返します。つまり重みによって出力する値が決定されます。学習するということは重みを上手に調節して期待通りの出力が得られるようにすることです。
バックプロパゲーションというアルゴリズムでは、まずニューラルネットワークから得られる出力と正解との誤差を計算します。誤差は誤差関数によって定義されます。その誤差はそれぞれの重みを変数とする多変数関数としてみることができます。ある重みについてこの誤差を偏微分することで得られる偏微分係数が正ならば減少させ負ならば増加させるように更新していくと、どんどん誤差を小さくしていくことができます。これを勾配降下法といいます。

誤差関数とは

ニューラルネットワークの出力と正解の誤差を定義する関数です。損失関数とも呼ばれます。
誤差の計算の仕方は目的が回帰か分類かによって変わります。
回帰とは入力の傾向から実数値を推測することであり、分類とは入力がどの組み分けに属しているかを判別することです。
回帰の場合は二乗誤差関数を用います。次のような式です。ニューラルネットワークの出力値をy_i正解値をt_iとしています。
$$\displaystyle E = \frac{1}{2}\sum_{i=0}^n (y_i - t_i)^{2}$$
 \frac{1}{2}がかけられていますが、これは微分された時に係数がちょうど1になるようにするためです。
分類の場合交差エントロピー誤差関数を使います。次のような式です。
$$ \displaystyle E = -\sum_{i=0}^n t_i \log y_i $$ 分類問題の時、正解値は一つだけ1でその他が0であるような値をとります。これはone-hotといいます。総和をとっているので複雑そうな式ですがone-hotなので t_{i} = 1のところ以外は誤差に影響しません。自然対数に−1をかけたものなので出力値が0に近いほど急激に誤差が大きくなります。

勾配降下法とは

微分して得られた傾き(勾配)に沿って降りていけば極小値に辿りつきます。 つぎのグラフをご覧ください。縦軸が誤差E、横軸はある重みw_iです。
f:id:sanbaiefforts:20181101091542p:plain
最初A地点にいるとするとAにおける勾配は負です。なので重みが増加する向き(右)に移動すれば誤差Eが減少するとわかります。逆にBにいるとすると勾配は正です。重みが減少する向き(左)に移動すれば誤差Eが減少しますね。
初期位置がAならC、BならDに落ち着くことがわかります。Cはその周辺ではたしかに一番小さい誤差になりますが最小値ではありません。このような値を局所解といいます。Dは本当の最小値であり、これは大域解といいます。重みを更新する時は局所解に陥らように工夫が必要です。

重みの更新式は次のようになるとわかります。
$$ \displaystyle w_{i} \gets w_{i} - \alpha \frac{\partial E}{\partial w_{i}}$$ \alphaは学習率という正の値です。更新の幅の大きさを表します。学習率が大きいと収束しにくいですが、局所解に陥りにくいという利点があります。

勾配の求め方

重みの更新式を手にいれたので、あとは更新を繰り返し適用すればニューラルネットワークを学習させることができます。 では具体的にどう計算すれば良いか解説します。ある程度数学的知識が必要なのでわからないところがあれば適宜調べてみてください。
入力層を第0層、出力層を第 N層としN-1個の中間層を持つニューラルネットワークを考えます。
1 \leqq n \leqq Nを満たす整数 nについて、第n層のi番目のニューロンと第n-1層のj番目のニューロンを結ぶ重みをw_{ij}^{(n)}と表します。(n)は累乗ではなく順番を表すことに注意してください。
n層のi番目の出力をy_{i}^{(n)}とし、第n-1層の出力と重みをかけて足しあわせたものをu_{i}^{(n)}とおくと、 $$ \begin{align} u_{i}^{(n)} &= \sum_{k}y_{k}^{(n-1)}w_{ik}^{(N)} \\ &= y_{0}^{(n-1)}w_{i0}^{(N)} + y_{1}^{(n-1)}w_{i1}^{(N)} + \cdots + y_{k}^{(n-1)}w_{ik}^{(N)}+ \cdots \end{align} $$ 活性化関数をfとおくと、
$$y_{i}^{(n)} = f(u_{i}^{(n)})$$ が成り立ちます。 各層の活性化関数はシグモイド関数とし、誤差関数を二乗誤差関数とします。 出力層において、連鎖律より
$$ \displaystyle \frac{\partial E}{\partial w_{ij}^{(N)}} = \frac{\partial E}{\partial y_{i}^{(N)}} \cdot \frac{\partial y_{i}^{(N)}}{\partial u_{i}^{(N)}} \cdot \frac{\partial u_{i}^{(N)}}{\partial w_{ij}^{(N)}} $$

 \displaystyle \frac{\partial u_i^{(N)}}{\partial w_{ij}^{(N)}} について、

$$ u_i^{(N)} = y_{0}^{(N-1)}w_{i0}^{(N)} + y_1^{(N-1)}w_{i1}^{(N)} + \cdots + y_j^{(N-1)}w_{ij}^{(N)} + \cdots$$

 w_{ij}^{(N)}以外は定数とみなしてよいので、

$$ \displaystyle \frac{\partial u_i^{(N)}}{\partial w_{ij}^{(N)}} = y_j^{(N-1)}$$

\displaystyle \frac{\partial y_{i}^{(N)}}{\partial u_{i}^{(N)}} = f'(u_{i}^{(N)})より、活性化関数fシグモイド関数なので、
$$ \displaystyle \frac{\partial y_{i}^{(N)}}{\partial u_{i}^{(N)}} = y_{i}^{(N)}(1-y_{i}^{(N)})$$
誤差関数は二乗誤差なので、
$$ \displaystyle \frac{\partial E}{\partial y_{i}^{(N)}} = \frac {\partial \frac{1}{2}\sum_{k}(y_{k}^{(N)} - t_{k})^{2}}{\partial y_{i}^{(N)}} = (y_{i}^{(N)} - t_{i})$$

よって、
$$\displaystyle \frac{\partial E}{\partial w_{ij}^{(N)}} = (y_{i}^{(N)} - t_{i}) \cdot y_{i}^{(N)}(1-y_{i}^{(N)}) \cdot y_j^{(N-1)}$$

このように既知の値で出力層における勾配を求めることができます。
つぎに、出力層以外でも勾配が求まることを示します。
まず、第n層におけるk番目のニューロンについて、\deltaを定義します。
$$ \displaystyle \delta_{k}^{(n)} = \frac{\partial E}{\partial u_{k}^{(n)}}$$ このとき、重みの更新式はこの\deltaをもちいて、
$$\displaystyle w_{ij}^{(n)} \gets w_{ij}^{(n)} - \alpha \frac{\partial E}{\partial u_{i}^{(n)}} \cdot \frac{\partial u_{i}^{(n)}}{\partial w_{ij}^{(n)}}$$より

$$ \displaystyle w_{ij}^{(n)} \gets w_{ij}^{(n)} - \alpha \delta _{i}^{(n)} \cdot y_{j}^{(n-1)}$$
と表せます。
ここで、 1 \leqq n \leqq N-1を満たすnについて、
$$ \displaystyle \frac{\partial E}{\partial w_{ij}^{(n)}} = \frac{\partial E}{\partial y_{i}^{(n)}} \cdot \frac{\partial y_{i}^{(n)}}{\partial u_{i}^{(n)}} \cdot \frac{\partial u_{i}^{(n)}}{\partial w_{ij}^{(n)}}$$
Eu_{k}^{(n+1)}(k = 0, 1, 2, \cdots)の関数であり、u_{k}^{(n+1)}はそれぞれ y_{i}^{(n)}の関数なので連鎖律より、
$$ \displaystyle \frac{\partial E}{\partial y_{i}^{(n)}} = \sum_{k}\frac{\partial E}{\partial u_{k}^{(n+1)}} \cdot \frac{\partial u_{k}^{(n+1)}}{\partial y_{i}^{(n)}} $$ よって、
$$ \displaystyle \frac{\partial E}{\partial y_{i}^{(n)}} = \sum_{k}{\delta _{k}^{(n+1)}} \cdot w_{ki}^{(n+1)} $$
両辺に、 \displaystyle \frac{\partial y_{i}^{(n)}}{\partial u_{i}^{(n)}} を掛けると、
$$ \begin{equation}
\displaystyle \frac{\partial E}{\partial u_{i}^{(n)}} = \sum_{k}{\delta _{k}^{(n+1)}} \cdot w_{ki}^{(n+1)}\cdot\frac{\partial y_{i}^{(n)}}{\partial u_{i}^{(n)}}
\end{equation} $$

$$ \begin{equation}
\displaystyle \delta_{i}^{(n)} = \sum_{k}{\delta _{k}^{(n+1)}} \cdot w_{ki}^{(n+1)}\cdot f'(u_{i}^{(n)})
\end{equation} $$

以上より、
{} $$ \displaystyle \delta_{i}^{(n)} = \left\{ \begin{array}{} (y_{i}^{(n)} - t_{i}) \cdot y_{i}^{(n)}(1-y_{i}^{(n)}) & (n = N) \\ \sum_{k}{\delta _{k}^{(n+1)}} \cdot w_{ki}^{(n+1)}\cdot f'(u_{i}^{(n)}) & (n < N) \end{array} \right. $$

が得られます。
この\deltaを出力層から入力層に向かって順々に計算し、以下の更新式を用いることで重みを更新できます。 $$ \begin{equation}
\displaystyle w_{ij}^{(n)} \gets w_{ij}^{(n)} - \alpha \delta _{i}^{(n)} \cdot y_{j}^{(n-1)}
\end{equation} $$