1. 什么是梯度消失,梯度爆炸
1.1. 什么是梯度消失
梯度消失是指在反向传播过程中梯度逐渐降低到0,导致参数不可学习的情况。
1.2. 什么是梯度爆炸
与梯度消失相反,在反向传播过程中,由于梯度过大导致模型无法收敛的情况。
总结:无论梯度消失还是梯度爆炸都跟模型学习过程中的链式求导有关。
当模型的层数过多的时候,计算梯度的时候就会出现非常多的乘积项。用下面这个例子来理解:
这是每层只有1个神经元的例子,每个神经元的激活函数都是sigmoid,然后我们想要更新b1这个参数。按照大家都公认的符号来表示:
可以得到这个偏导数:
然后化简:
因此经常会有这样的现象:
图中,分别表示4层隐藏层的梯度变化幅度。可以看到,最浅的那个隐藏层,梯度更新的速度,是非常小的。【图中纵轴是指数变化的】。
【总结】
- 梯度消失和梯度爆炸是指前面几层的梯度,因为链式法则不断乘小于(大于)1的数,导致梯度非常小(大)的现象;
- sigmoid导数最大0.25,一般都是梯度消失问题。
2. 解决梯度消失,梯度爆炸的方法
2.1. 更换激活函数
最常见的方案就是更改激活函数,现在神经网络中,除了最后二分类问题的最后一层会用sigmoid之外,每一层的激活函数一般都是用ReLU。
【ReLU】:如果激活函数的导数是1,那么就没有梯度爆炸问题了。
【leakyReLU】:在ReLU的负数部分,增加了一定的斜率:
解决了ReLU中会有死神经元的问题。
【ELU】:跟Leaky ReLU一样是为了解决死神经元问题,但是增加的斜率不是固定的:
但是相比Leaky ReLU,计算量更大。
2.2. 添加Batch Norm(BN)层
这个是非常给力的成功,在图像处理中必用的层了。BN层提出来的本质就是为了解决反向传播中的梯度问题。
在神经网络中,有这样的一个问题:Internal Covariate Shift。假设第一层的输入数据经过第一层的处理之后,得到第二层的输入数据。这时候,第二层的输入数据相对第一层的数据分布,就会发生改变,所以这一个batch,第二层的参数更新是为了拟合第二层的输入数据的那个分布。然而到了下一个batch,因为第一层的参数也改变了,所以第二层的输入数据的分布相比上一个batch,又不太一样了。然后第二层的参数更新方向也会发生改变。层数越多,这样的问题就越明显。
但是为了保证每一层的分布不变的话,那么如果把每一层输出的数据都归一化0均值,1方差不就好了?但是这样就会完全学习不到输入数据的特征了。不管什么数据都是服从标准正太分布,想想也会觉得有点奇怪。所以BN就是增加了两个自适应参数,可以通过训练学习的那种参数。这样把每一层的数据都归一化到β均值,γ标准差的正态分布上。
【将输入分布变成正态分布,是一种去除数据绝对差异,扩大相对差异的一种行为,所以BN层用在分类上效果的好的。对于Image-to-Image这种任务,数据的绝对差异也是非常重要的,所以BN层可能起不到相应的效果。】
2.3. 残差结构
==残差结构,简单的理解,就是让深层网络通过走捷径,让网络不那么深层。这样梯度消失的问题就缓解了。==
2.4. 梯度剪切、正则化
梯度剪切:
这个方案主要是针对梯度爆炸提出的,其思想是设置一个剪切阈值,如果更新梯度时,梯度超过了这个阈值,那么就将其强制限制在这个范围之内。这样可以防止梯度爆炸。
正则化:
另一种防止梯度爆炸的手段是采用权重正则化,正则化主要是通过对网络权重做正则来限制过拟合。通过限制正则化项的大小,也可以在一定程度上限制梯度爆炸的发生。
2.5. LSTM结构
LSTM不太容易发生梯度消失,主要原因在于LSTM内部复杂的“门(gates)”
2.6. 预训练加fine-tunning
此方法来自Hinton在06年发表的论文上,其基本思想是每次训练一层隐藏层节点,将上一层隐藏层的输出作为输入,而本层的输出作为下一层的输入,这就是逐层预训练。
训练完成后,再对整个网络进行“微调(fine-tunning)”。
此方法相当于是找全局最优,然后整合起来寻找全局最优,但是现在基本都是直接拿imagenet的预训练模型直接进行finetunning。
- 最后说:,梯度消失和梯度爆炸问题都是因为网络太深,网络权值更新不稳定造成的,本质上是因为梯度反向传播中的连乘效应
3. 如何知道网络中是否有梯度爆炸问题?
在网络训练过程中,如果发生梯度爆炸,那么会有一些明显的迹象表明这一点,例如:
- 模型无法在训练数据上收敛(比如,损失函数值非常差);
- 模型不稳定,在更新的时候损失有较大的变化;
- 模型的损失函数值在训练过程中变成NaN值;
如果你遇到上述问题,我们就可以深入分析网络是否存在梯度爆炸问题。还有一些不太为明显的迹象可以用来确认网络中是否存在梯度爆炸问题:
- 模型在训练过程中,权重变化非常大;
- 模型在训练过程中,权重变成NaN值;
- 每层的每个节点在训练时,其误差梯度值一直是大于1.0;
4. 如何知道网络中是否有梯度消失问题?
- 模型无法从训练数据中获得更新,损失几乎保持不变。
参考
https://blog.csdn.net/weixin_39853245/article/details/90085307
https://mp.weixin.qq.com/s/IdtX_wWTfsimU7AMDCnccw
https://zhuanlan.zhihu.com/p/263067159
(这里包含很多面经,面试题等,值得关注和学习)
https://mp.weixin.qq.com/s/s5MO8RXvc64kgw2YQueXkA
https://www.cnblogs.com/ZFJ1094038955/p/12158583.html