ResNet(Residual Neural Network)由微软研究院的Kaiming He等4名华人提出,通过使用Residual Unit成功训练152层深的神经网络,在ILSVRC 2015比赛中获得了冠军,取得3.57%的top-5错误率,同时参数量却比VGGNet低,效果非常突出。
ResNet的结构可以极快地加速超深神经网络的训练,模型的准确率也有非常大的提升。Inception V4则是将Inception Module和ResNet相结合。可以看到ResNet是一个推广性非常好的网络结构,甚至可以直接应用到Inception Net中。
Forward:from shallow to deep
Alexnet的出现带火了深度学习,其最重要的特点为通过数据驱动让模型自动学习特征,省去了人工寻找特征的步骤。但不同的模型也找出不同质量的特征,特征的质量直接影响到分类结果的准确度,表达能力更强的特征也给模型带来更强的分类能力。因此,深度网络通过数据学习到表达能力更强的特征。
特征也可以根据复杂度和表示能力粗略的分为高中低三种种类,理论上讲越复杂的特征有越强的表征能力。在深度网络中,各个特征会不断的经过线性非线性的综合计算,越深的网络输出表示能力越强的特征。所以,网络的深度对于学习表达能力更强的特征至关重要,这一问题在VGGNet中得到很好体现。
深度模型中,每层的输出特征图的尺寸大都随着网络深度而变化,主要是高和宽越来越小,输出特征图的深度随着网络层数的深度而增加,这一设计符合Inception v3 paper中的原则,从另一方面讲,高和宽的减小有助于减小计算量,而特征图深度的增加则使每层输出中可用特征数量的增多。
Backward:the problem caused by increasing depth
增加深度带来的首个问题就是梯度爆炸/消散的问题,这是由于随着层数的增多,在网络中反向传播的梯度会随着连乘变得不稳定,变得特别大或者特别小。这其中经常出现的是梯度消散的问题。
为了克服梯度消散也想出了许多的解决办法,如使用BatchNorm,将激活函数换为ReLu,使用Xaiver初始化等,可以说梯度消散已经得到了很好的解决
增加深度的另一个问题就是网络的degradation问题,即随着深度的增加,网络的性能会越来越差,直接体现为在训练集上的准确率会下降,残差网络解决的就是这个问题,而且在这个问题解决之后,网络的深度上升了好几个量级。
-
上图是论文中随着网络深度的增加网络在CIFAR10-数据集上分类的训练集的错误率,可以看到如果我们直接堆叠卷积层,随着层数的增多,错误率有明显上升的趋势,其中最深的56层网络得到了最差的准确率,我们在VGG网络上验证了一下,对于CIFAR-10数据集在18层的VGG网络上耗费5分钟时间在网络训练充分的情况下得到了80%正确率,而34层的VGG模型花费8分钟得到了72%正确率,网络衰退问题确实存在。
-
训练集错误率的下降说明degredation的问题并不是过拟合所造成,具体原因论文中也只是说留待继续研究,在作者的另一篇论文《Identity Mappings in Deep Residual Networks》中证明了degradation(退化)的产生是由于优化性能不好,这说明越深的网络反向梯度越难传导。
Deep Residual Networks
我们可以设想一下,当我们直接对网络进行简单的堆叠到特别长,网络内部的特征在其中某一层已经达到了最佳的情况,这时候剩下层应该不对改特征做任何改变,自动学成**恒等映射(identity mapping) ** 的形式。也就是说,对一个特别深的深度网络而言,该网络的浅层形式的解空间应该是这个深度网络解空间的子集,换句话说,相对于浅层网络更深的网络至少不会有更差的效果,但是因为网络degradation的问题,这并不成立。
那么,我们退而求其次,已知有网络degradation的情况下,不求加深度能提高准确性,能不能至少让深度网络实现和浅层网络一样的性能,即让深度网络后面的层至少实现恒等映射的作用,根据这个想法,作者提出了residual模块来帮助网络实现恒等映射。
Residual Module
- 根据上图,copy一个浅层网络的输出加给深层的输出,这样当网络特征达到optimal的时候更深层恒等映射的任务就从原来堆叠的层中释放到新建的这个恒等映射关系中,而原来层中的任务就从恒等映射转为全0。
- F(x)=H(x)−x,x为浅层的输出,H(x)为深层的输出,F(x)为夹在二者中间的的两层代表的变换,当浅层的x代表的特征已经足够成熟,如果任何对于特征x的改变都会让loss变大的话,F(x)会自动趋向于学习成为0,x则从恒等映射的路径继续传递。这样就在不增加计算成本的情况下实现了一开始的目的:在前向过程中,当浅层的输出已经足够成熟(optimal),让深层网络后面的层能够实现恒等映射的作用。
- ResNet相当于将学习目标改变了,不再是学习一个完整的输出,只是输出和输入的差别,即残差
传统的卷积层或全连接层在信息传递时,或多或少会存在信息丢失、损耗等问题。ResNet在某种程度上解决了这个问题,通过直接将输入信息绕道传到输出,保护信息的完整性,整个网络则只需要学习输入、输出差别的那一部分,简化学习目标和难度。
在ResNet推出后不久,Google就借鉴了ResNet的精髓,提出了Inception V4和Inception-ResNet-V2,并通过融合这两个模型,在ILSVRC数据集上取得了惊人的3.08%的错误率。
反向的Residual Module
那么从另一个角度看,在反向传播中,residual模块会起到什么样的作用呢?
-
residual模块将输出分成F(x)+x两部分,其中F依然是x的函数,也就是说F实际上是对于x的补充,是对于x的fun-tuning,这样就把任务从根据x映射成一个新的y转为了根据x求x和y之间的差距,这明显是一个相对更加简单的任务,论文是这么写的,到底怎么简单的,我们来分析一下。
-
举个例子,假设不加residual模块的输出为h(x)。x=10,h(x)=11,h简化为线性运算Wh,Wh明显为1.1,加了redidual模块后,F(x)=1,H(x)=F(x)+x=11,F也简化为线性运算,对应的WF为0.1。当标签中的真实值为12,反向传播的损失为1,而对于F中的参数和h中参数回传的损失实际上是一样大的而且梯度都是x的值(h=wx对w求偏导),但是对于F的参数就从0.1到1.1扩大了十倍多,而h的参数是从1.1到2.1扩大不到2倍,因此redidual模块会明显减小模块中参数的值从而让网络中的参数对反向传导的损失值有更敏感的响应能力,虽然根本上没有解决回传的损失小得问题,但是却让参数减小,相对而言增加了回传损失的效果,也产生了一定的正则化作用。
-
其次,因为前向过程中有恒等映射的支路存在,因此在反向传播过程中梯度的传导也多了更简便的路径,仅仅经过一个relu就可以把梯度传达给上一个模块。
-
所谓反向传播就是网络输出一个值,然后与真实值做比较的到一个误差损失,同时将这个损失做差改变参数,返回的损失大小取决于原来的损失和梯度,既然目的是为了改变参数,而问题是改变参数的力度过小,则可以减小参数的值,使损失对参数改变的力度相对更大。
-
因此残差模块最重要的作用就是改变了前向和后向信息传递的方式从而很大程度上促进了网络的优化。
bottleneck
利用Inceptionv3提出的四个准则我们再用一下以改进residual模块,利用准则3,在空间聚合之前先进行降维不会发生信息丢失 ,所以这里也采用了同样的方法,加入1*1的卷积核用来增加非线性和减小输出的深度以减小计算成本,卷积完成之后再升维从而能够与输入进行相加。就得到了成为bottleneck的residual模块形式。图左为basic形式,右为bottleneck的形式。
原始:3x3x256->3x3x256x256
优化:1x1x256x64->3x3x64x64->1x1x64x256
ResNet残差网络的其他设计
- 全部采用3x3卷积核
- 卷积步长2取代池化
- 使用BN
- 取消了max池化,全连接、Dropout
152层的ResNet相比于其他网络有提高了一些精度,并且ResNet的参数量为1.1千万,VGG16参数数量为1.53千万,可见虽然ResNet深度增加了近十倍,但是参数量因为使用bottleneck模块反而更少。