本文详细讲解dnn和cnn的反向传播流程。其实无论是dnn还是cnn、pool层,最重要的是,我们要弄清楚反向传播的四个公式,弄清楚他们,我们就明白整个网络是如何运作和优化的,4个核心公式分别是:
1、输出层的误差方程 -这个是基础
2、误差传递方程
3、可训练参数权重w的变化率(梯度)
4、可训练参数偏置b的变化率(说到底其实网络就是在算误差,然后优化w和b,使得最后误差最小)
同时理解各种层的前向推理过程,那么整个网络的流动和机制就相当清晰了。
首先,我们需要了解全连接层的dnn的网络的推理和传播过程,接着这个基础,再进一步的分析cnn的流程。
前向传播过程(激活输出值):
其中为每一层激活的输入,则上式变为。
反向推理过程其实就是权重w和偏置b的变化,通过两个参数的变化影响损失函数C,因此需要计算每一个参数的和 。此时引入误差的概念,表示第l层第j个单元的误差:
此时我们基于此推理出4个基本方程:
1、输出层的误差方程
写成矩阵形式:
2、误差传递方程:
从bp2可以看出,第l+1层的误差计算第l层的误差,结合bp1和bp2,便可以计算网络中的任意一层的误差,先计算,再计算,。。。指导输入层。
附上证明过程(思路简单,就是麻烦):
此时,所以可以得到,代入上述方程,因此可以得到bp2(写成点乘的方式就是bp2的表达式):
3、代价函数对偏置的改变率
4、代价函数对权重的改变率
可以进一步简写为:
可以看出,上一层的激活输出如果很小接近于0时,无论返回的误差有多么大,权重的改变率基本就为0,这就解释了为什么神经元饱和或者神经元死亡都会导致学习的非常慢,这也就是说明为什么激活函数的选择重要性。
综上,我们得到和后,此时我们就可以使用梯度下降,从而计算出网络中w和b参数的梯度。
这里提到为什么反向传播比普通的梯度定义求偏导快:
我们普通的求偏导可以使用如下式来进行计算:
为了计算上式,我们需要从头到尾进行一次前向传播得到最终的值,如果要单独计算每一个参数的偏导,假定有100万个参数,我们由于需要对每一个参数单独然后计算求偏导,相当于1次迭代就要前向传播100万次。
再看反向传播,此时已知神经网络先通过一次前向传播计算出最深层的输出和各层输出ak(第一次前向传播),,再利用bp1和bp2计算出所有的层的误差,...(计算量相当于一次前向传播-第二次前向传播),再由bp4可以看出,已知每一层的输出和误差,可以直接计算每一层的变化率(变化速度),从而得到梯度,计算量值相当于2次forward。
1、cnn的前向推理
卷积层的前向推理实际上就是矩阵计算然后将多个矩阵计算结果相加的问题,此处不讨论
2、cnn的反向传播
首先看卷积层的误差推理公式,也就是bp2,先给出结论:
为什么是这样的呢,我们通过简单的举例来验证:
假定l层的输出是一个3*3的矩阵,第l+1层的卷积核W-l+1是一个2*2的矩阵,卷积步长为1,则输出一个Z-l+1是一个2*2的矩阵,此时简化b-l(偏置)为0,则有:
将上式拆解成矩阵形式,如下式:
利用卷积的计算方式,可以得到:
接下来计算损失函数C对输出值a的偏导,
在式3的4个等式中,可以明显看出,a11只与z11有关,求偏导后,可以得到如下:
同理,可以得到其他8个:
然后我们将上面一共9个式子使用一个矩阵卷积的形式来表示:
如上所示,我们在误差矩阵周围填充了一圈0,此时将卷积核翻转后和反向传播的梯度和误差进行卷积,得到前一层的梯度误差,则我们直接可以简写成最开始的bp2形式,此处再重复写一次,得到cnn的bp2-误差传递方程:
然后我们基于bp4来推导权重的梯度,也需要经过一个旋转的操作(类似的原理,此处不详细分析),如下得到cnn的bp4-卷积的梯度计算(注意,根据原博客,认为是要上一层输出旋转180度,但是经过原始博客评论区提醒,我简单推了一下,应该是不需要旋转180度的,如下所示):
对于偏置b,由于误差时3维张量,而b只是一维向量,不能像dnn中直接,通常是将的各个子矩阵分别求和,得到一个误差向量,即b的梯度,则为cnn的bp3-偏置的梯度计算:
而cnn的bp1是一样的,因此从上到下,我们同样也分析到了基于cnn的bp2,bp3,bp4,因此本质上cnn的反向传播同样也是4个核心公式的变形,但是需要自己简单推理和理解一下。
由于池化层没有激活函数,则可以看成是线性激活函数,即,则,则bp1很好推理,与dnn一致,但激活层的偏导为1,接下来讨论池化层如何推导误差:
1、max-pool
如果是max-pool时,我们的误差推导则只需要在前向推理时记住max的位置,然后在反向传播时,将误差直接放到原来的最大值位置,其他位置置为0,形象化举例如下:
假定第k+1层的误差为如下,
则第k层的误差如下:
图中,最大池化的位置已经在前向传播时记住,因此直接放回最大的误差。
2、average pool
只需要将池化层的误差平均值放回原来的矩阵中即可,上式的简单举例,k+1层误差如最大池化层,k层最大误差为:
其实average、max pool是前向传播的逆操作,很好理解,这就是池化层的bp2。因为池化层没有参数,所以不需要bp3和bp4,bp1与dnn一致,但激活层的偏导为1.
综上,便是cnn的前向推理和反向传播的基本核心,至于其他的upsample、反卷积等,此处就不讨论了,有兴趣的同学可以进一步研究,本文的出发点在于回忆一些基础但很模糊的东西,下一篇是否要考虑总结一下各种优化方法?
注意:本文基本上是参考了如下博客,因为毕竟如果不进行参考的话,从哪里写起来都不知道,按照参考博客的思路整合和理解。
参考博客:https://blog.csdn.net/qq_16137569/article/details/81449209