總結反向傳播算法。
來源于https://udlbook.github.io/udlbook/,我不明白初始不從 x 0 \boldsymbol{x}_0 x0?開始,而是從 z 0 \boldsymbol{z}_0 z0?開始,不知道怎么想的。
考慮一個深度神經網絡 g [ x i , ? ] g[\boldsymbol{x}_i, \boldsymbol{\phi}] g[xi?,?],它接受輸入 x i \boldsymbol{x}_i xi?,具有 N N N個隱藏層和 ReLU 激活函數,并且有單獨的損失項 L i = l o s s [ g [ x i , ? ] , y i ] L_i = {\rm loss}[g[\boldsymbol{x}_i, \boldsymbol{\phi}], \boldsymbol{y}_i] Li?=loss[g[xi?,?],yi?]。反向傳播的目標是計算關于偏差 b ι \boldsymbol{b}_\iota bι?和權重 W ι \boldsymbol{W}_\iota Wι?的導數 ? L i ? b ι \frac{\partial L_i}{\partial \boldsymbol{b}_\iota} ?bι??Li??和 ? L i ? W ι \frac{\partial L_i}{\partial \boldsymbol{W}_\iota} ?Wι??Li??。
前向傳遞: 計算并存儲以下量:
z 0 = b 0 + W 0 x i x ι = f [ z ι ? 1 ] ι ∈ { 1 , 2 , … , M } z ι = b ι + W ι x ι . ι ∈ { 1 , 2 , … , M } \begin{aligned} \boldsymbol{z}_0 &= \boldsymbol{b}_0 + \boldsymbol{W}_0 \boldsymbol{x}_i \\ \boldsymbol{x}_\iota &=f[\boldsymbol{z}_{\iota-1}] & \iota \in \{1, 2, \ldots, M\} \\ \boldsymbol{z}_\iota &= \boldsymbol{b}_\iota + \boldsymbol{W}_\iota \boldsymbol{x}_\iota. & \iota \in \{1, 2, \ldots, M\} \end{aligned} z0?xι?zι??=b0?+W0?xi?=f[zι?1?]=bι?+Wι?xι?.?ι∈{1,2,…,M}ι∈{1,2,…,M}?
反向傳遞: 從損失函數 L i L_i Li?關于網絡輸出 z M \boldsymbol{z}_M zM?的導數 ? L i ? z M \frac{\partial L_i}{\partial \boldsymbol{z}_M} ?zM??Li??開始,并在網絡中反向工作:
? L i ? b ι = ? L i ? z ι ι ∈ { M , M ? 1 , … , 1 } ? L i ? W ι = ? L i ? z ι x ι T ι ∈ { M , M ? 1 , … , 1 } ? L i ? z ι ? 1 = I [ z ι ? 1 > 0 ] ⊙ ( W ι T ? L i ? z ι ) , ι ∈ { M , M ? 1 , … , 1 } \begin{aligned} \frac{\partial L_i}{\partial \boldsymbol{b}_\iota} &= \frac{\partial L_i}{\partial \boldsymbol{z}_\iota} & \iota \in \{M, M-1, \ldots, 1\} \\ \frac{\partial L_i}{\partial \boldsymbol{W}_\iota} &= \frac{\partial L_i}{\partial \boldsymbol{z}_\iota} \boldsymbol{x}_\iota^{\mathsf T} & \iota \in \{M, M-1, \ldots, 1\} \\ \frac{\partial L_i}{\partial \boldsymbol{z}_{\iota-1}} &= \mathbb{I}[\boldsymbol{z}_{\iota-1} > 0] \odot \left( \boldsymbol{W}_\iota^{\mathsf T} \frac{\partial L_i}{\partial \boldsymbol{z}_\iota} \right), & \iota \in \{M, M-1, \ldots, 1\} \end{aligned} ?bι??Li???Wι??Li???zι?1??Li???=?zι??Li??=?zι??Li??xιT?=I[zι?1?>0]⊙(WιT??zι??Li??),?ι∈{M,M?1,…,1}ι∈{M,M?1,…,1}ι∈{M,M?1,…,1}?
其中 ⊙ \odot ⊙表示逐點乘法,而 I [ z ι ? 1 > 0 ] \mathbb{I}[\boldsymbol{z}_{\iota-1} > 0] I[zι?1?>0]是一個向量,其中在 z ι ? 1 \boldsymbol{z}_{\iota-1} zι?1?大于零的位置包含一,在其他位置包含零。
最后,計算關于第一組偏差和權重的導數:
? L i ? b 0 = ? L i ? z 0 ? L i ? W 0 = ? L i ? z 0 x i T . \begin{aligned} \frac{\partial L_i}{\partial \boldsymbol{b}_0} &= \frac{\partial L_i}{\partial \boldsymbol{z}_0} \\ \frac{\partial L_i}{\partial \boldsymbol{W}_0} &= \frac{\partial L_i}{\partial \boldsymbol{z}_0} \boldsymbol{x}_i^{\mathsf T}. \end{aligned} ?b0??Li???W0??Li???=?z0??Li??=?z0??Li??xiT?.?
為批次中的每個訓練樣本計算這些導數,并將它們相加以獲取用于 SGD 更新的梯度。
請注意,反向傳播算法非常高效;前向和反向傳遞中最耗計算的步驟是矩陣乘法(分別由 W \boldsymbol{W} W和 W T \boldsymbol{W}^{\mathsf T} WT進行),這只需要加法和乘法。然而,它不是內存高效的;前向傳遞中的中間值必須全部存儲,這可能會限制可以訓練的模型的大小。