1.关于残差网络
残差网络从实现原理上并不复杂,但是关于具体的原理一开始比较难理解,找了一些资料也有了一点想法。
(1).我们要解决什么问题
首先,网络的性能并不是随网络层数加深而上升的,这是很符合直觉的,毕竟有过拟合的先例。但是实际上,即使网络还处于欠拟合,更深层次的网络也会导致性能的下降,也就是网络退化,要理清这一现象,需要先引入一个概念,恒等映射。恒等映射简单的讲就是f(x)=x,在我们预期中,一个理想的网络使用m层完成了最优拟合,那么在将网络增加到m+1层时,其输出应当也和m层一致。也就是说,对于理想的第m+1层,存在一个恒等映射的输入输出。但是实际网络中则不然,即使不考虑卷积层特征提取中损失的信息,relu等激活函数层也会为网络带来不可逆的信息损失,导致m+1,m+2等更深层无法完成恒等映射从而对实际拟合产生不良影响。残差网络的出现就是为了解决这一问题。
(2)我们为什么要解决问题
前文提到,我们现实中存在损失而无法继续加深层数,那么我们为什么不直接使用目前数据最好的层数呢?这是因为网络还没有过拟合,说明其优化能力还未被充分利用,只要解决了网络退化问题继续添加网络深度还是可以继续提升网络性能的,这也就是为什么我们不直接选择误差U型曲线最低点时的网络层数。
(3)我们怎么解决问题
残差网络说白了就是将每两个带有BN和激活函数的卷积层作为一个模块,在第二次激活函数计算前加上一个原始输入,使得原本的输出relu[H(x)]变成relu[H(x)+x],如果模块内存在形状的转换,还需要对x进行1*1卷积改变形状。同时,我们可以发现,resnet网络是将整个网络都应用了残差块结构,这是由于我们并不知道从哪一层开始网络开始退化出现冗余。
(4)为什么残差网络有效
首先谈谈我个人的理解,残差网络将输出从relu[H(x)]变成relu[H(x)+x],由于x是与当前层无关的,那么一定程度上这种设计淡化了当前层对网络整体的影响力。其次,如果网络此时已接近最优化,那么H(x)应当是个近似于零的数值,而近似于零代表容易被relu直接吃掉,而由于网络还没有达到最优化,加上一个x可以保证这部分参数可以顺利送入下一层继续得到优化的机会。这里可能比较绕,因为relu[H(x)]=0不代表H(·)达到最优,relu只是一个计算,反而会为下一层传达H(x)已经最优从而遮盖住H(x)≠0的实际情况。也就是说通过加入x屏蔽了一部分relu的作用从而防止了信息丢失带来的网络退化。
再来看看专家的说法,按照原作者何凯明的说法:在前向传播时,输入信号可以从任意低层直接传播到高层。由于包含了一个天然的恒等映射,一定程度上可以解决网络退化问题。但我更喜欢Andreas Veit的解释,他将残差块解释为路径的复合,残差网络就可以被看作是一系列路径集合组装而成的一个集成模型,其中不同的路径包含了不同的网络层子集。他还通过实验表明,残差网络中主要在训练中贡献了梯度的是那些相对较短的路径。
我对Andreas Veit说法的理解是:每一个残差块实际上像是一种让网络自主选择路径的模型,而不同的路径就像是不同权重的参数,通过这种结构为网络选择出合适的参数组合(也就是那些实际贡献梯度的残差块)
本来这篇是想继续记点知识点,但是越写越发现自己理解不足,希望有说的不对的地方大家多指正,谢谢大家。
本文参考:
凯明之作Resnet + 心路历程[超详] + 解决退化问题 + 让网络变得更深成为现实 - 知乎
CVPR2016:ResNet 从根本上解决深度网络退化问题 - 知乎
7.6. 残差网络(ResNet) — 动手学深度学习 2.0.0-beta0 documentation (d2l.ai)