δi:=∂e∂ai\delta_i:=\frac{\partial e}{\partial a_i}
∂e∂wiℓ=∂e∂ai∂ai∂wiℓ=δizℓ\frac{\partial e}{\partial w_{i\ell}}=\frac{\partial e}{\partial a_i}\frac{\partial a_i}{\partial w_{i\ell}}=\delta_i z_\ell

完整講解與原文對照 / Full explanation and source comparison

多層網路怎麼算梯度?靠反向傳播

訓練前饋神經網路,本質仍是梯度下降,但參數散落在各層,要算 ∂e/∂wiℓ\partial e / \partial w_{i\ell} 不能硬算——反向傳播(Backpropagation) 用鏈式法則從輸出層往回算,一次搞定所有權重梯度。同樣由 Rumelhart 等人系統化提出;概念上就是「分層系統裡的梯度下降 + 遞迴求導」。

單一神經元:前向與 δ\delta

考慮神經元 ii,權重 wiℓw_{i\ell} 連接前一層神經元 ℓ\ell。前向計算(式 (9)–(10)):

amp;ai=∑ℓ=1mwiℓzℓ,amp;zi:=σi(ai), \begin{align*} & a_{i}=\sum_{\ell=1}^{m} w_{i \ell} z_{\ell}, \tag{9}\\ & z_{i}:=\sigma_{i}\left(a_{i}\right), \tag{10} \end{align*}

aia_i 是激活前加權和,ziz_i 是激活後輸出,σi\sigma_i 是激活函數。

對任意權重 wiℓw_{i\ell},鏈式法則給出(式 (11)–(12)):

∂e∂wiℓ=∂e∂ai×∂ai∂wiℓ=(a)δi×zℓ,(11) \frac{\partial e}{\partial w_{i \ell}}=\frac{\partial e}{\partial a_{i}} \times \frac{\partial a_{i}}{\partial w_{i \ell}} \stackrel{(a)}{=} \delta_{i} \times z_{\ell}, \tag{11}

δi:=∂e∂ai.(12) \delta_{i}:=\frac{\partial e}{\partial a_{i}} . \tag{12}

δi\delta_i 是誤差對激活前輸入的敏感度;因為 ∂ai/∂wiℓ=zℓ\partial a_i / \partial w_{i\ell} = z_\ell,梯度 = δi×zℓ\delta_i \times z_\ell。

隱藏層的 δ\delta:往後傳

若 ii 在隱藏層(非輸出層),δi\delta_i 要從下游層累加回來(式 (13)–(15)):

δi=∂e∂ai=∑j(δj×∂aj∂ai)=∑j(δj×wjiσ′(ai)),(15) \delta_{i}=\frac{\partial e}{\partial a_{i}}=\sum_{j}\left(\delta_{j} \times \frac{\partial a_{j}}{\partial a_{i}}\right)=\sum_{j}\left(\delta_{j} \times w_{j i} \sigma^{\prime}\left(a_{i}\right)\right), \tag{15}

其中 ∂aj/∂ai=wji σ′(ai)\partial a_j / \partial a_i = w_{ji}\,\sigma'(a_i)(式 (14))。代入式 (11) 得隱藏層權重梯度(式 (16)):

∂e∂wiℓ=zℓσ′(ai)∑j(δjwji).(16) \frac{\partial e}{\partial w_{i \ell}}=z_{\ell} \sigma^{\prime}\left(a_{i}\right) \sum_{j}\left(\delta_{j} w_{j i}\right) . \tag{16}

權重更新:輸出層 vs 隱藏層

通用更新(式 (17)):

wiℓ(k+1):=wiℓ(k)−η(k)∂e∂wiℓ,∀i,ℓ.(17) w_{i \ell}^{(k+1)}:=w_{i \ell}^{(k)}-\eta^{(k)} \frac{\partial e}{\partial w_{i \ell}}, \quad \forall i, \ell . \tag{17}

輸出層(ii 在最後一層,式 (18)):

wiℓ(k+1):=wiℓ(k)−η(k)zℓ∂e∂ai.(18) w_{i \ell}^{(k+1)}:=w_{i \ell}^{(k)}-\eta^{(k)} z_{\ell} \frac{\partial e}{\partial a_{i}} . \tag{18}

