深度学习-梯度爆炸和梯度消失

1、梯度爆炸和梯度消失

        训练很深的神经网络时,随着层数的增加,导数会出现指数级的下降,则导致梯度消失。或者指数级的增加,导致梯度爆炸;本质是梯度传递的链式法则所导致的矩阵高次幂(反向传播会逐层对函数求偏导相乘);

1)梯度消失

        网络层之间的梯度(值小于 1.0)重复相乘导致的指数级减小会产生梯度消失;       

原因: 主要是因为网络层数太多,太深,导致梯度无法传播。本质应该是激活函数的饱和性

表现:神经网络的反向传播是逐层对函数偏导相乘,因此当神经网络层数非常深的时候,最后一层产生的偏差就因为乘了很多的小于1的数而越来越小,最终就会变为0,从而导致层数比较浅的权重没有更新,这就是梯度消失

DNN结果出现nan值?梯度爆炸,导致结果不收敛。都是梯度太大惹的祸,所以可以通过减小学习率(梯度变化直接变小)、减小batch size(累积梯度更小)、 features规格化(避免突然来一个大的输入)。

解决方法:

1、合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。

    其中, n 为特征数,初始化合理的权重值,它不会增长过快或下降过快到0,可避免梯度爆炸或消失,也可以加快训练速度;

2、使用relu代替sigmoid和tanh作为激活函数。

3、使用其他结构的RNNs,比如长短时记忆网络(LTSM)和Gated Recurrent Unit(GRU),这是最流行的做法。详情请参阅深度学习-循环神经网络(RNN)

2)梯度爆炸

        网络层之间的梯度(值大于 1.0)重复相乘导致的指数级增长会产生梯度爆炸;

原因:梯度爆炸就是由于初始化权值过大,前面层会比后面层变化的更快,就会导致权值越来越大,梯度爆炸的现象就发生了。

表现:在深层网络或循环神经网络中,误差梯度可在更新中累积,变成非常大的梯度,然后导致网络权重的大幅更新,并因此使网络变得不稳定。在极端情况下,权重的值变得非常大,以至于溢出,导致 NaN 值(即无穷大)。

解决方法:

1、可设置阈值进行梯度修剪:观察梯度向量,如果大于某个阈值,可以适当地缩放梯度,保证其不会太大,(通过最大值 阈值来修剪),相对具有鲁棒性。

在DL书中是说用梯度范数截断,通过银子缩放保证了参数更新与真实梯度是相同的方向;更新:g \leftarrow gv/\parallel g\parallel

2、权重正则化:通过对网络权重做正则限制过拟合;

2、为什么引入激活函数ReLU?

1)采用sigmoid等函数,反向传播求误差梯度时,求导计算量很大,而Relu求导非常容易。

2)对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(在sigmoid接近饱和区时,变换太缓慢,导数趋于0),从而无法完成深层网络的训练。

3)Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生;

4)ReLU:  g(z) = max(0,z),

leaky ReLU:g(z) = max(0.01z,z),求导,若激活函数为1,就不存在梯度消失或爆炸的问题了

                                                          g^{'}(z)=\left\{\begin{matrix} 0 & z<0\\ 1 & z>0 \end{matrix}\right.

3、为什么用非线性激活函数?

若用线性,线性的组合还是线性,设置多层就没有意义了,还不如不要隐层;

4、为什么用sigmoid作为激活函数呢?

求导方便,然后它可以把函数值映射到【0~1】之间,符合样本属于正类的概率;

猜你喜欢

转载自blog.csdn.net/sisteryaya/article/details/81364089