深度学习_经典网络_ResNet详解及常见问题总结
一.的介绍及核心思想
2015年,大大吸引了人们的眼球。实际上,早在分类竞赛中,取得胜利,深度残差网络(Deep )就成为过去几年中计算机视觉和深度学习领域最具突破性的工作。使得训练深达数百甚至数千层的网络成为可能,而且性能仍然优异。
由于其表征能力强,在图像分类任务之外的许多计算机视觉应用上也取得了巨大的性能提升,例如目标检测等等。
的核心思想:
根据泛逼近定理( ),如果给定足够的容量,一个单层的前向网络就足够表达任何函数。但是,这个层可能是非常大的,而且网络容易过拟合,因此,研究界有一个共同的趋势,就是网络结构越来越深。
从的提出以来,state-of-the-art的CNN经典模型都是越来越深。虽然只有5层卷积层,但后来的VGG网络和分别由19层和22层。
但是,如果只是简单地将层堆叠在一起,增加网络的深度并不会起太大的作用。这是由于训练时会存在梯度消失( )问题,这使得深层网络难以训练。下图展示了网络深度大的增加导致性能迅速下降:
为什么网络层数越深超过一定界限后网络效果就变得不好呢? 因为误差是普遍存在的,无论是训练集还是测试集,随着误差的传播,越往后误差越大,所以越深的网络效果可能并不会很好。按照信息熵的传播原理,信息在传播的过程中是有损失的,所以越深的网络能够学到的信息就越少,所以就更难训练。神经网络在求梯度的时候有个链式法则,求解梯度时会有累乘造成了梯度弥散或者爆炸。
基于上述存在的问题,第一次提出了残差结构,主要用于解决上面提到的两个问题:
梯度消失的问题。随着网络深度增加,性能没有提升反而下降的问题。
如下图所示,我们引入一个“恒等捷径连接( )”,本来要学习 F ( x ) F(x) F(x),现在转换为 F ( x ) + x F(x) + x F(x)+x,二者效果相同,但是优化难度下降,并且因为多了一个x,使得求导时总有1,避免了梯度消失的问题。
我们结合上图进一步解释残差指的是什么:
提出了两种:
第一种是 ,指的是上图中的“弯弯曲曲的曲线”。第二种是 ,指的是除了“弯弯曲曲的曲线”的部分,所以最后的输出是 H ( x ) = y = F ( x ) + x H(x) = y = F(x) + x H(x)=y=F(x)+x。
其中 是 x x x, 是 y − x y - x y−x,即F(x)。(我想到了差分放大器)
为什么加入残差模块会有效果呢?
假设:如果不使用残差模块,输出为 F 1 ( x ) = 5.1 F_{1} (x)= 5.1 F1(x)=5.1,期望输出为 H 1 ( x ) = 5 H_{1} (x)= 5 H1(x)=5,如果想要学习H函数,使得 F 1 ( x ) = H 1 ( x ) = 5 F_{1} (x) = H_{1} (x) = 5 F1(x)=H1(x)=5,这个变化率比较低,学习起来是比较困难的。
但是如果设计为 H 1 ( x ) = F 1 ( x ) + 5 = 5.1 H_{1} (x) = F_{1} (x) + 5 = 5.1 H1(x)=F1(x)+5=5.1,进行一种拆分,使得 F 1 ( x ) = 0.1 F_{1} (x)= 0.1 F1(x)=0.1,那么学习目标就变为让 F 1 ( x ) = 0 F_{1} (x)= 0 F1(x)=0,一个映射函数学习使得它输出由0.1变为0,这个是比较简单的。也就是说引入残差模块后的映射对输出变化更加敏感了。
进一步理解:如果 F 1 ( x ) = 5.1 F_{1} (x)= 5.1 F1(x)=5.1,现在继续训练模型,使得映射函数 F 1 ( x ) = 5 F_{1} (x)= 5 F1(x)=5。变化率为: ( 5.1 − 5 ) / 5.1 = 0.02 (5.1 - 5) / 5.1 = 0.02 (5.1−5)/5.1=0.02,如果不用残差模块的话可能要把学习率从0.01设置为0.。层数少还能对付,一旦层数加深的话可能就不太好使了。
这时如果使用残差模块,也就是 F 1 ( x ) = 0.1 F_{1} (x)= 0.1 F1(x)=0.1变化为 F 1 ( x ) = 0 F_{1} (x)= 0 F1(x)=0。这个变化率增加了100%。明显这样的话对参数权重的调整作用更大。
进一步拓展残差结构:
接下来我们详细解释一下上图的两个结构设计。左边的结构针对于,一般称整个结构为一个“ block”。右边的结构针对/101/152,一般称为“ ”,这个结构的设计是为了降低参数的数目,第一个 1 × 1 1\ 1×1的卷积把256维降到64维,然后再最后通过 1 × 1 1\ 1×1卷积恢复,整体上用的参数数目: 1 × 1 × 256 × 64 + 3 × 3 × 64 × 256 + 1 × 1 × 64 × 256 = 69632 1\\times 256\times 64 + 3\times 3\times 64\times 256 + 1\times 1\times 64\times 256 = 69632 1×1×256×64+3×3×64×256+1×1×64×256=69632,而不使用的话就是两个 3 × 3 × 256 3\times 3\times 256 3×3×256的卷积,参数数目: 3 × 3 × 256 × 256 × 2 = 3\times 3\times 256\times 256\times 2 = 3×3×256×256×2=,差了16.94倍。
对于常规的,可以用于34层或者更少的网络中,对于 的通常用于更深的如101这样的网络中,目的是减少计算和参数量。
二.网络结构
我们先看一看VGG网络、Plain网络和残差网络的结构比较:
由上图可知,有一些 是实线的,有一些是虚线的,为什么要这样呢?
因为可能会有F(x)和x的个数不同的情况,所以要分两种情况讨论。
实线的情况是两者的数目相同,采用的计算方式是 H ( x ) = y = F ( x ) + x H(x) = y = F(x) + x H(x)=y=F(x)+x。
虚线的情况是两者的数目不同,比如(64和128),所以采用的计算方式是 H ( x ) = y = F ( x ) + W x H(x) = y = F(x) + Wx H(x)=y=F(x)+Wx。其中W是卷积操作,用来调整的维度。
论文中的网络结构:
比较经典的是,和。下图给出详细的结构:
我们举上图为例子计算其层数:
首先有一个输入 7 × 7 × 152 7\times 7\times 152 7×7×152的卷积,然后经过 ( 3 + 4 + 23 + 3 ) = 33 (3 + 4 + 23 + 3)=33 (3+4+23+3)=33个 ,每一个有三层卷积,所以有 33 × 3 = 99 33\times 3 = 99 33×3=99层,99 + 最后的全连接层 + 一开始的输入卷积 = 101。
注意: 101层网络仅仅指卷积或者全连接层,而激活层或者层并没有计算在内。
我们还可以发现和唯一的区别是,差了6个,正好是51层。
三.相关公式理顺与梯度计算
首先根据上一节的介绍,残差单元可以表示为:
其中Xl和Xl+1分别表示的是第l个残差单元的输入和输出。F是残差函数,表示学习到的残差,而h(Xl) = Xl表示恒等映射,f是ReLU激活函数。基于上式,我们求得从浅层l到深层L的学习特征为:
利用链式规则,可以求得反向过程的梯度:
式子的第一个因式:loss/xL表示的是损失函数到达L的梯度,小括号中的1表明可以避免梯度消失问题,而另一项残差梯度需要经过带有W的层,梯度不是直接传递过来的。
四.试验结果:
如果网络已经到达最优化,继续加深网络, 将被push为0,只剩下 ,这样理论上网络一直处于最优状态,网络的性能也就不会随着深度增加而降低了。
五.基于的 R-CNN
论文中把当作 R-CNN的,取得了很好的效果,如下图所示:
那么其复合的网络结构是什么样子的呢?
上图展示了具体的架构,可以知道的最后的输出为RPN和RoI 共享的部分,而(共9层网络)都作用于RoI 之后的特征图 ( 14 × 14 × 1024 ) (14\times 14\times 1024) (14×14×1024),特征图的大小维度也刚好符合原本的中的输入。最后大家一定要记得接一个 ,得到 1 × 1 × 2048 1\times 1\times 2048 1×1×2048维特征,分别用于分类和框回归。
六.论文地址:
论文地址