梯度消失、梯度爆炸及其表现和解决方法

一、梯度消失

梯度消失出现的原因:

在深层网络中,如果激活函数的导数小于1,根据链式求导法则,靠近输入层的参数的梯度因为乘了很多的小于1的数而越来越小,最终就会趋近于0,例如sigmoid函数,其导数f′(x)=f(x)(1−f(x))的值域为(0,1/4),极易发生这种情况。
所以梯度消失出现的原因经常是因为网络层次过深,以及激活函数选择不当,比如sigmoid函数。

梯度消失的表现:

模型无法从训练数据中获得更新,损失几乎保持不变。

二、梯度爆炸

梯度爆炸出现的原因:

同梯度消失的原因一样,求解损失函数对参数的偏导数时,在梯度的连续乘法中总是遇上很大的绝对值,部分参数的梯度因为乘了很多较大的数而变得非常大,导致模型无法收敛。
所以梯度爆炸出现的原因也是网络层次过深,或者权值初始化值太大

梯度爆炸的表现:

(1)模型型不稳定,更新过程中的损失出现显著变化。
(2)训练过程中,模型损失变成 NaN。

三、梯度消失爆炸的解决方法:

  • 重新设置网络结构,减少网络层数,调整学习率(消失增大,爆炸减小)。
  • 预训练加微调
    • 此方法来自Hinton在2006年发表的一篇论文,Hinton为了解决梯度的问题,提出采取无监督逐层训练方法,其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。Hinton在训练深度信念网络(Deep Belief Networks中,使用了这个方法,在各层预训练完成后,再利用BP算法对整个网络进行训练。此思想相当于是先寻找局部最优,然后整合起来寻找全局最优,此方法有一定的好处,但是目前应用的不是很多了。
  • 激活函数采用relu,leaky relu,elu等。
  • batch normalization
  • 更换参数初始化方法(对于CNN,一般用xavier或者msra的初始化方法)
  • 调整深度神经网络的结构
  • 使用残差模块,DESNET模块或LSTM等结构(避免梯度消失)
  • l1、l2正则化(避免梯度爆炸)
  • 减小学习率、减小batch size(避免梯度爆炸)
  • 梯度裁剪(避免梯度爆炸)
    • 对于RNN,加入gradient clipping,每当梯度达到一定的阈值,就把他们设置回一个小一些的数字;

扩展:

loss突然变nan的原因?

可能原因:
1、training sample中出现了脏数据,或输入数据未进行归一化
2、学习速率过大,梯度值过大,产生梯度爆炸;
3、在某些涉及指数计算,可能最后算得值为INF(无穷)(比如不做其他处理的softmax中分子分母需要计算exp(x),值过大,最后可能为INF/INF,得到NaN,此时你要确认你使用的softmax中在计算exp(x)做了相关处理(比如减去最大值等等));
4、不当的损失函数(尤其是自定义的损失函数时);
5、在卷积层的卷积步伐大于卷积核大小的时候。

参考网址:
训练深度学习网络时候,出现Nan是什么原因,怎么才能避免?
梯度消失和梯度爆炸原因,表现,解决方案
警惕!损失Loss为Nan或者超级大的原因
知乎:训练神经网络循环3000次后,交叉熵损失为nan原因?
详解机器学习中的梯度消失、爆炸原因及其解决方法
梯度消失,梯度爆炸及表现

发布了143 篇原创文章 · 获赞 161 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/vivian_ll/article/details/100919715