一、为什么会产生梯度消失和梯度爆炸?
目前优化神经网络的方法都是基于BP,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。其中将误差从末层往前传递的过程需要链式法则(Chain Rule)的帮助,因此反向传播算法可以说是梯度下降在链式法则中的应用。
而链式法则是一个连乘的形式,所以当层数越深的时候,梯度将以指数形式传播。梯度消失问题和梯度爆炸问题一般随着网络层数的增加会变得越来越明显。在根据损失函数计算的误差通过梯度反向传播的方式对深度网络权值进行更新时,得到的梯度值接近0或特别大,也就是梯度消失或爆炸。梯度消失或梯度爆炸在本质原理上其实是一样的。
二、分析产生梯度消失和梯度爆炸的原因
【梯度消失】经常出现,产生的原因有:一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。当梯度消失发生时,接近于输出层的隐藏层由于其梯度相对正常,所以权值更新时也就相对正常,但是当越靠近输入层时,由于梯度消失现象,会导致靠近输入层的隐藏层权值更新缓慢或者更新停滞。这就导致在训练时,只等价于后面几层的浅层网络的学习。
【梯度爆炸】一般出现在深层网络和权值初始化值太大的情况下。在深层神经网络或循环神经网络中,误差的梯度可在更新中累积相乘。如果网络层之间的梯度值大于 1.0,那么重复相乘会导致梯度呈指数级增长,梯度变的非常大,然后导致网络权重的大幅更新,并因此使网络变得不稳定。
梯度爆炸会伴随一些细微的信号,如:①模型不稳定,导致更新过程中的损失出现显著变化;②训练过程中,在极端情况下,权重的值变得非常大,以至于溢出,导致模型损失变成 NaN等等。
下面将从这3个角度分析一下产生这两种现象的根本原因
(1)深层网络
一个比较简单的深层网络如下:
由于深度网络是多层非线性函数的堆砌,整个深度网络可以视为是一个复合的非线性多元函数(这些非线性多元函数其实就是每层的激活函数),那么对loss function求不同层的权值偏导,相当于应用梯度下降的链式法则,链式法则是一个连乘的形式,所以当层数越深的时候,梯度将以指数传播。
如果接近输出层的激活函数求导后梯度值大于1,那么层数增多的时候,最终求出的梯度很容易指数级增长,就会产生梯度爆炸;相反,如果小于1,那么经过链式法则的连乘形式,也会很容易衰减至0,就会产生梯度消失。
从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足。
(2)激活函数
以下图的反向传播为例(假设每一层只有一个神经元且对于每一层
可以推导出:
原因看下图,sigmoid导数的图像。
如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,而我们初始化的网络权值|w|通常都小于1,因此|σ′(z1)w1|≤1/4,|σ′(z2)w2|≤1/4,|σ′(z2)w2|≤1/4,|σ′(z2)w2|≤1/4,乘在一起肯定小于等于1/4,因此对于上面的链式求导,层数越多,求导结果∂C/∂b1越小,因而很容易发生梯度消失。
(3)初始化权重的值过大
如上图所示,比如w1=w2=w3=w4=16时,σ′(z1)=σ′(z2)=σ′(z3)=σ′(z4)=1/4时,得出|σ′(z1)w1|=|σ′(z2)w2|=|σ′(z3)w3|=|σ′(z4)w4|=4,乘在一起肯定大于等于1,根据链式相乘(反向传播)可得,则前面的网络层比后面的网络层梯度变化更快,很容易发生梯度爆炸的问题。