Pytorch: 残差网络-ResNet
Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology
本教程不商用,仅供学习和参考交流使用,如需转载,请联系本人。
Reference
import torch
import torch.nn as nn
残差网络(ResNet)
VGGNet 与 Inception 出现后,学者们将卷积网络不断加深以寻求更优越的性能,然而所着网络的加深,网络却越发难以训练,方而会产生梯度消失现象: 另一方面越深的网络返回的梯度相关性会越来越差,接近于白噪声,导致梯度更新也接近于随机扰动。
更详细的说,对神经网络模型添加新的层,充分训练后的模型是否只可能更有效地降低训练误差?理论上,原模型解的空间只是新模型解的空间的子空间。也就是说,如果我们能将新添加的层训练成恒等映射 f ( x ) = x f(x)=x f(x)=x ,新模型和原模型将同样有效。由于新模型可能得出更优的解来拟合训练数据集,因此添加层似乎更容易降低训练误差。然而在实践中,添加过多的层后训练误差往往不降反升。即使利用批量归一化带来的数值稳定性使训练深层模型更加容易,该问题仍然存在。
何恺明等人提出的ResNet(Residual Network,残差网络) 较好地解决了这个问题,并获得了 2015 年 ImageNet 分类任务的第一名。 此后的分类、检测、分割等任务也大规模使用 ResNet 作为网络骨架。
主要贡献
提出了一种残差学习框架来减轻网络训练,这些网络比以前使用的网络更深。
显式地将层重构为学习关于层输入的残差函数,而不是学习未参考的函数。
提供了全面的经验证据说明这些残差网络很容易优化,并可以显著增加深度来提高准确性。
动机
最根本的动机就是所谓的“退化”问题,即当模型的层次加深时,错误率却提高了。
但是模型的深度加深,学习能力增强,因此更深的模型不应当产生比它更浅的模型更高的错误率。而这个“退化”问题产生的原因归结于优化难题,当模型变复杂时,SGD 的优化变得更加困难,导致了模型达不到好的学习效果。
Residual 块
通过 shortcut 连接, identity mapping 来加深网络。
ResNet 的思想在于引入了一个深度残差框架来解决梯度消失问题,即让卷积网络去学习残差映射,而不是期望每一个堆叠层的网络都完整地拟合潜在的映射(拟合函数)。如图所示,对于神经网络,如果我们期望的网络最终映射为 H ( x ) H(x) H(x) , 左侧的网络需要直接拟合输出 H ( x ) H(x) H(x) ,而右侧由 ResNet 提出的子模块,通过引入一个 shortcut (捷径)分支,将需要拟合的映射变为残差 F ( x ) : H ( x ) − x F(x): H(x)-x F(x):H(x)−x 。 ResNet 给出的假设是:相较于直接优化潜在映射 H ( x ) H(x) H(x) ,优化残差映射 F ( x ) F(x) F(x) 是更为容易的。
在形式上,将期望的底层映射表示为 H ( x ) H(x) H(x) ,我们让堆叠的非线性层适合 F ( x ) F(x) F(x) 的另一个映射: F ( x ) = H ( x ) − x F(x)= H(x)-x F(x)=H(x)−x 。原始映射被重铸为 F ( x ) + x F(x)+x F(x)+x 。
我们用更详细的图来说明二者的区别。设输入为 x x x。假设我们希望学出的理想映射为 f ( x ) f(x) f(x) ,从而作为激活函数的输入。
左图虚线框中的部分需要直接拟合出该映射 f ( x ) f(x) f(x) ,而右图虚线框中的部分则需要拟合出有关恒等映射的残差映射 f ( x ) − x f(x)−x f(x)−x 。残差映射在实际中往往更容易优化。
以恒等映射作为我们希望学出的理想映射 f ( x ) f(x) f(x) 。我们只需将图中右图虚线框内上方的加权运算(如仿射)的权重和偏差参数学成 0 0 0 ,那么 f ( x ) f(x) f(x) 即为恒等映射。
实际中,当理想映射 f