残差网络ResNet

简介

Is learning better networks as easy as stacking more layers?

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

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

(难以训练,训练误差)

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

“Overly deep” plain nets have higher training error

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

模型

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

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

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

创新点

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$

恒等映射

Identity Mapping by Shortcuts

bottle neck

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

疑问

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

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

对于该问题的解决方法是正则化初始化和中间的正则化层(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. 而且,拟合残差肯定更加容易。

维度设计

从上到下:

  • 整体的feature_map变小
  • 整体的channel数目在增大

源码

keras

强调identity_block,恒等映射

pytorch

强调bottlenect

ResNet可视化

参考