# 誤差逆伝播法（Backpropagation）はなぜ効率的なのか？

## はじめに

Deep Learning では、モデルの性能を向上させるために、損失関数（予測と正解のズレ）を最小化するようにパラメータ（重みやバイアス）を調整します。このパラメータ調整には、損失関数に対する各パラメータの勾配（どれだけパラメータを変化させると損失が変化するかを示す値）が必要です。

この勾配計算には、一般的に**誤差逆伝播法 (Backpropagation)** が用いられます。では、なぜ入力側から出力側へ向かって計算していく**順伝播的な勾配計算**は非効率なのでしょうか？

ここでは、単純な 2 層ニューラルネットワークを例に、その理由と誤差逆伝播法の効率性を解説します。

**例で使用するネットワークと仮定:**

- **ネットワーク:** $x \xrightarrow{w_1} z_h \rightarrow h \xrightarrow{w_2} z_y \rightarrow y \rightarrow L$
  - $x$: 入力, $h$: 隠れ層出力, $y$: 最終出力
  - $z_h = w_1 x$ （簡単のためバイアスは省略）
  - $h = f(z_h)$ （$f$: 隠れ層の活性化関数）
  - $z_y = w_2 h$ （簡単のためバイアスは省略）
  - $y = g(z_y)$ （$g$: 出力層の活性化関数）
  - $L$: 損失関数
- **目標:** 損失 $L$ に関するパラメータ $w_1, w_2$ の勾配 $\frac{\partial L}{\partial w_1}, \frac{\partial L}{\partial w_2}$ を計算する。
- **仮定（簡単のため）:**
  - 活性化関数 $f, g$ は恒等関数 ($f(z)=z, g(z)=z$) とする。つまり $\frac{\partial h}{\partial z_h} = 1, \frac{\partial y}{\partial z_y} = 1$。
  - 損失関数 $L$ は平均二乗誤差 (MSE) の一部 $L = \frac{1}{2}(y - \text{正解})^2$ とする。つまり $\frac{\partial L}{\partial y} = y - \text{正解}$。

## 順伝播的な勾配計算とその非効率性

順伝播的な勾配計算は、入力に近いパラメータから順に、連鎖律（Chain Rule）を用いて勾配を計算していく方法です。

上記の 2 層ネットワークの場合、連鎖律による勾配は以下のようになります。

- $\frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial z_y} \times \frac{\partial z_y}{\partial h} \times \frac{\partial h}{\partial z_h} \times \frac{\partial z_h}{\partial w_1}$
- $\frac{\partial L}{\partial w_2} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial z_y} \times \frac{\partial z_y}{\partial w_2}$

この計算では、$\frac{\partial L}{\partial w_1}$ と $\frac{\partial L}{\partial w_2}$ の両方で、共通の計算部分 $\frac{\partial L}{\partial y} \times \frac{\partial y}{\partial z_y}$ が出現します。

層が増えると、この重複はさらに深刻になります。例えば、4 層のネットワーク $x \xrightarrow{w_1} h_1 \xrightarrow{w_2} h_2 \xrightarrow{w_3} h_3 \xrightarrow{w_4} y \rightarrow L$ を考えると、各パラメータの勾配は以下のようになります。

$\frac{\partial L}{\partial w_1} = (\frac{\partial L}{\partial y} \frac{\partial y}{\partial z_y} \frac{\partial z_y}{\partial h_3} \frac{\partial h_3}{\partial z_{h3}} \frac{\partial z_{h3}}{\partial h_2} \frac{\partial h_2}{\partial z_{h2}} \frac{\partial z_{h2}}{\partial h_1} \frac{\partial h_1}{\partial z_{h1}}) \times \frac{\partial z_{h1}}{\partial w_1}$
$\frac{\partial L}{\partial w_2} = (\frac{\partial L}{\partial y} \frac{\partial y}{\partial z_y} \frac{\partial z_y}{\partial h_3} \frac{\partial h_3}{\partial z_{h3}} \frac{\partial z_{h3}}{\partial h_2} \frac{\partial h_2}{\partial z_{h2}}) \times \frac{\partial z_{h2}}{\partial w_2}$
$\frac{\partial L}{\partial w_3} = (\frac{\partial L}{\partial y} \frac{\partial y}{\partial z_y} \frac{\partial z_y}{\partial h_3} \frac{\partial h_3}{\partial z_{h3}}) \times \frac{\partial z_{h3}}{\partial w_3}$
$\frac{\partial L}{\partial w_4} = (\frac{\partial L}{\partial y} \frac{\partial y}{\partial z_y}) \times \frac{\partial z_y}{\partial w_4}$

