GoogLeNet的提出主要就是为了应对梯度消失以及梯度爆炸,本文就是讲解下什么是梯度消失,以及梯度爆炸。
梯度消失是传统神经网络训练中非常致命的问题,其本质是由于链式法则的乘法特性导致的。比如之前神经网络中最流行的激活函数之一 sigmoid 其表达式如下:
这个函数的导数画出来,如图:
对于Sigmoid,导数的最大值在输入为0处,值为0.25.考虑一个激活函数都是Sigmoid的多层神经网络,则梯度向后传导时,没经过一个Sigmoid就需要乘以一个小于0.25的梯度。而每乘以一个小于0.25的梯度,则梯度的值又变得更小一些。况且在优化的过程中,每个激活层输入都在0附近的概率非常的低。也就是说随着层数的加深,梯度的衰减会非常的大,迅速接近0,这就是梯度消失的现象。
为什么我是使用梯度下降来优化神经网络参数
反向传播(用于优化网络参数):根据损失函数计算的误差通过反向传播的方式,指导深度网络参数更新优化
采取反向传播的原因:首先,深层网络由许多线性层和非线性层堆叠而来,每一层非线性层都可以视为是一个非线性函数(非线性来自于非线性激活函数),因此整个深度网络可以视为是一个复合的非线性多元函数。
我们最终的目的是希望这个非线性函数很好的完成输入到输出之间的映射,也就是找到让损失函数取得极小值。所以最终的问题就变成了一个寻找函数最小值的问题,在数学上,很自然的就会想到使用梯度下降来解决。
产生的原因
以最简单的网络结构为例,加入有三个隐藏层,每层的神经元个数都是1,且对应的非线性函数为(其中sigmoid是激活函数)
激活函数现在我们更新参数,那么我们就要求出损失函数对参数的导数,根据链式法则,可以写成下面的样子
而对于激活函数,之前一直使用Sigmoid函数,其函数图像成一个S型,如下所示,它会将正无穷到负无穷的数映射到0~1之间:
sigmoid函数当我们对其求导后
由此可以得到他的导数图像
导数图像
我们初始化后的网络权重通常都是小于1的,因此,当层数增多时,小于0的值不断相乘,最后就导致梯度消失的情况出现。同理,梯度爆炸的问题也就很明显了,就是当权重过于大,导致,最后大于1的值不断相乘,就会产生梯度爆炸的现象。
解决办法
梯度消失和梯度爆炸本质上是一样的,都是因为网络层数太深而引发的梯度反向传播中的连乘效应。
-
更换激活函数 使用relu、leakyrelu等激活函数
relu的导数始终都为1
LeakyReLu:包含了ReLu的几乎所有有点,同时解决了ReLu中0区间带来的影响 -
BatchNormalization
-
使用ResNet的残差结构
-
使用LSTM的结构
LSTM不太容易发生梯度消失,主要是因为其复杂的门结构 -
梯度剪切、正则
这个方案主要是针对梯度爆炸提出的,其思想是设值一个剪切阈值,如果更新梯度时,梯度超过了这个阈值,那么就将其强制限制在这个范围之内。这样可以防止梯度爆炸。另一种防止梯度爆炸的手段是采用权重正则化,正则化主要是通过对网络权重做正则来限制过拟合。
网友评论