以前很长一段时间都以为反向传播只不过是链式法则而已,对其理解并不是很到位。
前期组会做presentation的时候,终于对其有了深入的理解,反向传播的其实是结点误差,有了结点误差,就可以迅速更新梯度了(理解了这个,pytorch里面优化器更新模型参数的两个操作就很好理解了)。下面我们一起来看看吧。
1.模型介绍
为方面介绍反向传播,我们简化模型,如下图所示。其中是输入,结点按顺序标记1、2、3、..9;是第个结点经过激活函数的输出,默认采用激活函数;表示到的权重,4、5、6...9结点均有偏置,分别为(未在图中标记);模型输出为,图中的为真实标记;损失函数采用误差平方,前面的0.5是为了求导方便;学习算法采用随机梯度下降法(SGD)。
2.前向传播
前向传播是很简单的,我们的重点不仅仅在于写出单个结点的代数式,更重要的是矩阵的表示。
对于的计算如图2、3所示。
由此,我们可以整合下的表达式,如图4所示。观察4个代数式可以轻松的写出对应矩阵形式,如图5所示。
同理,我们可以飞快地写出第二个隐藏层节点输出的矩阵写法,如图6所示。
3.反向传播
如果不熟悉链式法则,图7是一个简单的示例,即将用换元方式对复杂函数求导,简化计算的方法。
下面就是重点了, 我们先对求偏导,结果如图8所示,是损失,即图1中的。我们将定义为,直观的看,结点8的误差确实是。这么定义现在看起来好像多此一举,但从后面链接的更新来看,这个定义既是形象的且更新时计算也是高效的。
同理,我们可以计算出,图9选择了几个进行计算。随后观察对应的代数式,可以将其写成矩阵形式,如图10所示。
差点漏了第二个隐藏层偏置梯度的计算了,让我们把它们俩补上去,计算方法是一模一样的,结果如图11所示,图12是其矩阵表示。
终于,我们掉了第二个隐层的权重、偏置的梯度。我们准备刷第一个隐层的权重、偏置的梯度,让我们考虑,其结果如图13所示,结合图8结点误差的定义,可以得到为(即4号结点误差)。同理,可以迅速求出该层其他链接的梯度,如图14,图15所示,而图16,图17分别是对应的矩阵的写法。
可以看到,通过定义,我们可以用矩阵乘法的形式写出权重、偏置的梯度。那么我们再把第一层结点误差求出来,结果如图18所示。从该式可以看出,前一层节点误差是后一层结点误差的线性组合,即前一层结点误差依赖于后一层结点误差。别忘了链接、偏置梯度是依赖于当层结点误差的,换言之,你告诉我某一层结点误差,我可以秒算出对应层链接、偏置的梯度值。
因此,我们的结论是只要计算每一层的结点误差,就可以秒算链接的梯度;前一层结点误差依赖于后一层结点误差;故而,在更新网络的链接时,我们可以考虑分两步走,先反向传播每一层结点误差(前一层依赖于后一层,故而反向计算方便得多),再利用结点误差秒算出对应层链接的梯度(从后往前,逐层更新),这与pytorch中优化器的两步操作也是对应的。
下述图是正向传播、反向传播的一个overview。
4.总结
希望读者通过此文,能理解反向传播的过程。step1,反向传播每一层结点误差;step2,更新每一层链接的权重。(当时做presentation的ppt是有存稿的,如有需要,可以contract。)
5.参考文献
[1] 塔里克·拉希德.python神经网络编程.
[2] 零基础入门深度学习(3) - 神经网络和反向传播算法.
[3] 李宏毅.2021春机器学习课程.
[4] 3Blue1Brown.What is backpropagation really doing?
[5] 陈希孺.概率论与数理统计.
[6] 吴恩达.深度学习.
[7] “反向传播算法”过程及公式推导(超直观好懂的Backpropagation)