简介
越深网络一定越好吗?
深层网络会遭遇退化问题(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 | structure: basic-block |
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 | structure: bottleneck |
resnet中首次提出
右侧是bottleneck连接,左右两个网络具有相似的复杂度,但是右侧的bottlenect设计能够用于更深层的网络。
conv as shortcut
1 | structure: bottleneck |
这里的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