深度学习中常用的方法有伍耐瞎:
权值衰减(Weight Decay): 在损失函数中加入权值参数的L2范数正则化项,可以缓解梯度消失和梯度爆炸的问题。
批标准化(Batch Normalization): 在网络的每一层的前后都加入批标准化层,能够有效地控制参数的分布,缓解梯度消失和梯度爆炸的问题。
ReLU激活函数: 使用ReLU激亩段活函数可以更好地解决梯度消失的问题。
采用残差网络(Residual Network): 采用残差网络能够加速训练过程,同时可以缓解梯度消失和梯度爆炸的问题。
引入Dropout: 在训练过程中随机丢弃部分神经元,能够有效地防止过拟合,同时可以缓解梯度消失和梯度爆炸的问题腔空。
两种情况下梯度消失经常出现,一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。弊轿梯度爆炸一般出现在深层网络和权值初始化值太大的情况下,下面分别从这两个角度分析梯度消失和爆炸的原因。
总结:从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足,另外多说一句,Hinton提出capsule的原因就是为了彻底抛弃反向传播,如果真能大范围普及,那真是一个革命。
其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果租埋肆激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其倒数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失
同理,tanh作为损失函数,它的导数图如下,可以看出,tanh比sigmoid要好一些,但是它的倒数仍然是小于1的。
在这里就不得不提一下我们用液悉得比较多的激励函数啦,上面的两类激励函数或多或少都会引起梯度爆炸,尤其是在网络结构越来越深的情况呀。那样什么样的激励函数能够避免这样的情况呢,这边我先引两个激励函数,之后的激励函数会再做一篇博客详细介绍
ReLu函数
Maxout函数
1、 梯度剪切 这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。
2、另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)比较常见的是l1正则,和l2正则,在各个深度框架中都有相应的API可以使用正则化,比如在tensorflow中,若搭建网络的时候已经设置了正则化参数
3、使用我上面提到的两个激活函数
4、Batchnorm是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batchnorm本质上是解决反向传播过程中的梯度问题。batchnorm全名是batch normalization,简称BN,即批规范化,通过规范化 *** 作将输出信号x规范化到均值为0,方差为1保证网络的稳定性。
(未完待续……)
反向传播(用于优化神网参数):根据损失函数计算的误差通过反向传播的方式,指导深度网络参数的更新优化。
采取反向传播的原因:首先,深层网络由许多线性层和非线性层堆叠而来,每一层非线性层都可以视为是一个非线性函数 (非线性来自于非线性激活函数)销枣,因此整个深度网络可以视为是一个复合的非线性多元函数。
我们最终的目的是希望这个非线性函数很好的完成输入到输出之间的映射,也就是找到让损失函数取得极小值。所以最终的问题就变成了一个寻找函数最小值的问题,在数学上,很自然的就会想到使用梯度下降来解决。
举个例子,对于一个含有三层隐藏层的简单神经网络来说,当梯度消失发生时,接近于输出层的隐藏层由于其梯度相对正常,所以权值更新时也就相对正常,但是当越靠近输入层时,由于梯度消失现象,会导致靠近输入层的隐藏层权值更新缓慢或者更新停滞。这就导致在训练时,只等价于后面几层的浅层网络的学习。
以最简单的网络结构为例,加入有三个隐藏层,每层的神经元个数都是1,且对应的非线性函数为 (其中为某个激活函数)如下图:
现在假设我们需要更新参数,那么我们就要求出损失函数对参数的导数,根据链式法则,可以写成下面这样:
而对于激活函数,之前一直使用Sigmoid函数,其函数图像成一个S型,如下所示,它会将正无穷到负无穷的数映射到0~1之间:
当我们对Sigmoid函数求导时,得到其结果如下:
由此可以得到它Sigmoid函数图像,呈现一个驼峰状(很像高斯函数),从求导结果可以看出,Sigmoid导数的取值范围在0~0.25之间,而我们初始化的网络权值 通常都小于1,因此,当层数增多时,小于0的值不断相乘,最后就导致梯度消失的情况出现。同理,梯度爆炸的问题也就很明显了,就是当权值 过大时,导致 ,最后大于1的值不断相乘,就会产生梯度爆炸。
Sigmoid函数求导图像
梯度消失和梯度爆炸本质上是一样的,都是因为网络层数太深而引发的梯度反向传播中的连乘效备历应。
解决梯度消失、爆炸主要有以下几种方案:
ReLu:让激活函数的导数为1
LeakyReLu:包含了ReLu的几乎所有有点,同时解决了ReLu中0区间带来的亏滚拆影响
ELU:和LeakyReLu一样,都是为了解决0区间问题,相对于来,elu计算更耗时一些(为什么)
具体可以看 关于各种激活函数的解析与讨论
BN本质上是解决传播过程中的梯度问题,具体待补充完善,查看 BN
具体待补充完善,查看 ResNet
LSTM不太容易发生梯度消失,主要原因在于LSTM内部复杂的“门(gates)”,具体看 LSTM基本原理解析
此方法来自Hinton在06年发表的论文上,其基本思想是每次训练一层隐藏层节点,将上一层隐藏层的输出作为输入,而本层的输出作为下一层的输入,这就是逐层预训练。
训练完成后,再对整个网络进行“微调(fine-tunning)”。
此方法相当于是找全局最优,然后整合起来寻找全局最优,但是现在基本都是直接拿imagenet的预训练模型直接进行finetunning。
这个方案主要是针对梯度爆炸提出的,其思想是设值一个剪切阈值,如果更新梯度时,梯度超过了这个阈值,那么就将其强制限制在这个范围之内。这样可以防止梯度爆炸。
另一种防止梯度爆炸的手段是采用权重正则化,正则化主要是通过对网络权重做正则来限制过拟合,但是根据正则项在损失函数中的形式:
可以看出,如果发生梯度爆炸,那么权值的范数就会变的非常大,反过来,通过限制正则化项的大小,也可以在一定程度上限制梯度爆炸的发生。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)