隱藏層(式 (19)):

wiℓ(k+1):=wiℓ(k)−η(k)zℓσ′(ai)∑j(δjwji).(19) w_{i \ell}^{(k+1)}:=w_{i \ell}^{(k)}-\eta^{(k)} z_{\ell} \sigma^{\prime}\left(a_{i}\right) \sum_{j}\left(\delta_{j} w_{j i}\right) . \tag{19}

差別在:輸出層 δi=∂e/∂ai\delta_i = \partial e / \partial a_i 可直接算;隱藏層要多乘 σ′(ai)\sigma'(a_i) 並把下游 δj\delta_j 加權傳回來。

Algorithm 2 流程摘要

  1. 初始化權重 w(0)\boldsymbol{w}^{(0)};
  2. 每輪 kk:設學習率 η(k)\eta^{(k)};
  3. 從最後一層往回(layer rr → 第一層):對每個神經元 ii、前一層神經元 ℓ\ell:
  4. 若 rr 是最後一層:用式 (18);
  5. 否則:用式 (19);
  6. 檢查收斂;未收斂則調整 η(k)\eta^{(k)} 繼續。

口語版:先 forward 算 a,za, z 和 loss → 輸出層算 δ\delta → 一層層往回傳 δ\delta → 用 δizℓ\delta_i z_\ell(加隱藏層修正)更新每個 wiℓw_{i\ell}。

教授祕笈:反向傳播——鍋爐房傳話,誤差從出口倒灌(式 (9)–(19))

同學,KP-1 已經劇透過:多層網路之所以能訓,靠的是反向傳播(Backpropagation)。今天進鍋爐房。前向很單純——煤炭從入口一間間傳到煙囪;麻煩的是出事以後。煙囪蒸汽太多或太少,你不能把整座廠拆了重算,你要讓「哪根閥門轉錯了」這句話,從出口倒灌回每一間房。Rumelhart 等人把這套傳話系統化:本質就是分層系統裡的梯度下降,配上鏈式法則。整節一句話:誤差從出口倒灌,每根閥門只聽隔壁傳過來的抱怨。

先把任務講成一句人話

訓練前饋網路,骨子裡還是梯度下降,但權重散落在各層,wiℓw_{i\ell} 對最終誤差 ee 的偏導不能硬算。反向傳播從輸出層開始,用鏈式法則一層層把「誤差對激活前輸入的敏感度」δ\delta 往回傳,於是每個權重的梯度都變成「我的 δ\delta 乘上前面傳來的輸出」。

鷹架式:先直覺,再符號

整座廠只做兩件事:先往前燒、再往回罵。

符號逐個拆

神經元 ii 的前向,就是鍋爐房的兩道手續(式 (9)–(10)):

ai=∑ℓ=1mwiℓzℓ.(9) a_{i}=\sum_{\ell=1}^{m} w_{i \ell} z_{\ell}. \tag{9}

zi:=σi(ai).(10) z_{i}:=\sigma_{i}\left(a_{i}\right). \tag{10}

對任意一根管子 wiℓw_{i\ell},鏈式法則拆成兩段(式 (11)–(12)):

∂e∂wiℓ=∂e∂ai×∂ai∂wiℓ=(a)δi×zℓ,(11) \frac{\partial e}{\partial w_{i \ell}}=\frac{\partial e}{\partial a_{i}} \times \frac{\partial a_{i}}{\partial w_{i \ell}}\stackrel{(a)}{=}\delta_{i}\times z_{\ell}, \tag{11}

δi:=∂e∂ai.(12) \delta_{i}:=\frac{\partial e}{\partial a_{i}}. \tag{12}

δi\delta_i 是誤差對這間房爐溫的敏感度。因為 aia_i 裡 wiℓw_{i\ell} 前面乘的就是 zℓz_{\ell},所以 ∂ai/∂wiℓ=zℓ\partial a_i/\partial w_{i\ell}=z_{\ell},梯度=抱怨強度 × 進來的量。

