精华内容
下载资源
问答
  • 本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。 其中,梯度消失...

    前言

    本文主要深入介绍深度学习中的梯度消失和梯度爆炸的问题以及解决方案。本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。
    其中,梯度消失爆炸的解决方案主要包括以下几个部分。

    - 预训练加微调
    - 梯度剪切、权重正则(针对梯度爆炸)
    - 使用不同的激活函数
    - 使用batchnorm
    - 使用残差结构
    - 使用LSTM网络
    

    第一部分:为什么要使用梯度更新规则


    在介绍梯度消失以及爆炸之前,先简单说一说梯度消失的根源—–深度神经网络和反向传播。目前深度学习方法中,深度神经网络的发展造就了我们可以构建更深层的网络完成更复杂的任务,深层网络比如深度卷积网络,LSTM等等,而且最终结果表明,在处理复杂任务上,深度网络比浅层的网络具有更好的效果。但是,目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。这样做是有一定原因的,首先,深层网络由许多非线性层堆叠而来,每一层非线性层都可以视为是一个非线性函数 f(x)f(x)f(x)(非线性来自于非线性激活函数),因此整个深度网络可以视为是一个复合的非线性多元函数
    F(x)=fn(...f3(f2(f1(x)∗θ1+b)∗θ2+b)...)F(x) = {f_n}(...{f_3}({f_2}({f_1}(x)*{\theta _1} + b)*{\theta _2} + b)...)F(x)=fn(...f3(f2(f1(x)θ1+b)θ2+b)...) 我们最终的目的是希望这个多元函数可以很好的完成输入到输出之间的映射,假设不同的输入,输出的最优解是g(x)g(x)g(x) ,那么,优化深度网络就是为了寻找到合适的权值,满足Loss=L(g(x),F(x))Loss = L(g(x),F(x))Loss=L(g(x),F(x))取得极小值点,比如最简单的损失函数
    Loss=∣∣g(x)−f(x)∣∣22Loss = ||g(x)-f(x)||^2_2Loss=g(x)f(x)22,假设损失函数的数据空间是下图这样的,我们最优的权值就是为了寻找下图中的最小值点,对于这种数学寻找最小值问题,采用梯度下降的方法再适合不过了。
    这里写图片描述

    第二部分:梯度消失、爆炸

    梯度消失与梯度爆炸其实是一种情况,看接下来的文章就知道了。两种情况下梯度消失经常出现,一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。梯度爆炸一般出现在深层网络和权值初始化值太大的情况下,下面分别从这两个角度分析梯度消失和爆炸的原因。

    1.深层网络角度

    比较简单的深层网络如下:
    这里写图片描述
    图中是一个四层的全连接网络,假设每一层网络激活后的输出为fi(x)f_i(x)fi(x),其中iii为第iii层, xxx代表第iii层的输入,也就是第i−1i-1i1层的输出,fff是激活函数,那么,得出fi+1=f(fi∗wi+1+bi+1)f_{i+1}=f(f_i*w_{i+1}+b_{i+1})fi+1=f(fiwi+1+bi+1),简单记为fi+1=f(fi∗wi+1)f_{i+1}=f(f_i*w_{i+1})fi+1=f(fiwi+1)
    BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,参数的更新为w←w+Δww \leftarrow w+\Delta www+Δw,给定学习率α\alphaα,得出Δw=−α∂Loss∂w\Delta w=-\alpha \frac{\partial Loss}{\partial w}Δw=αwLoss。如果要更新第二隐藏层的权值信息,根据链式求导法则,更新梯度信息:
    Δw2=∂Loss∂w2=∂Loss∂f4∂f4∂f3∂f3∂f2∂f2∂w2\Delta w_2=\frac{\partial Loss}{\partial w_2}=\frac{\partial Loss}{\partial f_4}\frac{\partial f_4}{\partial f_3}\frac{\partial f_3}{\partial f_2}\frac{\partial f_2}{\partial w_2}Δw2=w2Loss=f4Lossf3f4f2f3w2f2,很容易看出来∂f2∂w2=∂f∂(f1∗w2)f1\frac{\partial f_2}{\partial w_2}=\frac{\partial f}{\partial (f_1*w_2)}f_1w2f2=(f1w2)ff1,即第二隐藏层的输入。
    所以说,∂f4∂f3×w4\frac{\partial f_4}{\partial f_3} \times w4f3f4×w4就是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。如果说从数学上看不够直观的话,下面几个图可以很直观的说明深层网络的梯度问题1^11(图片内容来自参考文献1):

    注:下图中的隐层标号和第一张全连接图隐层标号刚好相反。
    图中的曲线表示权值更新的速度,对于下图两个隐层的网络来说,已经可以发现隐藏层2的权值更新速度要比隐藏层1更新的速度慢

    这里写图片描述

    	那么对于四个隐层的网络来说,就更明显了,第四隐藏层比第一隐藏层的更新速度慢了两个数量级:
    

    这里写图片描述

    总结:从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足,另外多说一句,Hinton提出capsule的原因就是为了彻底抛弃反向传播,如果真能大范围普及,那真是一个革命。

    2.激活函数角度

    其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其导数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失,sigmoid函数数学表达式为:sigmoid(x)=11+e−xsigmoid(x)=\frac{1}{1+e^{-x}}sigmoid(x)=1+ex1
    sigmoid函数sigmoid函数导数

    同理,tanh作为激活函数,它的导数图如下,可以看出,tanh比sigmoid要好一些,但是它的导数仍然是小于1的。tanh数学表达为:
    

    tanh(x)=ex−e−xex+e−xtanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}tanh(x)=ex+exexex

    这里写图片描述

    第三部分:梯度消失、爆炸的解决方案


    2.1 方案1-预训练加微调

    此方法来自Hinton在2006年发表的一篇论文,Hinton为了解决梯度的问题,提出采取无监督逐层训练方法,其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。Hinton在训练深度信念网络(Deep Belief Networks中,使用了这个方法,在各层预训练完成后,再利用BP算法对整个网络进行训练。此思想相当于是先寻找局部最优,然后整合起来寻找全局最优,此方法有一定的好处,但是目前应用的不是很多了。

    2.2 方案2-梯度剪切、正则

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

    注:在WGAN中也有梯度剪切限制操作,但是和这个是不一样的,WGAN限制梯度更新信息是为了保证lipchitz条件。
    

    另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)比较常见的是l1l1l1正则,和l2l2l2正则,在各个深度框架中都有相应的API可以使用正则化,比如在tensorflowtensorflowtensorflow中,若搭建网络的时候已经设置了正则化参数,则调用以下代码可以直接计算出正则损失:

    regularization_loss = tf.add_n(tf.losses.get_regularization_losses(scope='my_resnet_50'))
    

    如果没有设置初始化参数,也可以使用以下代码计算l2l2l2正则损失:

        l2_loss = tf.add_n([tf.nn.l2_loss(var) for var in tf.trainable_variables() if 'weights' in var.name])
    
    

    正则化是通过对网络权重做正则限制过拟合,仔细看正则项在损失函数的形式:
    Loss=(y−WTx)2+α∣∣W∣∣2Loss=(y-W^Tx)^2+ \alpha ||W||^2Loss=(yWTx)2+αW2
    其中,α\alphaα是指正则项系数,因此,如果发生梯度爆炸,权值的范数就会变的非常大,通过正则化项,可以部分限制梯度爆炸的发生。

    注:事实上,在深度神经网络中,往往是梯度消失出现的更多一些。
    

    2.3 方案3-relu、leakrelu、elu等激活函数

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

    这里写图片描述

    其函数图像:

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

    relu的主要贡献在于:

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

    同时也存在一些缺点

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

    尽管relu也有缺点,但是仍然是目前使用最多的激活函数

    leakrelu
    leakrelu就是为了解决relu的0区间带来的影响,其数学表达为:leakrelu=max(k∗x,x)leakrelu=max(k*x,x)leakrelu=max(kx,x)其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来

    这里写图片描述

    leakrelu解决了0区间带来的影响,而且包含了relu的所有优点
    elu
    elu激活函数也是为了解决relu的0区间带来的影响,其数学表达为:这里写图片描述
    其函数及其导数数学形式为:

    这里写图片描述

    但是elu相对于leakrelu来说,计算要更耗时间一些

    2.4 解决方案4-batchnorm

    Batchnorm是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batchnorm本质上是解决反向传播过程中的梯度问题。batchnorm全名是batch normalization,简称BN,即批规范化,通过规范化操作将输出信号x规范化保证网络的稳定性。
    具体的batchnorm原理非常复杂,在这里不做详细展开,此部分大概讲一下batchnorm解决梯度的问题上。具体来说就是反向传播中,经过每一层的梯度会乘以该层的权重,举个简单例子:
    正向传播中f2=f1(wT∗x+b)f_2=f_1(w^T*x+b)f2=f1(wTx+b),那么反向传播中,∂f2∂w=∂f2∂f1x\frac {\partial f_2}{\partial w}=\frac{\partial f_2}{\partial f_1}xwf2=f1f2x,反向传播式子中有xxx的存在,所以xxx的大小影响了梯度的消失和爆炸,batchnorm就是通过对每一层的输出规范为均值和方差一致的方法,消除了xxx带来的放大缩小的影响,进而解决梯度消失和爆炸的问题,或者可以理解为BN将输出从饱和区拉倒了非饱和区。
    有关batch norm详细的内容可以参考我的另一篇博客:
    http://blog.csdn.net/qq_25737169/article/details/79048516

    2.5 解决方案5-残差结构

    残差结构说起残差的话,不得不提这篇论文了:Deep Residual Learning for Image Recognition,关于这篇论文的解读,可以参考知乎链接:https://zhuanlan.zhihu.com/p/31852747这里只简单介绍残差如何解决梯度的问题。
    事实上,就是残差网络的出现导致了image net比赛的终结,自从残差提出后,几乎所有的深度网络都离不开残差的身影,相比较之前的几层,几十层的深度网络,在残差网络面前都不值一提,残差可以很轻松的构建几百层,一千多层的网络而不用担心梯度消失过快的问题,原因就在于残差的捷径(shortcut)部分,其中残差单元如下图所示:
    这里写图片描述
    相比较于以前网络的直来直去结构,残差中有很多这样的跨层连接结构,这样的结构在反向传播中具有很大的好处,见下式:
    这里写图片描述
    式子的第一个因子 ∂loss∂xL\frac{\partial loss}{\partial {{x}_{L}}}xLloss 表示的损失函数到达 L 的梯度,小括号中的1表明短路机制可以无损地传播梯度,而另外一项残差梯度则需要经过带有weights的层,梯度不是直接传递过来的。残差梯度不会那么巧全为-1,而且就算其比较小,有1的存在也不会导致梯度消失。所以残差学习会更容易。

    注:上面的推导并不是严格的证明。
    

    2.6 解决方案6-LSTM

    LSTM全称是长短期记忆网络(long-short term memory networks),是不那么容易发生梯度消失的,主要原因在于LSTM内部复杂的“门”(gates),如下图,LSTM通过它内部的“门”可以接下来更新的时候“记住”前几次训练的”残留记忆“,因此,经常用于生成文本中。目前也有基于CNN的LSTM,感兴趣的可以尝试一下。

    这里写图片描述

    参考资料:

    1.《Neural networks and deep learning》
    2.《机器学习》周志华
    3. https://www.cnblogs.com/willnote/p/6912798.html
    4. https://www.zhihu.com/question/38102762
    5. http://www.jianshu.com/p/9dc9f41f0b29


    如果感兴趣,请关注微信公众号,还有更多精彩:
    这里写图片描述

    展开全文
  • 因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足。 2、梯度消失、爆炸导致原因 2.1、从BP(反向传播原理)解释梯度消失和梯度爆炸 举例,一个简单的深层网络如下: 图中是一个四层的...

    1 、什么是梯度消失和梯度爆炸

    在反向传播过程中需要对激活函数进行求导,如果导数大于1,那么随着网络层数的增加梯度更新将会朝着指数爆炸的方式增加这就是梯度爆炸。同样如果导数小于1,那么随着网络层数的增加梯度更新信息会朝着指数衰减的方式减少这就是梯度消失。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足。

     

    2、梯度消失、爆炸导致原因

    2.1、从BP(反向传播原理)解释梯度消失和梯度爆炸

    举例,一个简单的深层网络如下:

    preview

    图中是一个四层的全连接网络,假设每一层网络激活后的输出为 fi(x) ,其中,fi(x) 代表第 i 层, 第i-1层的输出代表第 i 层的输入,也就是说第 fi-1 输出, f 是激活函数,那么 fi+1=f(fi*wi+1+bi+1) ,简答计为: fi+1=f(fi*wi+1) 。

    BP(反向传播算法)就是基于梯度下降策略,以目标的负梯度方向对参数进行调整,参数的更新为  ,给定学习率  ,得出  。如果更新第二层隐层的权值信息,根据链式求导法则,更新梯度信息为:

                             

    ,即第二隐藏层的输入。

     就是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失

    2.2、从激活函数角度分析梯度消失

     

    其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其导数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失,sigmoid函数数学表达式为:

        

     

    同理,tanh作为激活函数,它的导数图如下,可以看出,tanh比sigmoid要好一些,但是它的导数仍然是小于1的。tanh数学表达为:

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

     

    3.1、预训练加微调

    为了解决梯度的问题,采取无监督逐层训练方法,其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。此思想相当于是先寻找局部最优,然后整合起来寻找全局最优,此方法有一定的好处,但是目前应用的不是很多了。

    3.2、梯度剪切及正则化解决梯度爆炸

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

    另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)。

    正则化是通过对网络权重做正则限制过拟合,仔细看正则项在损失函数的形式:

    其中,  是指正则项系数,因此,如果发生梯度爆炸,权值的范数就会变的非常大,通过正则化项,可以部分限制梯度爆炸的发生。但在深度模型中,梯度消失更常见一些。

    3.3、relu、leakrelu、elu等激活函数

    3.3.1、Relu激活函数

    Relu:思想也很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了,每层的网络都可以得到相同的更新速度。Relu目前使用最多的激活函数

    3.3.2、Relu激活函数优缺点

    relu的优点:

    • 解决了梯度消失、爆炸的问题

    • 计算方便,计算速度快
    • 加速了网络的训练

    relu的缺点:

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

    3.3.3、leakrelu


    leakrelu就是为了解决relu的0区间带来的影响,其数学表达为:

                       leakrelu=max(k∗x,x)

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

    这里写图片描述

    3.3.4、elu

    elu激活函数也是为了解决relu的0区间带来的影响,其数学表达为:

    这里写图片描述

    相较于上面两个激活函数,elu计算更耗时一些

    3.4、batch normalization

    Batchnorm是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batchnorm本质上是解决反向传播过程中的梯度问题。batchnorm全名是batch normalization,简称BN,即批规范化,通过规范化操作将输出信号x规范化到均值为0,方差为1保证网络的稳定性。

    batchnorm解决梯度的问题上,即反向传播中,经过每一层的梯度会乘以该层的权重,举个简单例子:

    正向传播中f2=f1(wT∗x+b),那么反向传播中

    反向传播式子中有x的存在,所以x的大小影响了梯度的消失和爆炸,batchnorm就是通过对每一层的输出规范为均值和方差一致的方法,消除了x带来的放大缩小的影响,进而解决梯度消失和爆炸的问题。

    3.5、 残差结构

    3.5.1、深度网络的退化问题

    从经验来看,网络的深度对模型的性能至关重要,当增加网络层数后,网络可以进行更加复杂的特征模式的提取,所以当模型更深时理论上可以取得更好的结果,从下图中也可以看出网络越深而效果越好的一个实践证据。但是更深的网络其性能一定会更好吗?实验发现深度网络出现了退化问题(Degradation problem):网络深度增加时,网络准确度出现饱和,甚至出现下降。这个现象可以在图3中直观看出来:56层的网络比20层网络效果还要差。这不会是过拟合问题,因为56层网络的训练误差同样高。我们知道深层网络存在着梯度消失或者爆炸的问题,这使得深度学习模型很难训练。但是现在已经存在一些技术手段如BatchNorm来缓解这个问题。因此,出现深度网络的退化问题是非常令人诧异的。

    preview

    3.5.2、残差学习

    对于一个堆积层结构(几层堆积而成)当输入为 X 时其学习到的特征记为 H(x) ,现在我们希望其可以学习到残差 F(X)=H(X)-X ,这样其实原始的学习特征是 F(X)+X 。之所以这样是因为残差学习相比原始特征直接学习更容易。当残差为0时,此时堆积层仅仅做了恒等映射,至少网络性能不会下降,实际上残差不会为0,这也会使得堆积层在输入特征基础上学习到新的特征,从而拥有更好的性能。残差学习的结构如下图所示。这有点类似与电路中的“短路”,所以是一种短路连接(shortcut connection)。

    为什么残差学习相对更容易,从直观上看残差学习需要学习的内容少,因为残差一般会比较小,学习难度小点。不过我们可以从数学的角度来分析这个问题,首先残差单元可以表示为:

    其中 xl 和 xl+1 分别表示的是第 l 个残差单元的输入和输出,注意每个残差单元一般包含多层结构。  F是残差函数,表示学习到的残差,而 h(x)=x 表示恒等映射, f 是ReLU激活函数。基于上式,我们求得从浅层 l 到深层 L 的学习特征为:

    利用链式规则,可以求得反向过程的梯度:

    式子的第一个因子  表示的损失函数到达 L 的梯度,小括号中的1表明短路机制可以无损地传播梯度,而另外一项残差梯度则需要经过带有weights的层,梯度不是直接传递过来的。残差梯度不会那么巧全为-1,而且就算其比较小,有1的存在也不会导致梯度消失。所以残差学习会更容易。要注意上面的推导并不是严格的证明。

    3.6、LSTM

    循环神经网络RNN;

    在上面的示例图中,神经网络的模块A,正在读取某个输入xi ,并输出一个值 hi。循环可以使得信息可以从当前步传递到下一步。RNN 的关键点之一就是他们可以用来连接先前的信息到当前的任务上,例如使用过去的视频段来推测对当前段的理解。在间隔不断增大时,RNN 会丧失学习到连接如此远的信息的能力。所有 RNN 都具有一种重复神经网络模块的链式的形式。在标准的 RNN 中,这个重复的模块只有一个非常简单的结构,例如一个 tanh 层。


    LSTM 通过刻意的设计来避免长期依赖问题。LSTM 不同于RNN单一神经网络层,这里是有四个,以一种非常特殊的方式进行交互。

    图中使用的各种元素的图标

    LSTM 的关键就是细胞状态,水平线在图上方贯穿运行。

    细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。

    LSTM 有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个 sigmoid 神经网络层和一个按位的乘法操作。

    Sigmoid 层输出 0 到  1之间的数值,描述每个部分有多少量可以通过。 0代表“不许任何量通过”,1 就指“允许任意量通过”!

    使用一个合适激活函数,它的梯度在一个合理的范围。LSTM使用gate function,有选择的让一部分信息通过。gate是由一个sigmoid单元和一个逐点乘积操作组成,sigmoid单元输出1或0,用来判断通过还是阻止,然后训练这些gate的组合。所以,当gate是打开的(梯度接近于1),梯度就不会vanish。并且sigmoid不超过1,那么梯度也不会explode。

     

    参考网址:

    https://blog.csdn.net/qq_25737169/article/details/78847691 (梯度爆炸及消失详解)

    https://zhuanlan.zhihu.com/p/51490163  (梯度爆炸与梯度消失的介绍,考虑角度-反向传播 )

    https://blog.csdn.net/qq_25737169/article/details/79048516 (batchnorm详解)

    https://cloud.tencent.com/developer/article/1374163 (梯度消失和爆炸详解)

    https://zhuanlan.zhihu.com/p/31852747 (残差结构详解)

    https://www.zhihu.com/question/44895610/answer/154565425  (LSTM梯度弥散问题解释)

    https://www.jianshu.com/p/9dc9f41f0b29 (LSTM原理详解)

    https://zhuanlan.zhihu.com/p/32085405  (从几个门角度来详解LSTM的输入输出)

    展开全文
  • 当神经网络有很多层,每个隐藏层都使用Sigmoid函数作为激活函数时,很容易引起梯度消失或梯度爆炸问题 当x较大或较小时,Sigmoid函数导数接近0;且导数的最大值是0.25 梯度消失: 如果我们使用标准方法来初始化...

    原因

    在多层网络中,影响梯度大小的因素主要有两个:权重和激活函数的偏导,在反向传播过程中需要对激活函数进行求导,如果导数大于1,那么随着网络层数的增加梯度更新将会朝着指数爆炸的方式增加这就是梯度爆炸。同样如果导数小于1,那么随着网络层数的增加梯度更新信息会朝着指数衰减的方式减少这就是梯度消失。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足

    梯度消失:

    如果我们使用标准方法来初始化网络中的权重,那么会使用一个均值为0标准差为1的高斯分布。因此所有的权重通常会满足|wj|<1,而s‘是小于0.25的值,那么当神经网络特别深的时候,梯度呈指数级衰减,导数在每一层至少会被压缩为原来的1/4,当z值绝对值特别大时,导数趋于0,正是因为这两个原因,从输出层不断向输入层反向传播训练时,导数很容易逐渐变为0,使得权重和偏差参数无法被更新,导致神经网络无法被优化,训练永远不会收敛到良好的解决方案。 这被称为梯度消失问题。

    梯度爆炸:

    当我们将w初始化为一个较大的值时,例如>10的值,那么从输出层到输入层每一层都会有一个s‘(zn)*wn的增倍,当s‘(zn)为0.25时s‘(zn)*wn>2.5,同梯度消失类似,当神经网络很深时,梯度呈指数级增长,最后到输入时,梯度将会非常大,我们会得到一个非常大的权重更新,这就是梯度爆炸的问题,在循环神经网络中最为常见.

    解决方法

    1.合适的参数初始化
    2.使用RELU函数代替Sigmoid函数作为激活函数
    3.梯度剪切、权重正则 (针对梯度爆炸)
    4.批量规范化(Batch Normalization)
    5.LSTM的结构设计也可以改善RNN中的梯度消失问题

    LSTM缓解梯度消失的原因

    使用一个合适激活函数,它的梯度在一个合理的范围。LSTM使用gate function,有选择的让一部分信息通过。gate是由一个sigmoid单元和一个逐点乘积操作组成,sigmoid单元输出1或0,用来判断通过还是阻止,然后训练这些gate的组合。所以,当gate是打开的(梯度接近于1),梯度就不会消失。并且sigmoid不超过1,那么梯度也不会爆炸。

    LSTM的效果

    1、当gate是关闭的,那么就会阻止对当前信息的改变,这样以前的依赖信息就会被学到。
    2、当gate是打开的时候,并不是完全替换之前的信息,而是在之前信息和现在信息之间做加权平均。所以,无论网络的深度有多深,输入序列有多长,只要gate是打开的,网络都会记住这些信息。

    参考文章
    参考文章1
    参考文章2
    参考文章3
    LSTM解决梯度消失

    展开全文
  • [深度学习] 梯度消失与梯度爆炸的原因及解决方法

    万次阅读 多人点赞 2018-04-16 16:40:28
    本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。 其中,梯度消失...

    前言

    本文主要深入介绍深度学习中的梯度消失和梯度爆炸的问题以及解决方案。本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。 
    其中,梯度消失爆炸的解决方案主要包括以下几个部分。

    - 预训练加微调
    - 梯度剪切、权重正则(针对梯度爆炸)
    - 使用不同的激活函数
    - 使用batchnorm
    - 使用残差结构
    - 使用LSTM网络

    第一部分:为什么要使用梯度更新规则


    在介绍梯度消失以及爆炸之前,先简单说一说梯度消失的根源—–深度神经网络和反向传播。目前深度学习方法中,深度神经网络的发展造就了我们可以构建更深层的网络完成更复杂的任务,深层网络比如深度卷积网络,LSTM等等,而且最终结果表明,在处理复杂任务上,深度网络比浅层的网络具有更好的效果。但是,目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。这样做是有一定原因的,首先,深层网络由许多非线性层堆叠而来,每一层非线性层都可以视为是一个非线性函数 f(x)f(x)(非线性来自于非线性激活函数),因此整个深度网络可以视为是一个复合的非线性多元函数 

    F(x)=fn(...f3(f2(f1(x)θ1+b)θ2+b)...)F(x)=fn(...f3(f2(f1(x)∗θ1+b)∗θ2+b)...)
    我们最终的目的是希望这个多元函数可以很好的完成输入到输出之间的映射,假设不同的输入,输出的最优解是g(x)g(x) ,那么,优化深度网络就是为了寻找到合适的权值,满足Loss=L(g(x),F(x))Loss=L(g(x),F(x))取得极小值点,比如最简单的损失函数 
    Loss=||g(x)f(x)||22Loss=||g(x)−f(x)||22
    ,假设损失函数的数据空间是下图这样的,我们最优的权值就是为了寻找下图中的最小值点,对于这种数学寻找最小值问题,采用梯度下降的方法再适合不过了。 
    这里写图片描述

    第二部分:梯度消失、爆炸

    梯度消失与梯度爆炸其实是一种情况,看接下来的文章就知道了。两种情况下梯度消失经常出现,一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。梯度爆炸一般出现在深层网络和权值初始化值太大的情况下,下面分别从这两个角度分析梯度消失和爆炸的原因。

    1.深层网络角度

    比较简单的深层网络如下: 
    这里写图片描述 
    图中是一个四层的全连接网络,假设每一层网络激活后的输出为fi(x)fi(x),其中ii为第ii层, xx代表第ii层的输入,也就是第i1i−1层的输出,ff是激活函数,那么,得出fi+1=f(fiwi+1+bi+1)fi+1=f(fi∗wi+1+bi+1),简单记为fi+1=f(fiwi+1)fi+1=f(fi∗wi+1)。 
    BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,参数的更新为ww+Δww←w+Δw,给定学习率αα,得出Δw=αLosswΔw=−α∂Loss∂w。如果要更新第二隐藏层的权值信息,根据链式求导法则,更新梯度信息: 
    Δw1=Lossw2=Lossf4f4f3f3f2f2w2Δw1=∂Loss∂w2=∂Loss∂f4∂f4∂f3∂f3∂f2∂f2∂w2,很容易看出来f2w2=f1∂f2∂w2=f1,即第二隐藏层的输入。 
    所以说,f4f3∂f4∂f3就是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。如果说从数学上看不够直观的话,下面几个图可以很直观的说明深层网络的梯度问题11(图片内容来自参考文献1):

    注:下图中的隐层标号和第一张全连接图隐层标号刚好相反。 
    图中的曲线表示权值更新的速度,对于下图两个隐层的网络来说,已经可以发现隐藏层2的权值更新速度要比隐藏层1更新的速度慢

    这里写图片描述

        那么对于四个隐层的网络来说,就更明显了,第四隐藏层比第一隐藏层的更新速度慢了两个数量级:

    这里写图片描述

    总结:从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足,另外多说一句,Hinton提出capsule的原因就是为了彻底抛弃反向传播,如果真能大范围普及,那真是一个革命。

    2.激活函数角度

    其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其倒数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失,sigmoid函数数学表达式为:sigmoid(x)=11+exsigmoid(x)=11+e−x 
    sigmoid函数sigmoid函数导数

    同理,tanh作为损失函数,它的导数图如下,可以看出,tanh比sigmoid要好一些,但是它的倒数仍然是小于1的。tanh数学表达为:

    tanh(x)=exexex+extanh(x)=ex−e−xex+e−x

    这里写图片描述

    第三部分:梯度消失、爆炸的解决方案


    2.1 方案1-预训练加微调

    此方法来自Hinton在2006年发表的一篇论文,Hinton为了解决梯度的问题,提出采取无监督逐层训练方法,其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。Hinton在训练深度信念网络(Deep Belief Networks中,使用了这个方法,在各层预训练完成后,再利用BP算法对整个网络进行训练。此思想相当于是先寻找局部最优,然后整合起来寻找全局最优,此方法有一定的好处,但是目前应用的不是很多了。

    2.2 方案2-梯度剪切、正则

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

    注:在WGAN中也有梯度剪切限制操作,但是和这个是不一样的,WGAN限制梯度更新信息是为了保证lipchitz条件。

    另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)比较常见的是l1l1正则,和l2l2正则,在各个深度框架中都有相应的API可以使用正则化,比如在tensorflowtensorflow中,若搭建网络的时候已经设置了正则化参数,则调用以下代码可以直接计算出正则损失:

    regularization_loss = tf.add_n(tf.losses.get_regularization_losses(scope='my_resnet_50'))

    如果没有设置初始化参数,也可以使用以下代码计算l2l2正则损失:

        l2_loss = tf.add_n([tf.nn.l2_loss(var) for var in tf.trainable_variables() if 'weights' in var.name])

    正则化是通过对网络权重做正则限制过拟合,仔细看正则项在损失函数的形式: 
    Loss=(yWTx)2+α||W||2Loss=(y−WTx)2+α||W||2 
    其中,αα是指正则项系数,因此,如果发生梯度爆炸,权值的范数就会变的非常大,通过正则化项,可以部分限制梯度爆炸的发生。

    注:事实上,在深度神经网络中,往往是梯度消失出现的更多一些。

    2.3 方案3-relu、leakrelu、elu等激活函数

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

    这里写图片描述

    其函数图像:

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

    relu的主要贡献在于:

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

    同时也存在一些缺点

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

    尽管relu也有缺点,但是仍然是目前使用最多的激活函数

    leakrelu 
    leakrelu就是为了解决relu的0区间带来的影响,其数学表达为:leakrelu=max(kx,0)leakrelu=max(k∗x,0)其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来

    这里写图片描述

    leakrelu解决了0区间带来的影响,而且包含了relu的所有优点 
    elu 
    elu激活函数也是为了解决relu的0区间带来的影响,其数学表达为:这里写图片描述 
    其函数及其导数数学形式为:

    这里写图片描述

    但是elu相对于leakrelu来说,计算要更耗时间一些

    2.4 解决方案4-batchnorm

    Batchnorm是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batchnorm本质上是解决反向传播过程中的梯度问题。batchnorm全名是batch normalization,简称BN,即批规范化,通过规范化操作将输出信号x规范化到均值为0,方差为1保证网络的稳定性。 
    具体的batchnorm原理非常复杂,在这里不做详细展开,此部分大概讲一下batchnorm解决梯度的问题上。具体来说就是反向传播中,经过每一层的梯度会乘以该层的权重,举个简单例子: 
    正向传播中f2=f1(wTx+b)f2=f1(wT∗x+b),那么反向传播中,f2x=f2f1w∂f2∂x=∂f2∂f1w,反向传播式子中有ww的存在,所以ww的大小影响了梯度的消失和爆炸,batchnorm就是通过对每一层的输出规范为均值和方差一致的方法,消除了ww带来的放大缩小的影响,进而解决梯度消失和爆炸的问题。 
    有关batch norm详细的内容可以参考我的另一篇博客: 
    http://blog.csdn.net/qq_25737169/article/details/79048516

    2.5 解决方案5-残差结构

    残差结构说起残差的话,不得不提这篇论文了:Deep Residual Learning for Image Recognition,关于这篇论文的解读,可以参考知乎链接:https://zhuanlan.zhihu.com/p/31852747这里只简单介绍残差如何解决梯度的问题。 
    事实上,就是残差网络的出现导致了image net比赛的终结,自从残差提出后,几乎所有的深度网络都离不开残差的身影,相比较之前的几层,几十层的深度网络,在残差网络面前都不值一提,残差可以很轻松的构建几百层,一千多层的网络而不用担心梯度消失过快的问题,原因就在于残差的捷径(shortcut)部分,其中残差单元如下图所示: 
    这里写图片描述 
    相比较于以前网络的直来直去结构,残差中有很多这样的跨层连接结构,这样的结构在反向传播中具有很大的好处,见下式: 
    这里写图片描述 
    式子的第一个因子 lossxL∂loss∂xL 表示的损失函数到达 L 的梯度,小括号中的1表明短路机制可以无损地传播梯度,而另外一项残差梯度则需要经过带有weights的层,梯度不是直接传递过来的。残差梯度不会那么巧全为-1,而且就算其比较小,有1的存在也不会导致梯度消失。所以残差学习会更容易。

    注:上面的推导并不是严格的证明。

    2.6 解决方案6-LSTM

    LSTM全称是长短期记忆网络(long-short term memory networks),是不那么容易发生梯度消失的,主要原因在于LSTM内部复杂的“门”(gates),如下图,LSTM通过它内部的“门”可以接下来更新的时候“记住”前几次训练的”残留记忆“,因此,经常用于生成文本中。目前也有基于CNN的LSTM,感兴趣的可以尝试一下。

    这里写图片描述

    参考资料:

    1.《Neural networks and deep learning》 
    2.《机器学习》周志华 
    3. https://www.cnblogs.com/willnote/p/6912798.html 
    4. https://www.zhihu.com/question/38102762 
    5. http://www.jianshu.com/p/9dc9f41f0b29

    展开全文
  • 梯度消失和梯度爆炸原因及其解决方案1 梯度消失和梯度爆炸原因及其解决方案2
  • 一、为什么会产生梯度消失和梯度爆炸? 目前优化神经网络的方法都是基于BP,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。其中将误差从末层往前传递的过程需要链式法则(Chain ...
  • 一般在深层神经网络中,我们需要预防梯度爆炸和梯度消失的情况。 梯度消失(gradient vanishing problem)和梯度爆炸(gradient exploding problem)一般随着网络层数的增加会变得越来越明显。 例如下面所示的含有三...
  • 梯度不稳定概念和解决方法梯度消失和梯度爆炸问题概念原理详解解决方法更改激活函数(Relu、Leaky-Relu、P-Relu等)权重初始化加入BN层(Batch Normalization)梯度剪切、权重正则(针对梯度爆炸)使用预训练模型...
  • 梯度消失、爆炸原因及其解决方法

    万次阅读 多人点赞 2019-04-22 17:23:04
    1、梯度消失与梯度爆炸问题简述 层数比较多的神经网络模型在使用梯度下降法对误差进行反向传播时会出现梯度消失和梯度爆炸问题。梯度消失问题和梯度爆炸问题一般会随着网络层数的增加变得越来越明显。 例如,对于...
  • 梯度消失、梯度爆炸及其解决方法

    千次阅读 2018-05-02 12:55:51
    本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。 其中,梯度消失...
  • 1、梯度消失与梯度爆炸问题简述         层数比较多的神经网络模型在使用梯度下降法对误差进行反向传播时会出现梯度消失和梯度爆炸问题。梯度消失问题和梯度爆炸问题一般会随着网络层数的增加变...
  • 本文简要介绍梯度消失 (gradient vanishing) 和梯度爆炸 (gradient exploding) 问题,并给出一些可行的解决方法。 神经网络在更新参数的过程中,使用反向传播 (Backpropagation) 算法求得各层网络的梯度,可以看作是...
  • 一、引入:梯度更新规则目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过梯度反向传播的方式,更新优化深度网络的权值。这样做是有一定原因的,首先,...二、梯度消失、爆炸的原因下图...
  • 详解机器学习中的梯度消失、爆炸原因及其解决方法前言本文主要深入介绍深度学习中的梯度消失和梯度爆炸的问题以及解决方案。本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍...
  • 今天就让我们一起来学习一下梯度消失与梯度爆炸的概念、产生原因以及该如何解决。目录1.梯度消失与梯度爆炸的概念2.梯度消失与梯度爆炸的产生原因3.梯度消失与梯度爆炸的解决方案首先让我们先来了解一个概念:什么是...
  • batch-normalization用在激活函数前的那一层,作用是调整该层均值和方差(一般是均值为0,方差为1),可以有效减少梯度消失问题。 使用tensorflow的实现过程: #模拟一个tensor(CNN的tensor是四维,这里做了简化) ...
  • 1.梯度消失和爆炸产生的原因: a)从网络深度来分析: 在反向传播过程中需要对激活han函数进行求导,如果导数大于1,那么随着网络层数的增加梯度更新将会朝着指数爆炸的方式增加这就是梯度爆炸。同样如果导数小于1...
  • 在学习了解了深度学习中梯度消失和梯度爆炸的问题以及一些解决方法后想通过写一篇文章作为总结巩固。 梯度消失、爆炸的原因梯度消失和梯度爆炸可以看作是由于某种原因使得在优化过程中梯度变化到一个极端的值(很...
  • 本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。 其中,梯度消失...
  • 本文分为三部分,第一部分主要直观的介绍深度学习中为什么使用梯度更新,第二部分主要介绍深度学习中梯度消失及爆炸的原因,第三部分对提出梯度消失及爆炸的解决方案。有基础的同鞋可以跳着阅读。其中,梯度消失...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,036
精华内容 8,814
关键字:

梯度消失的原因及解决方法