声明:文章仅作知识整理、分享,如有侵权请联系作者删除博文,谢谢!
梯度消失爆炸的解决方案主要包括以下几个部分。
- 预训练加微调
- 梯度剪切、权重正则(针对梯度爆炸)
- 使用不同的激活函数
- 使用batchnorm
- 使用残差结构
此方法来自Hinton在2006年发表的一篇论文,Hinton为了解决梯度的问题,提出采取无监督逐层训练方法,其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。
Hinton在训练深度信念网络(Deep Belief Networks中,使用了这个方法,在各层预训练完成后,再利用BP算法对整个网络进行训练。此思想相当于是先寻找局部最优,然后整合起来寻找全局最优,此方法有一定的好处,但是目前应用的不是很多了。
梯度剪切,梯度剪切这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。
注:在WGAN中也有梯度剪切限制操作,但是和这个是不一样的,WGAN限制梯度更新信息是为了保证lipchitz条件。
权重正则化,另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)比较常见的是l1正则,和l2正则,在各个深度框架中都有相应的API可以使用正则化,比如在tensorflow中,若搭建网络的时候已经设置了正则化参数,则调用以下代码可以直接计算出正则损失:
regularization_loss = tf.add_n(tf.losses.get_regularization_losses(scope='my_resnet_50'))
如果没有设置初始化参数,也可以使用以下代码计算l2正则损失:
l2_loss = tf.add_n([tf.nn.l2_loss(var) forvarin tf.trainable_variables() if'weights'invar.name])
正则化是通过对网络权重做正则限制过拟合,仔细看正则项在损失函数的形式:
其中,α是指正则项系数,因此,如果发生梯度爆炸,权值的范数就会变的非常大,通过正则化项,可以部分限制梯度爆炸的发生。
注:事实上,在深度神经网络中,往往是梯度消失出现的更多一些。
Relu思想也很简单,如果激活函数的导数为1,那么就不存在梯度消失爆炸的问题了,每层的网络都可以得到相同的更新速度,relu就这样应运而生。先看一下relu的数学表达式:
其函数图像:
从上图中,我们可以很容易看出,relu函数的导数在正数部分是恒等于1的,因此在深层网络中使用relu激活函数就不会导致梯度消失和爆炸的问题。
relu的主要贡献在于:
1)解决了梯度消失、爆炸的问题;
2)计算方便,计算速度快;
3)加速了网络的训练。
同时也存在一些缺点:
1)由于负数部分恒为0,会导致一些神经元无法激活(可通过设置小学习率部分解决);
2)输出不是以0为中心的。
尽管relu也有缺点,但是仍然是目前使用最多的激活函数。
leakrelu就是为了解决relu的0区间带来的影响,其数学表达为:
,其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来。
leakrelu解决了0区间带来的影响,而且包含了relu的所有优点。
elu激活函数也是为了解决relu的0区间带来的影响,其数学表达为:
其函数及其导数数学形式为:
但是elu相对于leakrelu来说,计算要更耗时间一些。
使用tanh作为损失函数,它的导数图如下,可以看出,tanh比sigmoid要好一些,但是它的倒数仍然是小于1的。tanh数学表达为:
Batchnorm是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batchnorm本质上是解决反向传播过程中的梯度问题。batchnorm全名是batch normalization,简称BN,即批规范化,通过规范化操作将输出信号x规范化保证网络的稳定性。具体的batchnorm原理非常复杂,在这里不做详细展开,此部分大概讲一下batchnorm解决梯度的问题上。具体来说就是反向传播中,经过每一层的梯度会乘以该层的权重。
残差结构说起残差的话,不得不提这篇论文了:Deep Residual Learning for Image Recognition,关于这篇论文的解读,可以参考知乎链接:https://zhuanlan.zhihu.com/p/31852747这里只简单介绍残差如何解决梯度的问题。
事实上,就是残差网络的出现导致了image net比赛的终结,自从残差提出后,几乎所有的深度网络都离不开残差的身影,相比较之前的几层,几十层的深度网络,在残差网络面前都不值一提,残差可以很轻松的构建几百层,一千多层的网络而不用担心梯度消失过快的问题,原因就在于残差的捷径(shortcut)部分,其中残差单元如下图所示:
相比较于以前网络的直来直去结构,残差中有很多这样的跨层连接结构,这样的结构在反向传播中具有很大的好处,见下式:
式子的第一个因子 表示的损失函数到达 L 的梯度,小括号中的1表明短路机制可以无损地传播梯度,而另外一项残差梯度则需要经过带有weights的层,梯度不是直接传递过来的。残差梯度不会那么巧全为-1,而且就算其比较小,有1的存在也不会导致梯度消失。所以残差学习会更容易。
注:上面的推导并不是严格的证明。
参考文章:
https://blog.csdn.net/qq_25737169/article/details/78847691
https://www.cnblogs.com/wangguchangqing/p/10191266.html
https://zhuanlan.zhihu.com/p/113112455
https://zhuanlan.zhihu.com/p/72589432