若 ii 在隱藏層,它自己看不見煙囪,必須接下游的電話。式 (13)–(14) 先把 ∂e/∂ai\partial e/\partial a_i 拆成「各下游 δj\delta_j 乘上 ∂aj/∂ai\partial a_j/\partial a_i」,而 ∂aj/∂ai=wjiσ′(ai)\partial a_j/\partial a_i=w_{ji}\sigma'(a_i);加總後就是式 (15):

δi=∑j(δj wji σ′(ai)).(15) \delta_{i}=\sum_{j}\bigl(\delta_{j}\,w_{ji}\,\sigma'(a_{i})\bigr). \tag{15}

白話:把每間下游房的 δj\delta_j,乘上「我接過去那根管子 wjiw_{ji}」,再乘上「我這扇閥門此刻有多敏感 σ′(ai)\sigma'(a_i)」,全部加起來。代入式 (11) 就是隱藏層權重梯度(式 (16)):

∂e∂wiℓ=zℓ σ′(ai)∑j(δjwji).(16) \frac{\partial e}{\partial w_{i \ell}}=z_{\ell}\,\sigma'(a_{i})\sum_{j}(\delta_{j}w_{ji}). \tag{16}

通用更新還是梯度下降(式 (17)):

wiℓ(k+1):=wiℓ(k)−η(k)∂e∂wiℓ.(17) w_{i \ell}^{(k+1)}:=w_{i \ell}^{(k)}-\eta^{(k)}\frac{\partial e}{\partial w_{i \ell}}. \tag{17}

輸出層看得到誤差,直接用 δi=∂e/∂ai\delta_i=\partial e/\partial a_i(式 (18));隱藏層多乘 σ′\sigma' 並加總下游(式 (19)):

wiℓ(k+1):=wiℓ(k)−η(k)zℓ∂e∂ai,(18) w_{i \ell}^{(k+1)}:=w_{i \ell}^{(k)}-\eta^{(k)} z_{\ell}\frac{\partial e}{\partial a_{i}}, \tag{18}

wiℓ(k+1):=wiℓ(k)−η(k)zℓ σ′(ai)∑j(δjwji).(19) w_{i \ell}^{(k+1)}:=w_{i \ell}^{(k)}-\eta^{(k)} z_{\ell}\,\sigma'(a_{i})\sum_{j}(\delta_{j}w_{ji}). \tag{19}

Algorithm 2 的遍歷順序只有一句:從最後一層往回第一層。先 forward 算出所有 aa、zz 和 ee,輸出層算 δ\delta,一層層倒灌,再用 δizℓ\delta_i z_{\ell}(隱藏層加上 σ′\sigma' 與下游加權)更新每根管子。

真的算一遍:兩間房、一根倒灌的電話

最小鍋爐房:入口 → 隱藏房 ii → 出口房 jj。激活用 σ(a)=a2\sigma(a)=a^{2}(所以 σ′(a)=2a\sigma'(a)=2a),出口不再轉彎(恆等)。學習率 η=0.1\eta=0.1,誤差 e=12(zj−0)2e=\tfrac12(z_{j}-0)^{2}(目標蒸汽是 00,實際太多)。

步驟 人話 數字
入口送來 zℓz_{\ell} 11
隱藏管子 wiℓw_{i\ell} 11
隱藏爐溫 ai=wiℓzℓa_i=w_{i\ell}z_{\ell} 11
隱藏送出 zi=σ(ai)=ai2z_i=\sigma(a_i)=a_i^{2} 11
閥門斜率 σ′(ai)=2ai\sigma'(a_i)=2a_i 22
出口管子 wjiw_{ji} 11
出口爐溫/蒸汽 aj=zj=wjizia_j=z_j=w_{ji}z_i 11
誤差 e=12(1−0)2e=\tfrac12(1-0)^{2} 0.50.5
出口 δj\delta_j ∂e/∂aj=zj−0\partial e/\partial a_j=z_j-0 11
出口梯度 δj⋅zi\delta_j\cdot z_i(式 (11)) 11
隱藏 δi\delta_i δj wji σ′(ai)\delta_j\,w_{ji}\,\sigma'(a_i)(式 (15)) 1×1×2=21\times1\times2=2
隱藏梯度 δi⋅zℓ\delta_i\cdot z_{\ell} 22

更新:出口管子式 (18) 變成 1−0.1×1×1=0.91-0.1\times1\times1=0.9;隱藏管子式 (19) 變成 1−0.1×1×2×(1×1)=0.81-0.1\times1\times2\times(1\times1)=0.8。誤差 0.50.5 是正的、蒸汽太多,兩根管子都往細調——倒灌的方向跟常識一致。

用差分偷瞄一眼隱藏梯度:把 wiℓw_{i\ell} 從 11 撥到 1.011.01,則 ai=1.01a_i=1.01、zi=1.0201z_i=1.0201、zj=1.0201z_j=1.0201、e≈0.5203e\approx0.5203,差量約 0.0203/0.01=2.030.0203/0.01=2.03,貼近我們算的 22。鏈式法則不是咒語,是可以對帳的算術。

先留一個反轉

出口蒸汽明明全錯,中間那根閥門有沒有可能這一步完全不動?有。給隱藏房接兩根出口:一根 δ1=1\delta_1=1、w1i=1w_{1i}=1,另一根 δ2=−1\delta_2=-1、w2i=1w_{2i}=1。式 (15) 的加總 1⋅1+(−1)⋅1=01\cdot1+(-1)\cdot1=0,於是 δi=0\delta_i=0,隱藏梯度也是 00。兩間鍋爐房一個嫌熱、一個嫌冷,電話打到中間互相抵消——中間那個人這回合收不到任何該轉閥門的指示。反向傳播傳的不是「有沒有錯」,而是帶正負號、會對消的敏感度。你若以為「下游有錯、上游一定會動」,數字會打你臉。

換個場景,自己找出同一條路

把鍋爐房換成公司客訴專線:客服(輸出層)先聽到客人罵什麼,把「這單該誰負責」δ\delta 打給課長;課長再按各組貢獻的權重 wjiw_{ji}、以及自己這關有多敏感 σ′\sigma',加總後打給組長。組長調的那根旋鈕,仍然是 δ×\delta\times(下屬交來的量)。骨架與式 (11)、(15)、(19) 相同,只是工廠換成辦公室。

留一題:入口 zℓ=2z_{\ell}=2,隱藏 wiℓ=0.5w_{i\ell}=0.5、ai=1a_i=1,仍用 σ(a)=a2\sigma(a)=a^{2},出口 wji=2w_{ji}=2、目標改成 33,η=0.05\eta=0.05。自己走一遍前向、δj\delta_j、δi\delta_i、兩根管子的新權重。式 (9)–(19) 夠你算完。

大家最容易在這裡搞混

第一個誤解:δi\delta_i 是 ∂e/∂w\partial e/\partial w 或 ∂e/∂z\partial e/\partial z。錯,式 (12) 寫明 δi:=∂e/∂ai\delta_i:=\partial e/\partial a_i,是對激活前爐溫,不是對權重、也不是對激活後輸出。第二個誤解:反向是從輸入層往輸出層走。錯,Algorithm 2 是從最後一層往回第一層;你得先有下游的 δj\delta_j 才能算上游的 δi\delta_i。第三個誤解:隱藏層更新跟輸出層「只差一個學習率」。錯,式 (19) 比式 (18) 多了 σ′(ai)\sigma'(a_i) 與下游 δj\delta_j 的加權和——少乘 σ′\sigma',閥門敏感度整段消失,梯度就傳錯。

跨知識點掛勾

換句話重述

把整節濃縮成一句:前向用式 (9)–(10) 把爐溫與蒸汽算完;δi=∂e/∂ai\delta_i=\partial e/\partial a_i,權重梯度是 δizℓ\delta_i z_{\ell};隱藏層的 δ\delta 從下游倒灌(式 (15)–(16));輸出層用式 (18)、隱藏層用式 (19),而且一定從最後一層往回走。

一句話收尾: 誤差從煙囪倒灌,每間鍋爐房只接隔壁電話——δ\delta 乘上進來的量,閥門就知道該轉哪邊。