0%

残差网络ResNet

简介

越深网络一定越好吗?

深层网络会遭遇退化问题(degradation): 随着网络层数的增加,精度会到达饱和区,而后迅速下降。

作者在CIFAR-10数据进行实验,采用3x3 卷积层的简单堆叠来测试网络深度的影响。
发现当层数增加到20层的时候网络进入饱和区(即使再增加网络的深度,精度也不会提高)。
不仅如此,继续增加深度还会导致模型退化,训练精度和测试精度迅速下降。
这说明当网络变得很深以后,深度网络就变得更加难以训练了。(注意:这不是过拟合。过拟合是训练误差小,测试误差大)

随着网络层级的不断增加,模型精度不断得到提升。
而当网络层级增加到一定的数目以后,

“Overly deep” plain nets have higher training error

【问题来了】为什么随着网络层级越深,训练误差越大了?

从原理上来说其实56层网络的解空间是包括了20层网络的解空间的。
换而言之也就是说,56层网络取得的性能应该大于等于20层网络的性能的。但是从训练的迭代过程来看,56层的网络无论从训练误差来看还是测试误差来看,误差都大于20层的网络(这也说明了为什么这不是过拟合现象,因为56层网络本身的训练误差都没有降下去)。导致这个原因就是虽然56层网络的解空间包含了20层网络的解空间,但是我们在训练网络用的是随机梯度下降策略,往往解到的不是全局最优解,而是局部的最优解,显而易见56层网络的解空间更加的复杂,所以导致使用随机梯度下降算法无法解到最优解

模型

如何又能加深网络层数、又能解决梯度消失问题、又能提升模型精度呢?

那么我们作这样一个假设:假设现有一个比较浅的网络(Shallow Net)已达到了饱和的准确率,这时在它后面再加上几个恒等映射层(Identity mapping,也即y=x,输出等于输入),这样就增加了网络的深度,并且起码误差不会增加,也即更深的网络不应该带来训练集上误差的上升。而这里提到的使用恒等映射直接将前一层输出传到后面的思想,便是著名深度残差网络ResNet的灵感来源。

这里没看懂。恒等映射层是 y=x, 还是y=f(x)+x ?

residual/shortcut connection

shortcut连接有多重形式

  • 恒等映射(Identity Mapping)
    • 无参
    • 有利于模型训练
  • 变换后的映射(Projection Shortcuts)
    • A: zero-padding shortcuts are used for increasing dimensions, and all shortcuts are parameterfree
    • B: projection shortcuts are used for increasing dimensions, and other
      shortcuts are identity; 论文推荐用这个策略?
    • C: all shortcuts are projections。

恒等映射

1
2
structure: basic-block
shortcut: Identity Mapping

Residual Learning

  • 普通网络中:
    $H(x)$ is any desired mapping,
    hope the 2 weight layers fit $H(x)$
  • 残差网络:$H(x)$ is any desired mapping,
    hope the 2 weight layers fit 𝐻(𝑥)
    hope the 2 weight layers fit $F(x)$
    let $H(x)=F(x)+x$

resnet中首次提出

code-pytorch

Bottleneck架构

1
2
structure: bottleneck
shortcut: Identity Mapping

resnet中首次提出

右侧是bottleneck连接,左右两个网络具有相似的复杂度,但是右侧的bottlenect设计能够用于更深层的网络。

conv as shortcut

1
2
structure: bottleneck
shortcut: conv

这里的shortcut不再是恒等映射(identity mapping),而是采用的conv。

这是对恒等映射的改进吗?相比恒等映射,优势在哪?

code-pytorch

疑问

为什么不能简单地增加网络层数?

对于原来的网络,如果简单地增加深度,会导致梯度弥散或梯度爆炸。

对于该问题的解决方法是正则化初始化和中间的正则化层(Batch Normalization),这样的话可以训练几十层的网络。

虽然通过上述方法能够训练了,但是又会出现另一个问题,就是退化问题,网络层数增加,但是在训练集上的准确率却饱和甚至下降了。这个不能解释为overfitting,因为overfit应该表现为在训练集上表现更好才对。
退化问题说明了深度网络不能很简单地被很好地优化。
作者通过实验:通过浅层网络+ y=x 等同映射构造深层模型,结果深层模型并没有比浅层网络有等同或更低的错误率,推断退化问题可能是因为深层的网络并不是那么好训练,也就是求解器很难去利用多层网络拟合同等函数。

怎么解决退化问题?

深度残差网络。如果深层网络的后面那些层是恒等映射,那么模型就退化为一个浅层网络。那现在要解决的就是学习恒等映射函数了。 但是直接让一些层去拟合一个潜在的恒等映射函数H(x) = x,比较困难,这可能就是深层网络难以训练的原因。但是,如果把网络设计为H(x) = F(x) + x,如下图。我们可以转换为学习一个残差函数F(x) = H(x) - x. 只要F(x)=0,就构成了一个恒等映射H(x) = x. 而且,拟合残差肯定更加容易。

维度设计

  • 整体架构: channel数目(depth)逐渐增加,W,H逐渐减小
  • 局部设计: bottleneck,即降维->变换->升维

源码

  • 官方实现 | KaimingHe caffe

keras

强调identity_block,恒等映射

pytorch

强调bottlenect

  • resnet示例-pytorch
    • 依赖 resnet模型-pytorch
  • 另外一个resnet版本 https://github.com/keras-team/keras/blob/master/keras/applications/resnet50.py
  • resnet-tensorflow
    • 提供cifar10 imagenet的示例

ResNet可视化

来自 https://www.cs.umd.edu/~tomg/projects/landscapes/

参考

  • SGD在两层神经网络上是怎么收敛的? | 知乎
  • ResNet及其多种变体
  • https://www.jianshu.com/p/e58437f39f65