综述
随着神经网络每层的学习速度其实是不一样的,并且随着层数增加这个问题就越来越明显。一般来说,接近输出层学习速率快,前面的层数学习慢,并随着层数增加学习越来越慢。这种情况我们称为梯度消失(vanishing gradient problem)。下面我们就来分析一下为什么会出现这种情况,并给出解决方案。
理论推导
若有一个神经网络如下:
神经网络有6层,其中每层都有一个神经元。要想知道为什么层数增加训练的越来越慢自然而然的想到考察一下梯度与变量间的变化关系,因此首先来考察一下b与梯度的变化关系。
下面就是理论上的推导了:
假设:
那么:
注: ∇σ(z) 表示对z求导。
此时我们得出了
b1
的变化对
z1
的影响,而
a1
的变化又会对
z2
产生影响因为
z2=w2∗a1+b2
那么此时:
综合上面的分析把
a1
的变化代入
z2
的变化得到:
依次类推的到:
注:有人可能要问怎么简单的就出来了C了呢?其实这个问题要看一下最初始神经网络的推导:
前面推导出了 ∂a∂z∗∂z∂b 现在我只需要把推导出的代入后面两部分,加上变换就可以了。
等式两边同时除以 Δb1 得到:
到现在终于推导完成了,长舒一口气。。。。
下面分析一下这个变化中的值,首先我们在初始w时,我们一般初始化为绝对值小于1的数。再来看导数部分:
观察导数图像发现,最大值为0.25。于是对于这个连乘公式,里面的数都小于1.随着层数增加,最终的变化率将越来越小。以至于趋近于零。
解决VD问题
经过上文理论推导,我们发现这个问题中核心是激活函数。sigmod的导数最大值1/4成为连乘越来越小的关键。自然我们也想另外选取激活函数来解决这个问题。下面祭出核心大杀器:
Rectified linear unit(ReLU)
线性整流函数f(x) = max(0,x),我们对比一下几个函数的图像:
观察ReLU发现在x>0时函数的导数是个常数,而sigmod随着延伸越来越平缓最终导数为0.所以不会出现VD问题了。
我们选择激活函数的时候选择这个函数就可以咯。