ResNet要解决的问题
在很多论文中,以及很多比赛如ImageNet的前几名使用的算法中,表现出网络深度的重要性。许多任务都从深层的网络中得到了效果提升。那么问题来了:简单的堆叠更多的层是否就能得到性能更好的网络?
首先,随着网络层数的增加,随之而来的一个问题就是梯度消失\爆炸,梯度消失\爆炸会阻碍网络的收敛。然而这一问题,通过合理的初始化以及中间层的归一化(如BN层),已经在很大程度上得到了改善。
第二个问题就是网络性能的退化(degradation)。随着网络层数的增加,准确率会慢慢增加达到饱和,然后迅速退化。网络层数增加,网络的复杂度也随之增加,我们自然想到这一退化现象是否由过拟合引起?答案是否定的,因为网络在训练集上的表现也在变差。文章中给出了如下图的实验结果。ResNet要解决的就是退化(degradation)问题。
残差结构(building block)
假设我们想要学得的映射函数是(不一定代表整个网络的最终映射,也可以是中间某几层的最终映射),残差学习的思想不是直接让网络学习,而是学习残差,也就是说将想要得到的最终映射分为两部分,即残差和恒等映射(这些层的输入)。残差结构(building block)如下图所示。恒等映射没有引入多余的参数和计算量。
残差结构的思想,是受网络性能退化(degradation)这个问题的启发:给浅层的网络不断堆叠非线性层,网络性能会发生退化,那么如果堆叠的层被构建成恒等映射,就可以保证再深的网络也不会比其对应的浅层网络的结果差,退化的问题也就解决了。所以ResNet通过短路连接(shortcut)构建恒等映射解决退化问题。
对于残差结构,如果此时恒等映射是最优的,即,那么直接将残差中的权值置为0即可,而对比让调整非线性层的参数学习恒等映射,要容易得多。更一般地,此时恒等映射不是最优,相比既要学习输入输出前后的差别(残差),又要保留原始输入有用的信息,残差结构只需要学习输入输出前后的差别即可,降低了学习的难度。
残差结构的一些注意事项
1、对于残差结构(building block)中的残差部分,注意残差部分从最后线性层(weight layer(如图所示))出来,先与恒等映射对应元素相加后,再用非线性函数**。所以恒等映射一定要跨过2个及以上的weight layer,因为如果只有一层的话,残差部分是没有非线性函数**的,所以也只是一个线性函数,然后再一起送到后面的非线性函数**,这其实和直接堆叠非线性层(没有残差结构)没有本质差别。
2、在与对应元素相加时,一定要保证与维数相同,如果不相同,可以在恒等映射部分添加一个线性映射(如1x1的卷积),使得与维数相同。
ResNet网络结构
ResNet的网络结构如下图所示
网络中用到两种building block,如下图所示。左边的残差部分是两个3x3的卷积层的堆叠。右边的残差部分是1x1,3x3,1x1三个卷积层的堆叠。右边的设计叫做bottleneck,先用1x1的卷积压缩维度,最后再用1x1的卷积恢复维度,这样的设计可以减少模型参数,节省计算时间。
论文地址Deep Residual Learning for Image Recognition