深度学习中梯度消失和梯度爆炸的根本原因及其缓解方法

  • 一、梯度消失和爆炸的根本原因
  • 1. 深层网络角度
  • 2. 激活函数角度
  • 二、梯度消失、爆炸的解决方案
  • 1. 梯度剪切、正则
  • 2. 采用其他的激活函数
  • 2.1 Relu
  • 2.2 LeakRelu
  • 3. BatchNorm
  • 4. 残差结构


一、梯度消失和爆炸的根本原因

首先解释一下什么是梯度消失和梯度爆炸,
梯度消失:梯度趋近于零,网络权重无法更新或更新的很微小,网络训练再久也不会有效果;
梯度爆炸:梯度呈指数级增长,变的非常大,然后导致网络权重的大幅更新,使网络变得不稳定。

其实不管是梯度消失还是梯度爆炸本质上都是由于——深度神经网络的反向传播造成的。

可以通过两个角度去解释:一是在深层网络中,二是采用的激活函数导致的。

1. 深层网络角度

我们先来回顾一下神经网络反向传播的机理:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_神经网络


简单的三层神经网络

先看其中某一层的反算机制,上图中红色线的部分:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_权重_02


X表示本层的输入/上一层的输出,Y表示本层的输出

公式一

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_人工智能_03

公式二

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_激活函数_04


公式一表示:传到前一层的梯度大小,其值跟后一层传过来的梯度以及本层的权重W有关

公式二表示:本层更新权重W时的梯度值,其值跟后一层传过来的梯度以及本层的输入X有关

这两个概念很重要,从数学角度上解释了反向更新时的影响因子X和W。深度学习本质就是通过学习不断更新权重,以找到合适的值使损失下降的最低以完美的匹配输入和输出。

更新权重公式表示如下:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_激活函数_05


其中:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_神经网络_06

对于处理复杂任务时,深度网络比浅层的网络具有更好的效果。而多层深度网络更新权重时的反向传播采用的是链式法则,简单的理解就是n个公式二连乘。
当 ∂Loss/∂w 部分大于1时,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸;
当 ∂Loss/∂w 部分小于1时,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。

接着我们加入激活函数,来看看在深度网络中会发生什么情况:

从上述的公式二可知,

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_激活函数_04


更新权重的梯度不仅与本层的输入X有关还和下一层传过来的梯度有关。

通过网络结构可知,输入除了经过Affine (wx+b)层,还会经过激活函数,再传输到下一层。因此反向传播时,下一层传过来的梯度也会分别计算这两部分。假设用sigmoid作为激活函数:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_神经网络_08


其导数图像为:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_深度学习_09


该导数在s′(0)=0.25时达到最高,

如果我们使用标准方法(均值为0标准差为1的高斯分布)来初始化网络中的权重,那么权重通常会满足|W| < 1,则W*S′(y) < 1/4。

当所有这些项的乘积时,最终结果肯定会指数级下降:项越多,乘积的下降也就越快。假设现在有四层网络,我们想比较一下第一层网络的梯度和第三层的网络的梯度大小:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_人工智能_10


σ′(z)表示sigmoid的导数,z1-z4表示当前层的输出,w2-w4表示当前层的权重。

由上述公式可知,由于W*σ′(z) < 1/4的约束,因此∂C/∂b1要小于∂C/∂b3,即第一层网络的梯度要小于第三层的网络梯度。

一般情况中,梯度爆炸很少会发生(因为对输出会做归一化),大多会发生梯度消失,而越往前面传播,梯度就越小,因此靠近输入的前几层权重可能只会有很小的更新。

总结:从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。 因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足。

2. 激活函数角度

上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,tanh这种容易饱和的函数,梯度消失就会比较明显。

sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失,在前文中已经解释过了。

现在我们来看一下tanh函数及其导数:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_人工智能_11


tanh数学表达为:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_人工智能_12


从图像中我们可以看出tanh比sigmoid的梯度值要高,不过值也是小于1的,两边也会出现饱和,也会引起梯度消失的现象。

二、梯度消失、爆炸的解决方案

1. 梯度剪切、正则

梯度剪切这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。

权重正则化也是解决度爆炸的手段,比较常见的是L1正则,和L2正则,正则化是通过对网络权重做正则,防止w过大,限制过拟合,正则项在损失函数的形式为:

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_人工智能_13


α为超参数,是正则项系数

通过公式一可知,W越大,传到上一层的梯度就越大,连乘之后,就容易发生梯度爆炸,因此,对W做正则化就是约束W的取值,可以部分限制梯度爆炸的发生。
除了对W做正则化,在初始权重的时候可以加上标准化,使W符合均值为0,标准差为1的高斯分布,也能限制部分梯度爆炸的发生。

2. 采用其他的激活函数

2.1 Relu

relu思想很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了,每层的网络都可以得到相同的更新速度,relu就这样应运而生。

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_激活函数_14


relu的数学表达式

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_深度学习_15


relu的函数图像及其导数 从上图中,我们可以很容易看出,relu函数的导数在正数部分是恒等于1的,因此在深层网络中使用relu激活函数就不会导致梯度消失和爆炸的问题。

relu的主要贡献在于:

  • 解决了梯度消失、爆炸的问题
  • 计算方便,计算速度快
  • 加速了网络的训练

缺点:

  • 由于负数部分恒为0,会导致一些神经元无法激活(可通过设置小学习率部分解决)
  • 输出不是以0为中心的

2.2 LeakRelu

LeakRelu就是为了解决Relu的0区间带来的影响,其数学表达为:深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_激活函数_16

其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来。

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_深度学习_17


LeakRelu的函数图像

3. BatchNorm

BatchNorm具有加速网络收敛速度,提升训练稳定性的效果,本质上是解决反向传播过程中的梯度问题。BatchNorm全名是batch normalization,简称BN,即批归一化,通过规范化操作将输出信号X归一化保证网络的稳定性。
根据公式二可知,

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_激活函数_04


更新权重的梯度和上一层的输出X有关,如果输出过大或过小,就会导致产生梯度爆炸和梯度消失,BatchNorm就是通过对每一层的输出规范为均值和方差一致的方法,消除了X带来的放大缩小的影响,进而解决梯度消失和爆炸的问题,或者可以理解为BN将输出从饱和区拉倒了非饱和区。

4. 残差结构

深度学习进行测试的时候怎么 不进行梯度传播 解决深度网络梯度消失_神经网络_19


残差学习单元

残差中有很多这样的跨层连接结构,其实就是在前向传播的过程中,输出端的值加上输入X再传到下一层网络结构中,这样的结构在反向传播中具有很大的好处。
因为旁边的分支结构是直接传递过来的,没有带权重,因此反向传播时该分支的梯度始终为1,这样即使主干梯度值很小,加上分支的梯度再传给上一层网络时,梯度也不会很小,从而很大程度上缓解了梯度消失。
所以利用残差结构,可以轻松的构建几百层网络结构,而不用担心梯度消失过快的问题。