隠れ層の活性化関数が多変数の場合の誤差逆伝播

本記事は、機械学習の数理 Advent Calendar 2019の12/6の記事です。
間違い等ありましたらコメント欄にて指摘していただけるとありがたいです。

---

活性化関数は一変数を引数に取るものとして定義することが多いですが、例えばsoftmax関数など一変数関数でない活性化関数も存在します。
その意味でsoftmax関数が活性化関数の場合には誤差逆伝播の計算に特別の注意が必要なのですが、あまりそこが言及されることは多くないように見受けられます。
特にsoftmax関数が最終層に用いられる場合の記事は多くあるのですが、隠れ層に用いられる場合の記事はほとんど存在しません。

そこで、本記事では、一般に多変数を引数に取るとした場合に誤差逆伝播の表式がどのようになるのかを確認し、softmax関数を活性化関数とする場合の誤差逆伝播の表式を計算します。

誤差逆伝播法の詳細な説明は[誤差逆伝播法のノート](https://qiita.com/Ugo-Nama/items/04814a13c9ea84978a4c)などなどをご参照ください。

# Notation

L層の多層パーセプトロンを考えます。
$l=0,1,\cdots ,L$層目の出力を$\mathbf{y}^{(l)}$で表し、その$i$番目のセルの値を$y_i^{(l)}$により表します。$\mathbf{y}^{(0)}$は入力を表します。

$(l+1)$層目の出力の計算は$l$層目の出力の線形な足し合わせを活性化関数により処理することで得られます。具体的には、
$$
\begin{aligned}
v_{j}^{(l+1)} =& \sum_{i} w_{ij}^{(l)} y_i^{(l)} \cr
y_{j}^{(l+1)} =& \phi_j \left( \mathbf{v}^{(l+1)} \right)
\end{aligned}
$$
により$\mathbf{y}^{(l+1)}$を計算します。
損失関数$E$は最終層の出力$\mathbf{y}^{(L)}$の関数$E(\mathbf{y}^{(L)})$です。

誤差逆伝播は$w_{ij}^{(l)}$の微小変化の損失関数$E$への寄与$
\frac{\partial E}{\partial w_{ij}^{(l)}}
$を計算する手法で、効率よく計算するために、$
\boldsymbol{\delta}^{(l)} = \frac{\partial E}{\partial \mathbf{v}^{(l)}}
$を$l = L, L-1, \cdots , 1$と伝播させながら、順々に勾配を計算します。
そのため誤差逆伝播を計算する際に必要になるのは、$\frac{\partial E}{\partial w_{ij}^{(l)}}, \boldsymbol{\delta}^{(l)}$を、一つ上の層の$\delta$、すなわち$\boldsymbol{\delta}^{(l+1)}$の関数として表すことになります。


# 誤差逆伝播の計算（活性化関数が一変数）

活性化関数が一変数で、$j$番目のセルの出力が$v_{j}^{(l)}$のみに依存する場合、すなわち
$$
y_j^{(l)} = \phi_j (\mathbf{v}^{(l)}) = \phi_j (v_j^{(l)})
$$
の場合を考えます。このとき、$\frac{\partial E}{\partial w_{ij}^{(l)}}, \boldsymbol{\delta}^{(l)}$は
$$
\begin{aligned}
\frac{\partial E}{\partial w_{ij}^{(l)}} =& \frac{\partial E}{\partial v_j^{(l+1)}} \frac{\partial v_j^{(l+1)}}{\partial w_{ij}^{(l)}} \cr
=& \delta_j^{(l+1)} y_i^{(l)} \cr
&\cr
&\cr
\delta_i^{(l)} =& \frac{\partial E}{\partial v_i^{(l)}} \cr
=& \sum_{j} \frac{\partial y_i^{(l)}}{\partial v_i^{(l)}}
\frac{\partial v_j^{(l+1)}}{\partial y_i^{(l)}}
\frac{\partial E}{\partial v_j^{(l+1)}} \cr
=& \phi_i' (v_i^{(l)}) \sum_j w_{ij}^{(l)} \delta_j^{(l+1)}
\end{aligned}
$$
により得られます。

形式としてはここまでで十分なのですが、[誤差逆伝播法のノート](https://qiita.com/Ugo-Nama/items/04814a13c9ea84978a4c)と同じ例で具体的に確認しておきます。

損失関数と活性化関数が
$$
\begin{align}
E =& - \sum_{i} \left( t_i \log y_i^{(L)} + (1 - t_i) \log (1 - y_i^{(L)} ) \right) \cr
\phi_i (v_i^{(l)}) =& \frac{1}{1 + e^{-v_i^{(l)}}}
\end{align}
$$
の場合を考えます。
$\mathbf{t}$はトレーニングデータで、最終層の出力と同じ次元の定数ベクトルです。

計算しなければならないのは、$\boldsymbol{\delta}^{(L)}$と、伝播に際して必要になる$\phi_i ' (v_i^{(l)})$です。

あとで使うことになるので、$\phi_i ' (v_i^{(l)})$について先に計算すると、
$$
\begin{align}
\phi_i '(v_i^{(l)}) =& - \frac{(1 - e^{-v_i^{(l)}})'}{(1 - e^{-v_i^{(l)}})^2} \cr
=& - \frac{e^{-v_i^{(l)}}}{(1 - e^{-v_i^{(l)}})^2} \cr
=& \frac{1}{1 - e^{-v_i^{(l)}}} \left( \frac{-e^{-v_i^{(l)}}}{1 - e^{-v_i^{(l)}}} \right) \cr
=& \frac{1}{1 - e^{-v_i^{(l)}}} \left( 1 - \frac{1}{1 - e^{-v_i^{(l)}}} \right) \cr
=& \phi (v_i^{(l)}) (1-\phi(v_i^{(l)}))\cr
=& y_i^{(l)} (1 - y_i^{(l)})
\end{align}
$$
となります。また、$\boldsymbol{\delta}^{(L)}$は、
$$
\begin{align}
\delta_i^{(L)} =& \frac{\partial y_i^{(L)}}{\partial v_i^{(L)}} 
\frac{\partial E}{\partial y_i^{(L)}} \cr
=& - \phi' (v_i^{(L)}) \left( \frac{t_i}{y_i^{(L)}} - \frac{1 - t_i}{1 - y_i^{(L)}} \right) \cr
=& - y_i^{(L)} (1 - y_i^{(L)}) \frac{t_i - y_i^{(L)}}{y_i^{(L)} (1 - y_i^{(L)})} \cr
=& y_i^{(L)} - t_i
\end{align}
$$
となります。

したがって、この例では、

---

**step1**
順伝播の計算を行って、$\mathbf{y}^{(l)}, \mathbf{v}^{(l)}$を計算する。

**step2**
最終層の出力$\mathbf{y}^{(L)}$から$\boldsymbol{\delta}^{(L)} = \mathbf{y}^{(L)} - \mathbf{t}$を計算する。

**step3**
$$
\begin{align}
\frac{\partial E}{\partial w_{ij}^{(l)}} =& \delta_j^{(l+1)} y_i^{(l)} \cr
\delta_i^{(l)} =& y_i^{(l)} (1 - y_i^{(l)}) \sum_{j} w_{ij}^{(l)} \delta_j^{(l+1)}
\end{align}
$$
により、$l=L-1, L-2, \cdots , 0$まで逐次的に計算

---

とすることにより、全ての$\frac{\partial E}{\partial w_{ij}^{(l)}}$を効率よく計算できます。

# 誤差逆伝播の計算（活性化関数が多変数）

ここからが本題で、$\phi_i$が多変数関数の場合を考えます。
といっても、実は変わるところはあまり多くなく、特に$\frac{\partial E}{\partial w_{ij}^{(l)}} = \delta_j^{(l+1)} y_i^{(l)}$の部分は変化しません。
問題となるのは$\delta$の伝播の部分で、活性化関数が多変数のため$v_i^{(l)}$が$y_{i}^{(l)}$のみでなく$y_{j(\neq i)}^{(l)}$の変化にも寄与します。
これを頭に入れて式変形していくと、
$$
\begin{aligned}
\delta_i^{(l)} =& \frac{\partial E}{\partial v_i^{(l)}} \cr
=& \sum_{j, k} \frac{\partial y_j^{(l)}}{\partial v_i^{(l)}}
\frac{\partial v_k^{(l+1)}}{\partial y_j^{(l)}}
\frac{\partial E}{\partial v_k^{(l+1)}} \cr
=&  \sum_{j,k} \frac{\partial \phi_j (\mathbf{v}^{(l)})}{\partial v_i^{(l)}} w_{jk}^{(l)} \delta_k^{(l+1)}
\end{aligned}
$$
と、$\phi '$が$\phi$の偏導関数の和に置き換えられた形式になることが分かります。
また、一変数関数では
$$
\begin{align}
\frac{\partial \phi_j (\mathbf{v}^{(l)})}{\partial v_i^{(l)}} = 
\phi_i ' (v_i^{(l)}) \delta_{ij}
\end{align}
$$
（紛らわしいですが、この$\delta$はクロネッカーデルタです）となることを用いて
$$
\begin{aligned}
\delta_i^{(l)} =& \sum_{j,k} \phi_i ' (v_i^{(l)}) \delta_{ij} w_{jk}^{(l)} \delta_k^{(l+1)} \cr
=& \sum_{k} \phi_i ' (v_i^{(l)}) w_{ik}^{(l)} \delta_k^{(l+1)} \cr
=& \phi_i ' (v_i^{(l)}) \sum_{j} w_{ij}^{(l)} \delta_j^{(l+1)}
\end{aligned}
$$
とできるため、多変数関数の場合が一変数関数の場合の一般化になっていることが確認できます。

多変数関数の場合にも具体的な例で確認しておきます。
何度も参照して申し訳ありませんが、同じく例は[誤差逆伝播法のノート](https://qiita.com/Ugo-Nama/items/04814a13c9ea84978a4c)から、
$$
\begin{align}
E =& - \sum_{i} t_i \log y_i^{(L)} \cr
\phi_i (\mathbf{v}^{(l)}) =&  \frac{e^{v_i^{(l)}}}{\sum_j e^{v_j^{(l)}}}
\end{align}
$$
の場合を考えます。
softmax関数を用いる場合、トレーニングデータ$\mathbf{t}$は確率分布であることが多く（$\sum_i y_i^{(l)} = 1$が保証されているため）、ここでも$\sum_i t_i = 1$を仮定しておきます。

$\phi_i$の偏導関数が必要だったので、まず、$i\neq j$の場合について$\frac{\partial \phi_j (\mathbf{v}^{(l)})}{\partial v_i^{(l)}}$を求めることにすると、
$$
\begin{align}
\frac{\partial \phi_j (\mathbf{v}^{(l)})}{\partial v_i^{(l)}} =&
\frac{\partial \phi_j (\mathbf{v}^{(l)})}{\partial e^{v_i^{(l)}}}
\frac{\partial e^{v_i^{(l)}}}{\partial v_i^{(l)}}\cr
=& - \frac{e^{v_j^{(l)}} e^{v_i^{(l)}}}{(\sum_k e^{v_k^{(l)}})^2}\cr
=& - \phi_i (\mathbf{v}^{(l)}) \phi_j (\mathbf{v}^{(l)})\cr
=& - y_i^{(l)} y_j^{(l)}
\end{align}
$$
となり、$i=j$のときには、
$$
\begin{align}
\frac{\partial \phi_i (\mathbf{v}^{(l)})}{\partial v_i^{(l)}} =&
\frac{\partial \phi_i (\mathbf{v}^{(l)})}{\partial e^{v_i^{(l)}}}
\frac{\partial e^{v_i^{(l)}}}{\partial v_i^{(l)}}\cr
=& \frac{( \sum_k e^{v_k^{(l)}} - e^{v_i^{(l)}} ) e^{v_i^{(l)}}}{(\sum_j e^{v_j^{(l)}})^2}\cr
=& \phi_i (\mathbf{v}^{(l)}) (1 - \phi_i (\mathbf{v}^{(l)}) )\cr
=& y_i^{(l)} (1 - y_i^{(l)})
\end{align}
$$
となります。

最終層の出力による損失関数の微分についても、$\phi_i$が多変数関数であることを考慮して、
$$
\begin{align}
\delta_i^{(L)} =& \sum_j \frac{\partial y_j^{(L)}}{\partial v_i^{(L)}} 
\frac{\partial E}{\partial y_j^{(L)}} \cr
=& -\left(y_i^{(L)} (1 - y_i^{(L)}) \times \frac{t_i}{y_i^{(L)}} - \sum_{j\neq i} y_i^{(L)} y_j^{(L)} \times \frac{t_j}{y_j^{(L)}} \right) \cr
=& -\left(t_i (1 - y_i^{(L)}) - y_i^{(L)} \sum_{j\neq i} t_j \right) \cr
=& -\left(t_i - y_i^{(L)} \sum_{j} t_j \right) \cr
=& y_i^{(L)} - t_i
\end{align}
$$
となります。

誤差伝播法について書かれた記事の多くはここまでで終わっていることが多いですが、中間層の活性化関数にsoftmax関数を用いる場合には、$\boldsymbol{\delta}^{(l)}$の伝播式が一変数の場合と異なっているため、$\boldsymbol{\delta}^{(l)}$をどのように更新しておくかを計算しておく必要があります。（実装上そんなことはねーよというツッコミは置いておいて）
これは、
$$
\begin{align}
\delta_i^{(l)}
=& \sum_{j,k} \frac{\partial \phi_j (\mathbf{v}^{(l)})}{\partial v_i^{(l)}} w_{jk}^{(l)} \delta_k^{(l+1)}\cr
=& \sum_k \left( y_i^{(L)} (1 - y_i^{(L)}) w_{ik}^{(l)} -  \sum_{j\neq i} y_i^{(L)} y_j^{(L)} w_{jk}^{(l)} \right) \delta_k^{(l+1)} \cr
=&  y_i^{(L)} \sum_k \left(w_{ik}^{(l)} - \sum_{j}  y_j^{(L)} w_{jk}^{(l)} \right) \delta_k^{(l+1)}
\end{align}
$$
となります。（もうちょっときれいに変形できるかもしれませんが私はここが限界でした...）

以上を含めて、例えば全ての層の活性化関数がsoftmax関数で、損失関数がCross entropyであるような多層パーセプトロンの誤差逆伝播アルゴリズムを書き下すと次のようになります。

---

**step1**
順伝播の計算を行って、$\mathbf{y}^{(l)}, \mathbf{v}^{(l)}$を計算する。

**step2**
最終層の出力$\mathbf{y}^{(L)}$から$\boldsymbol{\delta}^{(L)} = \mathbf{y}^{(L)} - \mathbf{t}$を計算する。

**step3**
$$
\begin{align}
\frac{\partial E}{\partial w_{ij}^{(l)}} =& \delta_j^{(l+1)} y_i^{(l)} \cr
\delta_i^{(l)} =& y_i^{(L)} \sum_k \left(w_{ik}^{(l)} - \sum_{j}  y_j^{(L)} w_{jk}^{(l)} \right) \delta_k^{(l+1)}
\end{align}
$$
により、$l=L-1, L-2, \cdots , 0$まで逐次的に計算

---

活性化関数がlogistic関数の場合と比べて$\boldsymbol{\delta}^{(l)}$の更新式が異なることがわかります。

# まとめ

隠れ層の活性化関数には一変数関数が用いられる場合が多いですが、多変数関数を用いた場合にも誤差逆伝播を導出することができます。
上の二つの例では偶然にも最終層の出力による損失関数の偏微分係数は同じ形をしていますが、$\boldsymbol{\delta}^{(l)}$を前の層に伝播していく式は異なります。
隠れ層に多変数関数を用いる場合には$\boldsymbol{\delta}^{(l)}$の伝播式に注意する必要があります。