nn-anatomy

数式ノート (math-notes)

本シミュレータが画面の右パネル「式の展開」で表示している数式の、 紙の上での定義と導出をまとめたリファレンス。

教室で学生が「なぜ δ = (ŷ − y) · φ'(z) なのか」「なぜエッジの勾配が a · δ なのか」を自力で確認できるように、記号の定義と連鎖律の展開を この 1 ファイルにまとめた。シミュレータ画面では [段1] 一般形 → [段2] 当てはめ → [段3] 数値 の 3 段構成で出しているが、ここでは [段1] に相当 する一般形と、[段2] → [段3] に接続するための補足を中心に書く。

詳細な実装 (Float64Array の二重ネスト、update() のタイミング等) は design.md を参照。

1. 記号と形状

層は 0 起点で、入力層が 0、出力層が $L-1$。各層 $l$ のサイズを $n_l$ とする (シミュレータ UI の 2-3-1 なら $n_0=2, n_1=3, n_2=1$)。

記号 形状 意味 画面表示
$x$ $n_0$ 入力ベクトル 入力層のノード
$a^{(l)}$ $n_l$ 層 $l$ の活性値 (= 出力) ノード上の “a=…”
$z^{(l)}$ $n_l$ 層 $l$ の pre-activation ノード上の “z=…”
$W^{(l)}$ $n_l \times n_{l-1}$ 層 $l$ の重み エッジの “w=…”
$b^{(l)}$ $n_l$ 層 $l$ のバイアス ノード右の青バッジ
$y$ $n_{L-1}$ 正解ラベル サンプル選択で固定
$\hat{y}$ $n_{L-1}$ モデル出力 $= a^{(L-1)}$ 出力層ノードの “a=…”
$\varphi$ スカラ関数 活性化 (層ごと) UI の Activation
$L$ スカラ 損失 Loss タブ
$\eta$ スカラ 学習率 (lr) UI の LR

画面上の $\delta_j^{(l)} := \partial L / \partial z_j^{(l)}$ は ノード下の赤字。δb も同様に $\partial L / \partial b_j^{(l)}$ の略。

2. Forward (推論)

入力層は恒等: $a^{(0)} = x$。以降は層を 1 枚ずつ通す。

\[z^{(l)}_j = b^{(l)}_j + \sum_i W^{(l)}_{ij} a^{(l-1)}_i, \qquad a^{(l)}_j = \varphi(z^{(l)}_j).\]

画面の [段2] ではノード名を入れて $z(L2N0) = b(L2N0) + w[L1N0 \to L2N0] \cdot a(L1N0) + \dots$ のように貼り替え、[段3] で数値を入れて最終的な $z$ と $a$ を確定する。

活性化 $\varphi$ の具体形は 4 種:

画面では同じ $\varphi’(z)$ が $a$ で書けるときは $a$ で書く ように してある (例: sigmoid は $a(1-a)$)。これは授業で「$a$ は画面に出てる、 $z$ より $a$ のほうがピンと来る」という事情に合わせた便宜。

3. 損失

2 種類。どちらも出力ベクトルの各成分で独立に計算できる形にしてある。

バッチ (Run) では全サンプル分を平均して $L$ と $\partial L / \partial W, \partial L / \partial b$ を求める (設計書 §6.4)。

4. Backward (誤差逆伝播)

4.1 記号の約束

\[\delta^{(l)}_j := \frac{\partial L}{\partial z^{(l)}_j}\]

を 1 つの名前で持ち回る。連鎖律の仕掛けが $\delta$ を 1 層前に伝搬 させるだけで重み勾配・バイアス勾配が全部出揃う構造になっていること を明示するのが、画面の赤字 δ

4.2 出力層

$\hat{y} = a^{(L-1)}$ なので、まず出力側で $\partial L / \partial a$ を 損失の微分として得る:

\[\frac{\partial L}{\partial a^{(L-1)}_j} = \begin{cases} \hat{y}_j - y_j & (\text{MSE}) \\ (\hat{y}_j - y_j) / (\hat{y}_j (1 - \hat{y}_j)) & (\text{BCE}) \end{cases}\]

そこから $z$ 側に映すのは活性化の傾きで:

