本文是对于提出了ResNet(深度残差网络)神经网络模型的论文Deep Residual Learning for Image Recognition的阅读笔记。
有关于神经网络模型的实现,可以参考我的另一篇blogCV-Model【4】:ResNet-34
更深的神经网络更难训练。本文提出了一个残差学习框架,以缓解比以前使用的网络要深得多的网络的训练。该框架使得层能根据其输入来学习残差函数而非原始函数(unreferenced functions)。本文提供了全面的依据表明,这些残差网络的优化更简单,而且能由更深的层来获得更高的准确率。
在深度的重要性的驱使下,出现了一个新的问题:训练一个更好的网络是否和堆叠更多的层一样简单呢?解决这一问题的障碍便是困扰人们很久的梯度消失 / 梯度爆炸,这从一开始便阻碍了模型的收敛。归一初始化(normalized initialization)和中间归一化(intermediate normalization)在很大程度上解决了这一问题,它使得数十层的网络在反向传播的随机梯度下降(SGD)上能够收敛。
当更深的网络能够开始收敛的时候,一个退化的问题就暴露出来了:随着网络深度的增加,准确度会达到饱和,然后迅速退化。出乎意料的是,这种退化并不是由过拟合引起的,在一个合适的深度模型上增加更多的层会导致更高的训练误差。
20层和56层的“plain”网络在CIFAR-10上的训练错误率(左)和测试错误率(右)。越深的网络在训练和测试上都具有越高的错误率。
但是模型的深度加深,学习能力增强,因此更深的模型不应当产生比它更浅的模型更高的错误率。而这个“退化”问题产生的原因归结于优化难题,当模型变复杂时,SGD的优化变得更加困难,导致了模型达不到好的学习效果。
在机器学习中,使用基于梯度的学习方法和反向传播训练人工神经网络时会遇到梯度消失问题。使用上述方法的情况下,在每次训练迭代期间,每个神经网络的权重都会接收与误差函数相对于当前权重的偏导数成比例的更新。问题是在某些情况下,梯度会非常小,阻止了权重改变其值。在最坏的情况下,这可能会完全阻止神经网络进一步训练。
深层模型存在一个构造上的解决方案:通过恒等映射(identity mapping)构建增加的层,从学习到的浅层模型中复制其他的层。这种构造性解决方案的存在表明:深层模型不应该产生比浅层模型更高的训练误差。
举例来说,有一个20层的网络,训练到跟之前的浅层网络差不多的精度和参数,这个时候在后面添加的14层都是identity mapping,此时训练精度不应该变差(浅层的网络与之前的浅层网络发挥一样的作用,深层的网络因为恒等映射,理论上是维持原来的网络的效果,而不应该使该网络效果变差),但是此时SGD找不到这个结果。
本文中,我们提出了一种深度残差学习框架来解决这个退化问题。我们明确的让这些层来拟合残差映射(residual mapping),而不是让每一个堆叠的层直接来拟合所需的底层映射(desired underlying mapping)。假设所需的底层映射为 H ( x ) \mathcal{H}(x) H(x),我们让堆叠的非线性层来拟合另一个映射: F ( x ) : = H ( x ) − x \mathcal{F}(x) := \mathcal{H}(x) - x F(x):=H(x)−x 。 因此原来的映射转化为: F ( x ) + x \mathcal{F}(x) + x F(x)+x。我们推断残差映射比原始未参考的映射(unreferenced mapping)更容易优化。在极端的情况下,如果某个恒等映射是最优的,那么将残差变为0 比用非线性层的堆叠来拟合恒等映射更简单。
公式 F ( x ) + x \mathcal{F}(x) + x F(x)+x,即identity mapping,可以通过前馈神经网络的 shortcut connection 来实现。Shortcut连接就是跳过一个或者多个层。通俗地讲,就是讲一个块的输入和该块的输出进行加和,以减少因为反向传播导致的梯度损失。Shortcut connection只是做加法,没有任何需要学的参数,不会增加模型的复杂度,也不会增加太多的计算量,且保证了网络仍然可以被训练。
所谓反向传播就是网络输出一个值,然后与真实值做比较的到一个误差损失,同时将这个损失做差改变参数,返回的损失大小取决于原来的损失和梯度,既然目的是为了改变参数,而问题是改变参数的力度过小,则可以减小参数的值,使损失对参数改变的力度相对更大。
在图像识别中,VLAD是残差向量对应于字典进行编码的一种表达形式,Fisher Vector可以看做是VLAD 的一个概率版本。对于图像检索和分类它们都是强力的浅层表达。对于向量量化,残差向量编码比原始向量编码更加有效。
在低级视觉和计算机图形学中,为了求解偏微分方程(PDEs),通常使用Multigrid法将系统重新表达成多尺度的子问题来解决,每一个子问题就是解决粗细尺度之间的残差问题。Multigrid的另外一种方式是分层基预处理,它依赖于代表着两个尺度之间残差向量的变量。实验证明 这些求解器比其他标准求解器的收敛要快得多,却并没有意识到这是该方法的残差特性所致。这些方法表明了一个好的重新表达或者预处理能够简化优化问题。
Shortcut连接已经经过了很长的一段实践和理论研究过程。训练多层感知器(MLPs)的一个早期实践就是添加一个连接输入和输出的线性层。在Szegedy2015Going及Lee2015deeply中,将一些中间层直接与辅助分类器相连接可以解决梯度消失/爆炸问题。在Szegedy2015Going中,一个“inception”层由一个shortcut分支和一些更深的分支组合而成。
与此同时,“highway networks”将shortcut连接与门控函数结合起来。这些门是数据相关并且是有额外参数的,而我们的恒等shortcuts是无参数的。当一个门的shortcut是“closed”(接近于0)时,highway网络中的层表示非残差函数。相反的,我们的模型总是学习残差函数;我们的恒等shortcuts从不关闭,在学习额外的残差函数时,所有的信息总是通过的。此外,highway网络并不能由增加层的深度(例如, 超过100层)来提高准确率。
f ∗ f^* f∗为最优, F 1 , F 2 , . . . \mathcal{F}_1, \mathcal{F}_2, ... F1,F2,...是逐步优化的模型,对于Non-nested function classes,虽然模型变复杂了,但是可能学习的方向偏了,导致更复杂的模型 F 6 \mathcal{F}_6 F6并没有 F 3 \mathcal{F}_3 F3的效果好。而对于Nested function classes,我们让后面优化得到的复杂模型,严格包含子模型,那么更复杂的模型就不会比之前的子模型变得更差,这也就是ResNet的核心思想。
ResNet允许在网络里面嵌入一些之前的小网络,并先去拟合小网络。
我们将 H ( x ) \mathcal{H}(x) H(x)看作一个由部分堆叠的层(并不一定是全部的网络)来拟合的底层映射,其中x是这些层的输入。
假设多个非线性层能够逼近复杂的函数,这就等价于这些层能够逼近复杂的残差函数,例如, H ( x ) − x \mathcal{H}(x) - x H(x)−x(假设输入和输出的维度相同)。所以我们明确的让这些层来估计一个残差函数: F ( x ) : = H ( x ) − x \mathcal{F}(x) := \mathcal{H}(x) - x F(x):=H(x)−x,而不是 H ( x ) \mathcal{H}(x) H(x)。因此原始函数变成了: F ( x ) + x \mathcal{F}(x) + x F(x)+x。尽管这两个形式应该都能够逼近所需的函数(正如假设),但是学习的难易程度并不相同。结合上述,此时我们可以保证模型不会变差,因为当 F ( x ) = 0 \mathcal{F}(x) = 0 F(x)=0时,输入与输出相等。
正如我们在介绍中所讨论的,如果增加的层可以被构建为恒等映射,那么更深的模型的训练误差应该不大于与其对应的浅层模型。退化问题表明了,求解器在通过多个非线性层来估计恒等映射上可能是存在困难的。而伴随着残差学习的重新表达,如果恒等映射是最优的,那么求解器驱使多个非线性层的权重趋向于零来逼近恒等映射。
为了方便理解,这里不考虑偏置
残差结构可简单的写成如下形式:
x l + 1 = x l + F ( x l , W l ) x_{l+1} = x_l + F(x_l, W_l) xl+1=xl+F(xl,Wl)
其中 x l x_l xl又可以拆分为上一模块的输出和l层残差模块的加和,因此循环递归得到以下公式:
x l + 2 = x l + 1 + F ( x l + 1 , W l + 1 ) = x l + F ( x l , W l ) + F ( x l + 1 , W l + 1 ) x_{l+2} = x_{l+1} + F(x_{l+1}, W_{l+1}) = x_l + F(x_l, W_l) + F(x_{l+1}, W_{l+1}) xl+2=xl+1+F(xl+1,Wl+1)=xl+F(xl,Wl)+F(xl+1,Wl+1)
不停的循环下去,可以得到任意深层单元L特征的表达(即通式):
x L = x l + ∑ i = l L − 1 F ( x i , W i ) x_L = x_l + \displaystyle\sum^{L-1}_{i=l}F(x_i, W_i) xL=xl+i=l∑L−1F(xi,Wi)
可以看到,对于L层的输出而言,可以看作任何一个L层之前的l层的输出 x l x_l xl和中间残差块的输出的叠加(注意中间残差块的输入也是随着i变化的,因此每个残差块内部也都有l层输出 x l x_l xl的作用),因此整个网络是residual fashion的,可以把任何一层和该层之前的任何一层看成残差模块,这样就保证了整个网络的前向传播的畅通。
对于反向传播,假设损失函数为E,根据反向传播的链式法则可以得到:
∂ ε ∂ X l = ∂ ε ∂ X L ∂ X L ∂ X l = ∂ ε ∂ X L ( 1 + ∂ ∂ X l ∑ i = l L − 1 F ( x i , w i ) ) \frac{\partial_\varepsilon}{\partial_{X_l}} = \frac{\partial_\varepsilon}{\partial_{X_L}} \frac{\partial_{X_L}}{\partial_{X_l}} = \frac{\partial_\varepsilon}{\partial_{X_L}} (1 + \frac{\partial}{\partial_{X_l}}\displaystyle\sum^{L-1}_{i=l}F(x_i, w_i)) ∂Xl∂ε=∂XL∂ε∂Xl∂XL=∂XL∂ε(1+∂Xl∂i=l∑L−1F(xi,wi))
我们可以发现这个导数可以被分为两部分:
对于任何一层的x的梯度由两部分组成,其中一部分直接就由L层不加任何衰减和改变的直接传导l层,这保证了梯度传播的有效性,另一部分也由链式法则的累乘变为了累加,这样有更好的稳定性。
设计规则:
在以上plain网络的基础上,我们插入shortcut连接,将网络变成了对应的残差版本。
设计网络的规则:
需要进行的浮点运算数:
FLOPs=(卷积核长 x 卷积核宽 x 输入通道)x(输出宽 x 输出高 x 输出通道)
p.s. loss大幅度下降,是因为学习率的原因(玄学)!理论上来说再训练一段时间再下降可能会更好(因为找的方向比较正确,避免了后期训练无力的情况)
右边的结构会用于构建Deeper Bottleneck Architectures,即ResNet-50、ResNet-101和ResNet-152
对于更深的模型,我们希望能学习到更多的东西,所以我们会增加输入的参数,即输入的通道数。但是如果直接使用左图的结构,会增加大量的计算复杂度,十分的不划算。所以这里使用1x1卷积将输入的通道数256,映射回64,此时的计算与原本的计算的复杂度相同。训练完后,再将通道数映射回256。
虽然降维会带来信息的损失,但因为残差的存在,以及足够深的模型结构,这里复杂度减少带来的好处要多于信息损失带来的坏处。
本文主要分析提出了经典的卷积神将网络ResNet的论文Deep Residual Learning for Image Recognition,并推导有关残差的相关逻辑。
翻译部分参考资料