（※ $\times$ を省略して並べています）

このように、各パラメータの勾配を順伝播的に計算すると、出力層に近い部分の計算（括弧内の共通部分）がパラメータごとに何度も繰り返し現れ、層が深くなるほど計算量が爆発的に増加してしまいます。これが順伝播的な勾配計算の非効率性です。

## 誤差逆伝播法（Backpropagation）の効率性

誤差逆伝播法は、この計算の重複を避けるために考案されました。出力層から入力層に向かって、**誤差信号 $\delta$** （各層の活性化関数への入力 $z$ に関する最終的な損失 $L$ の勾配 $\frac{\partial L}{\partial z}$）を計算し、それを再利用して各パラメータの勾配を効率的に求めます。

**1. 出力層の誤差信号 $\delta_y$ の計算:**

まず、出力層の活性化関数への入力 $z_y$ に対する損失 $L$ の勾配 $\delta_y = \frac{\partial L}{\partial z_y}$ を計算します。
$\delta_y = \frac{\partial L}{\partial z_y} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial z_y}$
（仮定より $\frac{\partial L}{\partial y} = y - \text{正解}$, $\frac{\partial y}{\partial z_y} = 1$ なので、 $\delta_y = (y - \text{正解}) \times 1 = y - \text{正解}$ となります。）

**2. 出力層のパラメータ $w_2$ の勾配計算:**

計算済みの $\delta_y$ を使って、出力層の重み $w_2$ の勾配 $\frac{\partial L}{\partial w_2}$ を計算します。
$\frac{\partial L}{\partial w_2} = \frac{\partial L}{\partial z_y} \times \frac{\partial z_y}{\partial w_2} = \delta_y \times \frac{\partial (w_2 h)}{\partial w_2} = \delta_y \times h$
（ここで $\frac{\partial L}{\partial z_y}$ の計算結果 $\delta_y$ を再利用しています。）

**3. 隠れ層の誤差信号 $\delta_h$ の計算:**

次に、誤差信号 $\delta_y$ を隠れ層へ逆伝播させ、隠れ層の活性化関数への入力 $z_h$ に対する損失 $L$ の勾配 $\delta_h = \frac{\partial L}{\partial z_h}$ を計算します。
$\delta_h = \frac{\partial L}{\partial z_h} = \frac{\partial L}{\partial z_y} \times \frac{\partial z_y}{\partial h} \times \frac{\partial h}{\partial z_h} = \delta_y \times \frac{\partial (w_2 h)}{\partial h} \times \frac{\partial h}{\partial z_h}$
（仮定より $\frac{\partial h}{\partial z_h} = 1$ なので、 $\delta_h = \delta_y \times w_2 \times 1 = \delta_y w_2$ となります。）
（ここでも $\delta_y$ を再利用しています。）

**4. 隠れ層のパラメータ $w_1$ の勾配計算:**

計算済みの $\delta_h$ を使って、隠れ層の重み $w_1$ の勾配 $\frac{\partial L}{\partial w_1}$ を計算します。
$\frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial z_h} \times \frac{\partial z_h}{\partial w_1} = \delta_h \times \frac{\partial (w_1 x)}{\partial w_1} = \delta_h \times x$
（ここで $\frac{\partial L}{\partial z_h}$ の計算結果 $\delta_h$ を再利用しています。）

このように、誤差逆伝播法では、出力層から順に誤差信号 $\delta$ を計算し、その $\delta$ を次の層の $\delta$ 計算や、その層のパラメータ勾配計算に再利用します。これにより、順伝播的な勾配計算で発生した計算の重複が解消され、効率的に全パラメータの勾配を求めることができます。

## 結論

- **順伝播的な勾配計算** は、各パラメータの勾配を計算する際に、出力に近い部分の計算を何度も繰り返してしまうため、特に層が深いネットワークでは計算量が非常に多くなり非効率です。
- **誤差逆伝播法 (Backpropagation)** は、出力層から逆向きに「誤差信号 $\delta$」（$\frac{\partial L}{\partial z}$）を計算し、その結果を再利用することで、計算の重複を避け、全てのパラメータの勾配を効率的に計算できます。

多くのパラメータを持つ深いニューラルネットワークの学習において、勾配計算の効率は極めて重要です。そのため、現在広く使われている Deep Learning フレームワークでは、誤差逆伝播法が標準的な勾配計算手法として採用されています。