Summary
为解决神经网络层数增加后,训练误差和复杂度过大等的问题,本文提出了一种残差学习框架,巧妙地引入一条恒等映射的快捷路径,由$x \to H_1(x)$变为$x \to F(x)+x=H_2(x)$,解决了梯度消失的问题,在增加了神经网络的深度同时,仍保持较低的训练误差和复杂度,且结构简单,训练成本较低。
Abstract
背景:更为深层的神经网络难以训练
问题:解决深层的神经网络训练难,精度低的问题。做到比以往神经网络更深的同时仍然容易训练的效果。
方法:提出一种残差学习框架,网络深度比远高于VGGNet和GoogLeNet的同时,仍然保持了较低的训练误差和复杂度。
Research Objective
解决深层的神经网络训练误差高,复杂度高的问题,即要解决深层网络中出现的网络退化问题。
Problem Statement
1、好的网络并不是要堆叠更多的层。当达到较深层时,就可能出现梯度消失/爆炸,从而阻碍收敛。但已经通过标准初始化(normalized initialization)和中间归一化层(intermediate normalization layers)来改善,使得数十层的网络能通过反向传播(backpropagation)来收敛,从而实现随机梯度下降(SGD)。
2、(==本文要解决的问题==)更深的网络会出现退化问题(degradation):即随着网络层数的增加,准确度会逐渐达到饱和,然后急剧下滑。同时会出现更高的训练误差。如图,56层明显比20层的错误大得多。
Method(s)
方法
提出了一种深度残差学习框架,在更深的神经网络中,仍保持较高的精确度和较低的复杂度。
优点
1、即使输入在传输时损失很大,其输出仍包含完整的输入,且仍可以通过SGD和反向传播进行端到端的训练。
2、结构简单,可以通过使用公共库(如Caffe)轻松实现,无需修改求解器。
3、训练的层数远大于之前的模型(VGGNet有19层、GoogLeNet有22层,而ResNet达到152层)。而其他框架只是单纯线性输出,当损失很大时,该输出(也就是下一层的输入)会逐渐变小直到训练不动,误差也就越来越大。
残差块
本模型:如图,输入为$x$,分为两条路线,一条通过两到三个卷积层(指weight layer)的值为$F(x)$,另一条通过恒等映射(identity mapping)输出仍为$x$,该模型输出为$H(x)=F(x)+x$。
其他模型:输入为$x$,一条线通过线性层值为$H(x)$,即该模型输出为$H(x)$,且$H(x)<x$(传输有损失)。同时该模块的输出即为下一模块的输入,当$H(x)$越来越小时,将难以训练,直到误差越来越高。
即使极端情况下损失最高,输出$F(x)=0$,由于还有恒等映射)中的$x$,仍有$H(x)=x$,即输入$x$输出仍为$x$,而不会出现输入x输出越来越小、导致难以训练的情况。
ResNet是如何解决梯度消失的?
设对某一个残差块输入为$% MathType!MTEF!2!1!+-
% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaWGybWaaSbaaSqaaiaadMgaaeqaaaaa
% !4115!
$${X_i}$,输出为$% MathType!MTEF!2!1!+-
% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaWGybWaaSbaaSqaaiaadMgacqGHRaWk
% caaIXaaabeaaaaa!42B2!
$${X_{i + 1}}$,忽略ReLu优化,该残差块输出应为$% MathType!MTEF!2!1!+-
% feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaWGybWaaSbaaSqaaiaadMgacqGHRaWk
% caaIXaaabeaakiabg2da9iaadAeacaGGOaGaamiwamaaBaaaleaaca
% WGPbaabeaakiaacYcacaGG7bGaam4vamaaBaaaleaacaWGPbaabeaa
% kiaac2hacaGGPaGaey4kaSIaamiwamaaBaaaleaacaWGPbaabeaaaa
% a!4F70!
$${X_{i + 1}} = F({X_i},{ {W_i}} ) + {X_i}$。下一个残差块输出即为
$$
\displaylines{
{X_{i + 2}} = F({X_{i + 1}},{ {W_{i + 1}}} ) + {X_{i + 1}}
= F({X_{i + 1}},{ {W_{i + 1}}} ) + F({X_i},{ {W_i}} ) + {X_i} \cr
……
}
$$
对于最后一个残差块而言,其输出设为${X_I}$,即有
$$
\displaylines{
{X_n} = F({X_{n - 1}},{ {W_{n - 1}}} ) + F({X_{n - 2}},{ {W_{n - 2}}} ) + …… + F({X_i},{ {W_i}} ) + {X_i} \cr
= \sum\limits_{k = i}^{n - 1} {F({X_k},{ {W_k}} ) + } {X_i} \cr}
$$
当更新梯度时,有
$$
\eqalign{
{{\partial loss} \over {\partial {X_i}}} &= {{\partial loss} \over {\partial {X_n}}} \times {{\partial {X_n}} \over {\partial {X_i}}} \cr &= {{\partial loss} \over {\partial {X_n}}} \times {{\partial (\sum\limits_{k = i}^{n - 1} {F({X_k},\{ {W_k}\} + {X_i})} } \over {\partial {X_i}}} \cr
&= {{\partial loss} \over {\partial Xn}} \times ({{\partial \sum\limits_{k = i}^{n - 1} {F(Xk,\{ Wk\} )} } \over {\partial Xi}} + 1) \cr}
$$
可以看到,偏导结果化简中始终存在“1”,则即使训练得很差,导致残差值$F(X)$很小,,其输出结果仍有${{\partial loss} \over {\partial Xn}}$(相当于恒等映射),也可以把训练好的网络传到下一层,有效避免了梯度消失的问题。
网络结构
如图,分别为18到152层的ResNet,以34层和50层为例子。都通过64X7X7,步长(stride)=2的卷积层以及3x3,步长=2的池化层。
对于34层而言,还通过3个conv2_x(3层)残差块,4个conv3_x(4层)残差块,6个conv4_x(6层)残差块,3个conv5_x(3层)残差块,1+1+2x3+2x4+2x6+2x3+1=34。
如图,对于50层而言,为保证训练精度和计算量,conv2_x残差块中使用两个1x1的卷积层。用来降维和升维。例如输入256维度,通过64x1x1来降维到64维,后和左边一样通过64x3x3,之后再通过256x1x1升维到256,因为要保证这里输出和输入维度一样。
虽然会减少点精度,但复杂度却下降很多,如34层和50层的复杂度接近。