神经网络如今能够得以广泛应用,就是在于反向传播算法使得求梯度变得简单而快速,大量参数才能够快速更新。
这里手推一下NN的BP过程。首先定义网络各表达式:
- 设损失函数为J(W,b)
- 第l层输入为第l-1层的输出,即$A^{l-1}$
- 经过线性运算后为$Z^l=W^lA^{l-1}+b^l$
- 经过激活函数后输出为$A^l=\sigma(Z^l)$
根据链式求导法则,损失函数对第l层的参数$W^l$梯度为(b同理,略)
$$
\frac{\partial J}{\partial W^l}=\frac{\partial J}{\partial Z^l}\frac{\partial Z^l}{\partial W^l}
$$
根据开始的定义,易得$\frac{\partial Z^l}{\partial W^l}=A^{l-1}$。就是前一层的输出。这是正向传播的过程。
那么对于$\frac{\partial J}{\partial Z^l}$继续进行链式求导:
$$
\frac{\partial J}{\partial Z^l}=\frac{\partial J}{\partial A^l}\frac{\partial A^l}{\partial Z^l}=\frac{\partial J}{\partial A^l}\sigma^\prime (Z^l)
$$
对于$\frac{\partial J}{\partial A^l}$而言,因为$A^l$会输入到之后的网络层最终影响J,所以之后所有层也都要考虑。例如对l+1层,根据链式求导可以继续推导为:
$$
\frac{\partial J}{\partial A^l} = \frac{\partial J}{\partial Z^{l+1}} \frac{\partial Z^{l+1}}{\partial A^1}
$$
同样根据开始的定义,易得$\frac{\partial Z^{l+1}}{\partial A^l}=W^{l+1}$。
综合以上式子,得到一个递推公式:
$$
\frac{\partial J}{\partial Z^l}=\frac{\partial J}{\partial Z^{l+1}}W^{l+1}\sigma^\prime (Z^l)
$$
将损失对第l层非线性变换前的偏导称为该层的误差$\delta ^l = \frac{\partial J}{\partial Z^l}$,则式子可以简化写成
$$
\delta ^l = \delta ^{l+1}W^{l+1}\sigma^\prime (Z^l)
$$
这个式子可以这么理解:第l+1层的节点误差$\delta ^{l+1}=\frac{\partial J}{\partial Z^{l+1}}$经由参数为$W^{l+1}\sigma^\prime (Z^l)$的线性变换得到第l层的节点误差$\delta ^l=\frac{\partial J}{\partial Z^l}$。于是发现,这个式子也代表了一个神经网络,和原网络路径相同,方向相反,并且原网络参数得到了重复使用——这就是反向传播。
于是,反向传播梯度下降的过程就是:
- 正向传播,计算所有层输入输出
$$
Z^l=W^lA^{l-1}+b^l
$$
$$
A^l=\sigma(Z^l)
$$
- 计算输出层的损失
$$
\delta ^L = \frac{\partial J}{\partial Z^L}
$$
- 每层损失反向传播,计算梯度
$$
\delta ^l = \delta ^{l+1}W^{l+1}\sigma^\prime (Z^l)
$$
$$
\frac{\partial J}{\partial W^l}=\delta ^l A^{l-1}
$$
$$
\frac{\partial J}{\partial b^l}=\delta ^l
$$
- 每层用梯度下降法更新参数
$$
W^l \to W^l-\alpha \frac{\partial J}{\partial W^l}
$$
$$
b^l \to b^l-\alpha \frac{\partial J}{\partial b^l}
$$