ResNet论文阅读笔记

深度神经网络更难训练。我们提出了一个残差学习框架来简化网络的训练,这些网络比以前使用的要深得多。

Resnet到底在解决一个什么问题呢? - 薰风初入弦的回答 - 知乎

Introduction

[!question] 学习更好的网络就像堆叠更多的层一样简单吗?
回答这个问题的一个障碍是臭名昭著的梯度消失/爆炸问题,它从一开始就阻碍了收敛。

然而,这个问题已经通过规范化初始化(Normalization)和中间规范化层(Batch Normalization)得到了很大程度的解决,这使得具有数十层的网络能够开始收敛随机梯度下降(SGD),并可以反向传播

[!question] 更深的网络性能会变好吗?
image.png
不是欠拟合,而是梯度消失无法继续训练
随着网络深度的增加,精度趋于饱和

判断是否过拟合:过拟合情况应该训练误差也变得很低,但是在上图中会看到与实际情况不符

这一段有点反直觉:

[!note] 更深的网络效果不会比浅的网络效果差
(训练精度的)退化表明,并非所有系统都同样容易优化。让我们考虑一个较浅的体系结构和它的更深的对应物,它在上面添加了更多的层。
通过构造更深的模型存在一个解决方案:添加的层是身份映射(identify mapping,输入 $x$ 输出 $x$ ),其他层是从学习的较浅模型复制的。这种构造解的存在表明,较深的模型不会比较浅的模型产生更高的训练误差。但实验表明,我们现有的求解器无法找到与构建的解决方案相当或更好的解决方案(或者无法在可行时间内做到这一点)。

解决上面的问题,提出残差网络

在本文中,我们通过引入深度残差学习框架来解决退化问题。我们不是希望每几个堆叠层直接符合期望的底层映射,而是明确地让这些层符合残差映射

形式上,将期望的底层映射表示为$H(x)$,我们让堆叠的非线性层适合另一个映射$F(x):= H(x) - x$(学习的内容)。原始映射被重铸为$F(x)+x$。我们假设优化残差映射比优化原始的、未引用的映射更容易。在极端情况下,如果一个恒等映射是最优的,将残差推至零要比用一堆非线性层拟合一个恒等映射容易得多。

学习的不是原本的$x$,而是残差

image.png|475
shortcut connection实际上做的就是identity mapping
不会增加模型复杂度

越深,精度越高

Related work

残差表示:统计和机器学习里面用的多,比如GBDT、线性模型的残差拟合

shortcut connection

Deep Residual Learning

$$
\mathbf{y}=\mathcal F(\mathbf{x}, {W_{i}}) +\mathbf{x}
$$

$\mathbf{x}, \mathbf{y}$ 是输入和输出层,$\mathcal F(\mathbf{x}, {W_{i}})$是学习的残差映射$\mathcal F=W_{2} \sigma (W_{1}\mathbf{x})$

要求:$\mathbf{x}$和$\mathcal F$的维度需要匹配
不匹配的解决方法,使用投影:
$$
\mathbf{y}=\mathcal F(\mathbf{x}, {W_{i}}) +W_{s}\mathbf{x}
$$

当输入和输出维度相同时(图中的实线快捷方式),可以直接使用标识快捷方式(Eqn.(1))。当维度增加时(图中的虚线快捷方式),我们考虑两种选择:(A)增加维度时填充额外的零项。这个选项不引入额外的参数;(B) Eqn.(2)中的投影方式用于匹配维度(通过1×1卷积完成)。对于这两个选项,当shortcuts跨越两个大小的feature maps时,它们的步幅为2

这里的意思是增加维度填充0,降维的时候使用$1 \times 1$卷积核?

image.png

Experiment

实验预处理:随机裁剪、翻转、标准化、批归一化

image.png

conv2_x这些表示的是一个块,一个块里面有里面有多个层
18的计算:$(2+2+2+2)(每个块的卷积层之和)\times 2(均出现2次) + 头卷积+ 尾全连接$
注意pooling一般不算层

实验结果

image.png
左侧为没加残差,右侧为加了残差。
中间突然下降是因为学习率乘了0.1

可以看到,有残差连接的收敛会快,且准确率更高

方案比较

当shortcuts输入输出维度不同时

  • A: 做0填充
  • B: 用$1 \times 1$卷积做投影
  • C: 对所有都做投影

结果:B和C差不多,但是B的参数量少
image.png

bottle neck

image.png

先做降维,再做$3 \times 3$卷积,再用$1 \times 1$卷积映射回去

总结

实际在做的事情

原本梯度计算

$$
\frac{\partial f(g(x))}{\partial x} = \frac{\partial f(g(x))}{\partial g(x)} \cdot \frac{\partial g(x)}{\partial x}
$$
会因为一直累乘而趋于0

但现在的求梯度:

$$
\frac{\partial f(g(x)) + g(x)}{\partial x} = \frac{\partial f(g(x))}{\partial g(x)} \cdot \frac{\partial g(x)}{\partial x} + \frac{\partial g(x)}{\partial x}
$$

这样可以把梯度变大

残差块

使得网络没那么快收敛,能够训练的动,就更难陷入局部最优解

这里的residual和GBDT的residual不同