关于Resnet残差网络的一些理解

注:整理自各个博客,并且添加个人理解
随着卷积神经网络的发展和普及,网络深度和架构研究早已经成为人们常见的问题,所以,现在卷积神经网络的趋势发展趋势就是:足够深、足够广。足够深就是网络层数足够深,足够广就意味着不能从传统尺度来解决问题,而应该是多尺度,也就是multi-scale。
但是随着网络的深入,一些经典的问题也就随之出现,例如梯度弥散和梯度爆炸。这两种问题都是由于神经网络的特殊结构和特殊求参数方法造成的,也就是链式求导的间接产物。

梯度弥散:当使用反向传播方法计算导数的时候,随着网络的深度的增加,反向传播的梯度(从输出层到网络的最初几层)的幅度值会急剧地减小。结果就造成了整体的损失函数相对于最初几层的权重的导数非常小。这样,当使用梯度下降法的时候,最初几层的权重变化非常缓慢,以至于它们不能够从样本中进行有效的学习。这种问题通常被称为“梯度的弥散”。
梯度爆炸:差梯度在网络训练时被用来得到网络参数更新的方向和幅度,进而在正确的方向上以合适的幅度更新网络参数。在深层网络或递归神经网络中,误差梯度在更新中累积得到一个非常大的梯度,这样的梯度会大幅度更新网络参数,进而导致网络不稳定。在极端情况下,权重的值变得特别大,以至于结果会溢出(NaN值,无穷与非数值)。当梯度爆炸发生时,网络层之间反复乘以大于1.0的梯度值使得梯度值成倍增长。

这两个不良影响也常常困扰着卷积神经网络的设计者和使用者,也成为人们不得不思考的问题。但是所幸的是,一些网络的出现很好的解决了这些问题。最近学习的Resnet就有效的解决了这个问题。
Resnet在2015年提出之后,立马获得了当年的Image图像比赛第一名,并且准确率奇高。

关于Resnet残差网络的一些理解

最初Resnet的提出目的并不是为了解决梯度弥散,有效的消除梯度弥散可以说是无心之举。在当前的背景下,卷积神经网络提出之后,深度成为人们要追求的目标。但是随着层数增加,就出现了学习退化的问题。

关于Resnet残差网络的一些理解

本来随着网络深度增加准确率越来越好的网络出现了诡异的变化,随着后续的发现,发现问题主要来自于两个,第一个是恒等函数的问题,第二个就是来自于梯度爆炸和梯度弥散的问题。
深层网络应该优于浅层网络,可以说是所有人都认同的的事实,但是随着网络的加深,一些层通常是没有必要出现的,如果训练好参数随着后面的网络扰动,会被类似于白噪音的问题使参数重新偏移变差。因此,人们想到了恒等函数,也就是说,直接在后面几层使得F(x)=x,来进行等效传递。但是问题是,等效传递并不容易,更不用说Sigmoid函数等特殊函数曲线的存在。因此,利用残差块,可以完美的解决这个问题。

关于Resnet残差网络的一些理解

对于输出函数变为了H(x),并且H(x)=F(x)+x。此时,为了使得进行恒等变换,只用使F(x)足够小就可以了,此时,输出也就近似变成了H(x)=x。也就是说,假如优化目标函数是逼近一个恒等映射, 而不是0映射,那么学习找到对恒等映射的扰动会比重新学习一个映射函数要容易。
同时,残差网络也很好的解决了梯度下降中的梯度弥散的问题。当我们进行链式求导,来求得某个参数的偏导数的时候,在深层网络总会遇到偏导结果较小,从而导致参数更新过小的情况。
例如:

关于Resnet残差网络的一些理解

当网络足够深的时候,会出一下Loss函数:

从而使得偏导结果:

关于Resnet残差网络的一些理解

非常小,相当于原地踏步。因此,当进行残差块的增添之后,偏导结果如下所示:

关于Resnet残差网络的一些理解
此时,就不用再担心梯度下降的相关问题。并且与此同时,函数的拟合F(x)=0会比F(x)=x更加容易,后者对参数的变化会更加敏感。总的来说,残差学习再浅层的时候,学习是线性叠加,到深层后,F(x)会趋于零,从而使得残差块编程恒等映射,从而避免层数增加影响学习结果的情况。

  1. 经典Resnet网络

    目前最主经典的残差网络莫过于Resnet v2。由于ResNet的结构有别于传统的卷积结构,使得信号的前向传播和梯度的反向传播变得更复杂。为了稳定训练时信号的前向传播和梯度的反向传播,从ResNet开始,网络普遍使用Batch Normalization,因此,Resnet v2也采用了BN算法。
    BN算法:我们在训练深度学习模型的时候,经常会采用随机梯度下降的方式,每次随机选取训练数据中的一个小部分进行求训练模型,经过多步迭代后会逐渐手链,模型的loss会逐渐趋于稳定,但由于只是一部分数据进行训练,还是会有一定起伏,一般训练误差如下图所示。

关于Resnet残差网络的一些理解

随着神经网络的深度增加,也会出现梯度扩散和梯度爆炸的问题。

这里简单解释一下梯度扩散和梯度爆炸,随着神经网络深度增加,每层计算误差都会逐步缩小,这个主要跟我们选的激活函数有关,链式法则相乘之后,输出层的很大的误差,对前几层带来的影响会变得非常小,此时前几层的梯度修正会非常小,梯度会趋于零,使得训练无效,这就是梯度消失gradient vanish,相反的则是梯度爆炸gradient explode。

改变激活函数,比如说ReLu可以较好地避免梯度的问题,而这两篇作者提出的batch normalization也可以解决这个问题。

BN的主要思想就是对每层输入数据做标准化,使其以较小的方差集中在均值附近,具体方法如下图:

关于Resnet残差网络的一些理解

在正向传播的时候对输入数据进行标准化,求随机梯度下降的一个batch进行正规化可以大大减小计算量,同时作者为了避免数据整体影响,在最后还进行了一个规模和位置的线性转换,用以尽量保留原数据的方差与均值信息。

相关推荐