前言
- 本文参考师兄的博文:反向传播算法过程及公式推导
- 好文章一定要吸收理解,强烈推荐本文的图示理解反向传播算法
图示BP过程
- 首先需要明确一个重要的知识点:每个神经元由两部分组成,第一部分 e 是输入值和权重系数乘积的和,第二部分f(e)是一个激活函数(非线性函数)的输出, y=f(e)即为某个神经元的输出,可以想象成一个神经元是一个圆形,一分为二,左半部分是e,右半部分是f(e)。如下图:
- 反向传播算法的关键:“正向传播”求损失,“反向传播”回传误差。同时,神经网络每层的每个神经元都可以根据误差信号修正每层的权重。下面以3层的感知机为例:
- 对上图略加解释:隐层和输出层的神经元都分为两部分,具体如图及之前所述。
- 上图的前向传播(网络输出计算)过程如下(此处为网络的整个误差的计算,误差E计算方法为mse)。下图从后向前剖析误差的产生。
上面的计算过程并不难,只要耐心一步步的拆开式子,逐渐分解即可。现在还有两个问题需要解决:
- 误差E有了,怎么调整权重让误差不断减小?
- E是权重w的函数,如何找到使得函数值最小的w?
解决上面问题的方法是梯度下降算法,简单图示如下:
- 划重点!BP算法的具体例子,如图是一个简单的神经网络用来举例:
- 前向(前馈)运算(激活函数为sigmoid):
- 反向传播(求网络误差对各个权重参数的梯度):
- 先来求最简单的,求误差E对w5的导数。首先明确这是一个“链式求导”过程,要求误差E对w5的导数,需要先求误差E对out o1的导数,再求out o1对net o1的导数,最后再求net o1对w5的导数,经过这个链式法则,我们就可以求出误差E对w5的导数(偏导),如下图所示:
解释一下out o1 对 net o1求偏导的过程:sigmoid函数的导数就是f(1-f),所以有了上式的求导过程。插一句:如上数值可以看到,sigmoid函数求导之后,梯度下降很大,导致梯度很小。在反向传播过程中,正是因为每次都会✖️激活函数(仅针对此处的sigmoid)的导数,所以会导致梯度消失问题,所以现在大部分都用ReLU激活函数,减轻梯度消失问题。
导数(梯度)已经计算出来了,下面就是反向传播与参数更新过程:
- 要想求误差E对w1的导数,误差E对w1的求导路径不止一条,这会稍微复杂一点,但换汤不换药,计算过程如下所示:
解释一下:神经网络图下的对w1求偏导,因为隔了o层,所以先求对o层的,再求对h1层的。至此,“反向传播算法”及公式推导的过程结束。
有关梯度消失的原因问题已经在上述过程中记录。
- 有关并行计算,GPU加速的理解:
- 对于每个batch的数据,可以对它们并行计算;
- 对于每层的神经元,重点:每层的神经元,不能跨层,可以对该层的神经元并行计算参数,进行更新。
- RNN不能如上所述进行并行计算,因为它的结构是神经元之间也有联系,每个神经元代表一个时间状态,所以只能串行。