\[\delta^{(L-1)}_j = \frac{\partial L}{\partial a^{(L-1)}_j} \cdot \varphi'(z^{(L-1)}_j).\]

画面の「Backward (出力層)」はまさにこの 2 行をそのまま板書する。

4.3 中間層 (連鎖律の核)

後段の $\delta^{(l+1)}$ が既に出ていれば、

\[\delta^{(l)}_j = \left( \sum_k W^{(l+1)}_{kj} \, \delta^{(l+1)}_k \right) \cdot \varphi'(z^{(l)}_j).\]

括弧内の和は「自分のノード $j$ から後段の各 $k$ に伸びるエッジの 重み × 後段の $\delta$ の和」。画面の [段3] では $k$ ごとに $(w \cdot \delta_\text{next})$ の項を横に並べ、後で $\varphi’(z)$ を 掛ける 2 段描きになっている。これが 連鎖律の正体 で、学生には 「後ろから届いた信号を、自分の活性の傾きで整え直している」と説明 できる。

4.4 重み勾配・バイアス勾配

$z^{(l)}j = b^{(l)}_j + \sum_i W^{(l)}{ij} a^{(l-1)}i$ を $W^{(l)}{ij}$ と $b^{(l)}_j$ で偏微分するだけ:

\[\frac{\partial L}{\partial W^{(l)}_{ij}} = a^{(l-1)}_i \cdot \delta^{(l)}_j, \qquad \frac{\partial L}{\partial b^{(l)}_j} = \delta^{(l)}_j.\]

$\partial L / \partial b$ が $\delta$ そのものになるのは 「$b$ は入力に何も掛からない」から。画面のバイアス Backward 欄で $\partial L / \partial b = \partial L / \partial z$ と 1 行で書ける 根拠。

4.5 まとめ (画面との対応)

画面 数式 備考
出力層ノード $\delta = (\partial L/\partial a) \cdot \varphi’(z)$ 損失と活性化の両方が [段2] 注記に出る
中間層ノード $\delta = (\sum_k w \cdot \delta_\text{next}) \cdot \varphi’(z)$ 後段の $\delta$ が既知前提
エッジ $\partial L/\partial w = a \cdot \delta$ 入力側 $a$ × 出力側 $\delta$
バイアス $\partial L/\partial b = \delta$ 入力側が常に 1

5. Update (勾配降下)

$\delta$, $\partial L/\partial W$, $\partial L/\partial b$ が出たあと の動きはシンプルな SGD:

\[\Delta W^{(l)}_{ij} = -\eta \cdot \frac{\partial L}{\partial W^{(l)}_{ij}}, \qquad W^{(l)}_{ij} \leftarrow W^{(l)}_{ij} + \Delta W^{(l)}_{ij},\]

バイアスも同形。符号は必ず勾配の逆向き なので、$\Delta$ は 必ず損失を下げる方向に 1 歩動く。Lesson6 でここを数値確認する。

3 経路での違い:

6. 学習率 $\eta$ の役割と発散

$\eta$ は 1 歩の大きさ。小さすぎると収束が遅く、大きすぎると

のいずれかが起きる。本シミュレータは isNetDiverged() で $W, b, a, z, \partial L/\partial \cdot$ のいずれかに NaN / Inf が現れた時点で 発散検出 し、Loss タブを 「⚠ 勾配が発散しました」カードに差し替える (設計書 §8 B8)。典型的な トリガは以下。

7. 初期化 (init scheme)

名前 分布 想定
xavier $\mathcal{N}(0, 1/n_{l-1})$ sigmoid/tanh 向き
he $\mathcal{N}(0, 2/n_{l-1})$ ReLU 向き
uniform $U(-1, 1)$ デモ用・分散固定の感覚づかみ
zero すべて $0$ 対称性で学習が進まない反例

seed を固定しておけば、同じ scheme + 同じサイズで必ず同じ $W, b$ に なる。Lesson5 が seed=42、Lesson7 が seed=7 なのはいずれも 「教室で 2 相収束が見えるように教員が事前に選んだ」値。

8. 参考: 画面と数式の対応早見表

画面操作 何が計算されている
Forward $a^{(0)} = x$ → 各層 $z^{(l)}, a^{(l)}$ を順に埋める
Backward 出力層で $\delta^{(L-1)}$、層 $l$ ごとに $\delta^{(l)}, \partial L/\partial W^{(l)}, \partial L/\partial b^{(l)}$
Update $W \leftarrow W + \Delta W$, $b \leftarrow b + \Delta b$ ($\Delta = -\eta \cdot \partial L/\partial \cdot$)
1 Step 上 3 つをこの順でまとめて
Run N 「全サンプルで Backward して平均 → Update」を N 回
Reset 現 UI 値で $W, b$ を再初期化 (seed 再利用)
Reset to Lesson 選択 Lesson の推奨値で UI を上書きしてから rebuild