ResNet 学习笔记

ResNet


出自论文Deep Residual Learning for Image Recognition


1.提出背景


1. 梯度爆炸/消失问题(这篇博客讲的很好)
2. 退化问题(随着网络深度增加,准确率达到饱和,然后迅速下降)
3. 为了使网络能够有更深的深度

2.什么是残差函数?


我们使用一般网络拟合的是h(x),使得输入x,h(x)能够得到正确的解来帮助我们预测分类
而在ResNet中引入了残差函数f(x)=h(x)-x(即目标值与输入值的偏差),通过训练拟合f(x),进而由f(x)+x得到h(x)

使用残差函数的好处有哪些呢?我的理解有以下几点(仅个人理解,如有错误请指出~)

  • 解决了退化问题同时很好的避免(或者只能说是减少?)了梯度爆炸/消失。ResNet的出发点并不是为了解决梯度爆炸/消失问题,达到这种效果纯粹是无意之举,关于原因的话,我阅读了大量的博客和解析,他们用公式的解释方法我并不是很理解。
  • 首先为什么解决了退化问题。当网络达到一定深度,若网络已经最优化,那么当继续增加网络时,f(x)将被push为0,h(x)变为恒等映射,那么对于整个网络来说,深度的增加也并不会对网络的performance带来太大的影响了。那么,我的理解是,梯度爆炸/消失的原因是随着深度增加,梯度的同向变化传递所导致的(如对每个单元选择同样的**函数,导数同时大于1或小于1,分别对应梯度爆炸和梯度消失,因此最简单的解决方法是使用ReLU**函数,而ResNet也同样选择了ReLU作为**函数),在ResNet中随着网络深度的增加,后续的网络由于采用恒等映射,因此并不会继续传递这种变化,从而避免了梯度爆炸/消失。(同样的原因,也有学者diss ResNet并没有真正的增加深度,只是使网络退化为了浅层网络)
  • 进而,由于恒等映射的学习比一般的线性映射要简单的多,所以训练速度也相对同样的深层网络来说使比较快的。
  • 同时,网络在深层如果真正学习到了一些东西,而不是简单的恒等映射,那么将会有更好的performance
  • 此外,使用残差函数f(x)对映射后的输出更敏感,如由h(x)=f(x)+x=5.1,h1(x)=f(x)+x=5.2,x=5,f(x)=0.1->f(x)=0.2那么变化率由0.1/5放大至0.1/0.1=100%.

3.Residual Block


在实现网络时,使用了Residual Block来拟合h(x)=f(x)+x,整个网络由多个包含相同形式的Residual Blocks(每一层的第一个Block的第一个卷积层的stride可能和其他的不同)的layers堆叠形成

ResNet 学习笔记

Residual Block 图示

我们称图中的弧线为short connection,随着网络不断优化达到最优时,f(x)被push为0,只剩下short connection,这时,Block表示一个恒等映射。

 

ResNet 学习笔记
吴恩达的.deaplearning课程中对Residual Block的数学解释


这里的每一个节点都执行了线性函数和ReLU**函数。所以插入的时机是在线性变换之后,ReLU**之前

 

ResNet 学习笔记
两种不同Residual Block 图示


左边的这种结构一般用于34层以上的网络,右边的结构用于于深层网络。
其中右侧的第一个1x1卷积用于降维,第三个卷积恢复维度,以减少参数量和计算。

那么如果f(x)维度和x不同该怎么相加?
这种情况一般发生在两个layer的交接处,即每个layer的第一个block,特征图像的尺寸和通道数发生了变化。为解决这个问题,论文中作者提出使用矩阵Ws左乘x后,再与f(x)相加,说白了,在实现的时候就是通过卷积达到同维度(我在实现CIFAR10的ResNet时使用一个1x1的卷积核,stride=2,即可实现特征图像尺寸减半同时通道数翻倍)

 

Residual Network

 

ResNet 学习笔记
ResNet网络构造

ResNet 学习笔记
.deeplearning课程对ResNet的解释


该图表示ResNet在Plain Network上增加了short connetion,可以看出ResNet的训练误差并没有发生退化。
网络以average pooling -> 1000-d fc -> softmax结束

Details
- 图像水平翻转,减去均值,224x224随机裁剪
- 每个卷积后和**前采用BN
- batchsize =256,lr = 0.1 当误差稳定时更新lr = lr*0.1,SGD优化函数,weight_decay=0.0001,momentum=0.9,
- 不采用dropout

 

用于CIFAR10的ResNet结构


CIFAR10的图像均为32x32,论文中ResNet的网络结构设置如下:

layer name Input Size Output Size Block & Kernel Setting
conv1 32x32,3(channels)  32x32,16 {3x3,16} x 1 , s=1
conv2 32x32,16  32x32,16 {3x3,16} x n , 首个block的首层s=1
conv3 32x32,16  16x16, 32 {3x3,32} x n , 首个block的首层s=2
conv4 16x16,32   8x8,64 {3x3,64} x n , 首个block的首层s=2
average pool & 10d-fc  8x8,64   1x1,64 pool kernerl:{1x1,64} ; linear(64,10)

其中n = {3,5,7,9},表示每个层中block的个数,分别形成Res20,32,44,56的网络
(depth= 6n+2)

具体实现请见我的github