ResNet论文笔记
为什么不是神经网络越深,训练效果越好?
神经网络加深,训练效果差可能是以下因素引起的:
- 梯度爆炸/消失(否决)
- 已经通过标准化解决
- 过拟合现象(否决)
- 过拟合现象应该是在训练集表现好,测试集表现差
- 图中的现象很明显不是过拟合(在训练集和测试集都差)
- 神经网络退化(可能的解释)
- 更深的神经网络训练难度大
解决神经网络退化问题
分析前面的问题
- 神经网络越深本不应会“退化"
- 将一个深层神经网络拆解为一个浅层神经网络和若干个网络层的组合。
- 若干个网络层最差也可以训练成恒等映射 ( y = x ) (y=x) (y=x)
- 那么深层神经网络最差应该性能和浅层神经网络相同
- "“退化”"的原因
- 现阶段的训练器无法在适当的时间内找到这样一个恒等映射或者将网络训练的更好
- 随着神经网络加深,收敛速度变慢,训练越来越困难
解决方式
- 假设浅层网络的输出为 x x x,而整么模型需要学习的函数为 H ( x ) H(x) H(x)
- 对于若干个网络层的组合,与其重新学习 H ( x ) H(x) H(x)不如学习 H ( x ) H(x) H(x)与浅层网络的输出 x x x之间的残差 H ( x ) − x H(x)-x H(x)−x,记作 F ( x ) F(x) F(x)
- 因此整个模型的输出 H ( x ) H(x) H(x)可以写作 F ( x ) + x F(x)+x F(x)+x
- 在最差的情况下,模型学习到的 F ( x ) F(x) F(x)为0,即模型的输出最差也不会比输入要差
由上图可知,模型可以按照自己的序求选择是否使用函数 f i f_i fi,从而解决了模型深度增加带来的退化问题
解决恒等映射问题
解决输出维度/通道数不匹配问题
y
=
F
(
x
,
{
W
i
}
)
+
x
y=F(x,\{W_i\})+x
y=F(x,{Wi})+x
- 当 F ( x ) F(x) F(x)的通道数与原始的输入x相同时,原始的恒等映射已经足够解决退化问题,再使用1X1的矩阵做映射不经济
y = F ( x , { W i } ) + W s x y=F(x,\{W_i\})+W_sx y=F(x,{Wi})+Wsx
- 当 F ( x ) F(x) F(x)的通道数与原始的输入x不相同时,需要对原始的输入x通过全连接层/卷积层,将其输出维度/通道数与 F F F函数的输出匹配
恒等与映射的选择问题
原文中作者对以下三种方式做了比较:
- A:所有的shortcut都使用恒等映射,也就是多出来的通道补0,没有额外的参数
- B:对需要调整维度的使用卷积映射shortcut来实现,不需要调整维度的使用恒等shortcut,升维的时候使用1 * 1卷积
- C:所有的shortcut都使用1 * 1卷积
不难发现,在降低错误率方面C>B>A,但是由于C方案对所有的shortcut都是使用1*1卷积,提高的模型复杂度远高与对模型的改进,不划算,作者在其网络构建中使用的是B方案。
解决深层网络参数过大问题
当通道维度增加时,由于卷积的特性会使得参数以平方的数量级增加,因此为了在更深层的网络上也可以进行训练,需要对残差块进行如下调整。下面假设输入特征的通道数均为256
原始的残差块:
- 将输入特征直接经过两个输出特征为256维的 3 × 3 3\times3 3×3卷积
- 参数量: 3 × 3 × 256 × 256 × 2 = 1179648 3\times3\times256\times256\times2=1179648 3×3×256×256×2=1179648
改进的残差块
- 将输入特征经过 1 × 1 1\times1 1×1卷积调整通道数到64
- 然后经过一个输出通道数为64的 3 × 3 3\times3 3×3卷积
- 最后将输出通道数通过 1 × 1 1\times1 1×1卷积还原为256
- 参数量: 1 × 1 × 256 × 64 + 3 × 3 × 64 × 64 + 1 × 1 × 64 × 256 = 69632 1\times1\times256\times64+3\times3\times64\times64+1\times1\times64\times256=69632 1×1×256×64+3×3×64×64+1×1×64×256=69632
总体比较参数量 改进前 改进后 = 1179648 69632 = 16.94 \frac{改进前}{改进后}=\frac{1179648}{69632}=16.94 改进后改进前=696321179648=16.94,显著减少了参数量。
从数学角度看残差模块为什么可以训练更深的网络
考虑一个两层的神经网络
- 第一层: f ( x ) f(x) f(x)
- 第二层: g ( x ) g(x) g(x)
- 考虑非残差连接
-
对于输入 x x x,其输出 y y y为 y = g ( f ( x ) ) y=g(f(x)) y=g(f(x))
-
反向传播的梯度计算为:
显然,在规格化之后,梯度本来就很小,在经过乘法运算只会让梯度更小,因此随着网络加深,训练逐渐变得困难。
- 考虑残差连接
-
对于输入 x x x,其输出 y y y为 y = g ( f ( x ) ) + x y=g(f(x))+x y=g(f(x))+x
-
反向传播的梯度计算为:
如此,确保了梯度足够大,加快了模型的收敛速度。