反向传播算法——矩阵形式递推公式——ReLU传递函数_反向传播算法 矩阵形式
总结反向传播算法。
来源于https://udlbook.github.io/udlbook/,我不明白初始不从x0\\boldsymbol{x}_0x0开始,而是从z0\\boldsymbol{z}_0z0开始,不知道怎么想的。
考虑一个深度神经网络g[xi,ϕ]g[\\boldsymbol{x}_i, \\boldsymbol{\\phi}]g[xi,ϕ],它接受输入xi\\boldsymbol{x}_ixi,具有NNN个隐藏层和 ReLU 激活函数,并且有单独的损失项Li=loss[g[xi,ϕ],yi]L_i = {\\rm loss}[g[\\boldsymbol{x}_i, \\boldsymbol{\\phi}], \\boldsymbol{y}_i]Li=loss[g[xi,ϕ],yi]。反向传播的目标是计算关于偏差bι\\boldsymbol{b}_\\iotabι和权重Wι\\boldsymbol{W}_\\iotaWι的导数∂Li∂bι\\frac{\\partial L_i}{\\partial \\boldsymbol{b}_\\iota}∂bι∂Li和∂Li∂Wι\\frac{\\partial L_i}{\\partial \\boldsymbol{W}_\\iota}∂Wι∂Li。
前向传递: 计算并存储以下量:
z0=b0+W0xixι=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}z0xιzι=b0+W0xi=f[zι−1]=bι+Wιxι.ι∈{1,2,…,M}ι∈{1,2,…,M}
反向传递: 从损失函数LiL_iLi关于网络输出zM\\boldsymbol{z}_MzM的导数∂Li∂zM\\frac{\\partial L_i}{\\partial \\boldsymbol{z}_M}∂zM∂Li开始,并在网络中反向工作:
∂Li∂bι=∂Li∂zιι∈{M,M−1,…,1}∂Li∂Wι=∂Li∂zιxιTι∈{M,M−1,…,1}∂Li∂zι−1=I[zι−1>0]⊙(WιT∂Li∂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ι∂Lixι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大于零的位置包含一,在其他位置包含零。
最后,计算关于第一组偏差和权重的导数:
∂Li∂b0=∂Li∂z0∂Li∂W0=∂Li∂z0xiT.\\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∂LixiT.
为批次中的每个训练样本计算这些导数,并将它们相加以获取用于 SGD 更新的梯度。
请注意,反向传播算法非常高效;前向和反向传递中最耗计算的步骤是矩阵乘法(分别由W\\boldsymbol{W}W和WT\\boldsymbol{W}^{\\mathsf T}WT进行),这只需要加法和乘法。然而,它不是内存高效的;前向传递中的中间值必须全部存储,这可能会限制可以训练的模型的大小。