逆伝播の数学的本質

この章では、2層ニューラルネットワークの逆伝播の全過程を手計算します。

逆伝播 = 計算グラフ上のチェーン則の体系的な適用です。


概念解説

計算グラフ:順伝播と逆伝播

シンプルな2層ネットワーク:入力 x → 隠れ層(ReLU)→ 出力 → MSE損失。

x
z₁=w₁x+b₁
a₁=ReLU(z₁)
z₂=w₂a₁+b₂
ŷ
L=(ŷ-y)²

順伝播は左から右へ出力を計算します。逆伝播は右から左へ各パラメータの損失に対する勾配を計算します。

完全な例を手計算する

x=2、y=4(真のラベル)とし、パラメータは w₁=0.5、b₁=0、w₂=1、b₂=0 とします。

順伝播

ステップ計算值
z₁ = w₁x + b₁0.5×2 + 01.0
a₁ = ReLU(z₁)max(0, 1.0)1.0
ŷ = w₂a₁ + b₂1×1.0 + 01.0
L = (ŷ - y)²(1-4)²9.0

逆伝播(チェーン則)

ŷ に対する損失の勾配:\( \frac{\partial L}{\partial \hat{y}} = 2(\hat{y}-y) = 2(1-4) = -6 \)

w₂ に対する ŷ の勾配 → w₂ に対する L:\( \frac{\partial \hat{y}}{\partial w_2} = a_1 = 1.0 \),\( \frac{\partial L}{\partial w_2} = (-6) \times 1.0 = -6 \)

a₁ に対する L の勾配(さらに前へ伝播):\( \frac{\partial L}{\partial a_1} = \frac{\partial L}{\partial \hat{y}} \cdot w_2 = -6 \times 1 = -6 \)

ReLU を通過:\( \frac{\partial a_1}{\partial z_1} = 1 \)(z₁=1>0 のため)、\( \frac{\partial L}{\partial z_1} = -6 \)

w₁ に対する L:\( \frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial z_1} \cdot x = -6 \times 2 = -12 \)

勾配をまとめて更新

パラメータ勾配更新 (lr=0.1)
w₁-120.5 + 1.2 = 1.7
b₁-60 + 0.6 = 0.6
w₂-61 + 0.6 = 1.6
b₂-60 + 0.6 = 0.6

勾配がすべて負である——現在の予測が小さすぎる(1 < 4)ことを示しており、すべてのパラメータを大きくする必要があります。

w₁ の勾配(-12)は w₂(-6)より大きい:w₁ は損失からより遠く、チェーン伝播の経路が長く、さらに x=2 が掛けられているためです。


Python での検証

実例

import torch

x = torch.tensor([2.0])
y = torch.tensor([4.0])
w1 = torch.tensor([0.5], requires_grad=True)
b1 = torch.tensor([0.0], requires_grad=True)
w2 = torch.tensor([1.0], requires_grad=True)
b2 = torch.tensor([0.0], requires_grad=True)

# 順伝播
a1 = torch.relu(w1 * x + b1)
y_pred = w2 * a1 + b2
loss = (y_pred - y) ** 2
loss.backward()

print("=== サンプル PyTorch 検証 ===")
print(f"∂L/∂w1 = {w1.grad.item():.1f} (手計算: -12)")
print(f"∂L/∂b1 = {b1.grad.item():.1f} (手計算: -6)")
print(f"∂L/∂w2 = {w2.grad.item():.1f} (手計算: -6)")
print(f"∂L/∂b2 = {b2.grad.item():.1f} (手計算: -6)")

# 勾配降下法で1ステップ
lr = 0.1
with torch.no_grad():
    w1 -= lr * w1.grad; b1 -= lr * b1.grad
    w2 -= lr * w2.grad; b2 -= lr * b2.grad
    new_loss = ((w2 * torch.relu(w1*x+b1) + b2 - y)**2).item()

print(f"\n元の損失: {loss.item():.1f} → 新しい損失: {new_loss:.2f}")
print(f"損失が減少しました!")
=== サンプル PyTorch 验证 ===
∂L/∂w1 = -12.0  (手算: -12)
∂L/∂b1 = -6.0  (手算: -6)
∂L/∂w2 = -6.0  (手算: -6)
∂L/∂b2 = -6.0  (手算: -6)
原损失: 9.0 → 新损失: 1.03
损失减小了!

逆伝播 = 3つの線が合流

線形代数

順伝播 = 行列演算

z = Wx + b

微分積分

逆伝播 = チェーン則

∂L/∂w = ∂L/∂z · ∂z/∂w

最適化

パラメータ更新 = 勾配降下法

θ = θ - η∇J

確率 & 情報理論

損失設計 = MLE + 交差エントロピー

L = -log P(y|x)

逆伝播は本質的に3つのことを行います:順伝播で行列演算により出力を計算し、逆伝播でチェーン則により勾配を計算し、得られた勾配で勾配降下法によりパラメータを更新します。

確率統計と情報理論は、損失関数の選択に理論的根拠を提供します。


その他の拡張