背景
Resent可以被视作卷积神经网络的发展里程碑,它的出现解决了更深的网络训练带来的退化问题,使得卷积神经网络在各种计算机视觉任务上的表现更加优秀,对计算机视觉的发展做出了很重要的贡献。其中的亮点就是shortCut,走捷径这种方式并不是何凯明第一个发现,但是他在前人的基础上做了很多的实验,证明了残差能有效解决深度网络的退化问题。在此之后还有DenseNet的出现,也是残差网络的另一种形式
这个系列讲述resnet到densenet的发展过程,算是对两篇论文的解读吧。这一篇博客单单讲下resnet论文的要点。
我个人认为resnet的亮点如下:
- 引入残差结构,大胆设想残差映射比普通的堆叠层的映射更容易优化
- 使用zero padding和1x1投影(projection)的方式解决分辨率和深度不一样的特征图的相加问题
这篇博客就按照两个亮点分为两部分。
残差结构
何凯明在论文的Introduction中提了一个问题,是否网络学习得更好就像堆叠更多层那样容易呢?当然不是了,实验证明网络会出现退化现象,即更深的网络收敛时的loss数值反而比更小的网络大,精度也不如小网络。
作者开始思考,想让网络更深,一种很简单的方式就是让层与层之间进行恒等映射,可能这样学不到什么东西,但确实能加深网络的层数,那么用什么可以描述网络进行了恒等映射呢?当然就是残差的形式。我们看上图,x是输入,经过两个映射得到F(x),最终的输出是
relu(F(x)+x)relu(F(x)+x)relu(F(x)+x)
那么如果F(x)为0,输出就是relu(x),因为x本身就经过上一层的relu了,所以输出和x相等,这样就实现了恒等映射。说明残差是可以描述网络是否进行恒等映射的。作者也设想残差映射的优化要比普通的学习映射要容易。
其实对残差进行优化在很多领域都有更好的效果,我个人是自动化专业的,回想起本科学习的PID控制,就是对输出和输入的偏差做文章,具体是啥我忘了。
还有就是DnCNN,一个去除高斯噪声的网络,网络输出并不是一张去噪之后的图,而是学习到噪声的分布。所要优化的对象就是加噪之后的图像与原始图像之间的差的分布。
还有BEGAN,损失函数中能体现优化残差。生成的图像经过auto encoder得到的特征和生成图像的分布之差,如果能和真实图像经过auto encoder得到的特征和真实图像的分布之差,这两个差的分布如果很相似,就能认为生成图像已经很符合真实图像了。
网络的结构
这里以resNet34举例。
结构图很清晰,仅仅有一个地方需要注意。x的路径分为实线和虚线。实线意味着x不进行任何处理,直接与F(X)相加,对应元素相加,因为此时F(X)的分辨率和深度都是x是一样的。但是虚线部分就不一样了。
我们看有虚线部分对应的残差块,第一个卷积层的stride是2,那个/2的意思就是stride是2;同时注意到深度也发生了变换,channel数目增加一倍(扩大两倍)。这样F(X)的分辨率比x小一半,厚度比x大一倍。
针对这种情况,作者提出两种办法,
- 对于增加了维度的部分,用0填充,这样是没有额外参数的
- 用1x1的卷积核增加维度
- 以上两种办法都是stride为2(解决不同分辨率相加的问题),论文中没有提第一种方法具体是如何操作的,但我想,既然是没有额外的参数,想必是经过了一个stride为2的池化层了吧。虚线部分的torchvision中实现方法是步长为2的卷积和batchnorm,没有激活函数。
更深的瓶颈结构
resnet有几种结构,更深的三种是50,101,152。它们都使用了瓶颈结构代替残差块。
先来看看瓶颈块。
左边是我们之前提到的残差块,右边则是瓶颈结构了。之所以称为瓶颈结构,因为它两端深度(channel)大,中间小,就像是一个瓶口的颈部。
那为什么要提出这种结构呢?其实主要是解决在更加深的残差网络101或者152中,参数数目的问题。我们从resnet34中看到,特征图的厚度是逐渐加深的,在resnent34中最后几层卷积是512的厚度,那到了resnet152,岂不是上万的厚度,带来的参数数目是巨大的。所以我们看右边的图,输入先经过一个1x1的卷积核降维,将一个256维的输入降到了64维,再使用3x3的卷积提特征,再用1x1的卷积核升维。这样就到了减少参数数目的目的。
这一系列的下一篇将会讲述DenseNet。
Update in 2019.3.9
今天看注意力机制的时候突然想明白了残差的深层含义,即为什么残差能解决退化现象。
设F为一个残差单元,x是上一个残差单元的输出,代表提取的特征,残差单元的输出为F(x)+x。要知道反向传播是损失函数代表的空间中往更优的方向走。每一次迭代理论上说参数应该更新为满足优化损失函数的数值。我们就当做这个设想成立。现在设想残差单元的输出F(x)+x这个特征比x要差,那么反向传播时,F中的参数该往什么方向上更新呢,当然是往数值更小的方向更新,尽量使得F(X)为0或者近似0。因为这样能保证F(x)+x至少不会比x更差。如果F(x)为0了,或者近似0,说明当前残差单元进行了恒等映射,所得到的特征和上一个单元的特征一样,那么可以说当前单元得到的特征至少不会比上一层的特征差。又因为残差又不可能为0,其数值是往优化损失函数的方向上更新的,所以特征会越来越好。
Update in 2019.5.2
关于很多人说,resnet是通过解决梯度消失问题来解决深度网络的退化问题的,这其实是错误的
来看原文
34层的普通网络的错误率比34层的残差网络高。作者验证了34层的普通网络的梯度,反向传播的梯度是健康的,这是由于BN的存在,所以不要再说resnet是通过解决梯度消失问题来解决深度网络的退化问题的了。
今天看到一篇SR的survey,就是这么说的。哎