首先解释何为残差,一般和误差做一个区分

误差是观察值与真实值之间的差。误差中的观察值表示通过测量得出的值,真实值表示那个理想地、几乎不可能达到的精确的值。可以说我们的模型是自带误差。误差是无法消除得

残差是观察值与模型估计值之间的差。残差中的观察值就是我们的标注数据的值,在实际的使用上,也直接将这个观察值描述为真实值。模型估计值不必多说,就是我们对每个样本的预测值。那按照这样的定义,损失函数中的算子不就包含了这个残差吗?  

Python残差运算 残差计算方法_Python残差运算

 这个y - f(x)是否就是残差??就是一个东西

Python残差运算 残差计算方法_Python残差运算_02

使用的时候,残差就是符合直觉得那个值。早就包含在loss function中了

Python残差运算 残差计算方法_Python残差运算_03

 可以看到,resnet在alexnet的基础上将错误率再降低10%以上。在alexnet之前,只能使用基于统计学的像素级特征,比如HOG\SIFT,麻烦而且效果也比较差

resnet在alexnet的基础上,提出了残差模块,将CNN可以做到更深更宽,从此以后,卷积的限制变得微乎其微。但这又招致另外的一些批评,认为CNN提取的特征缺乏解释性,不可靠

Python残差运算 残差计算方法_Python残差运算_04

 resnet这是个很恐怖的深度

QUESTIONMARK:为什么卷积网络在之前不能做到很深?

回顾历史,在lenet时代,算力不够导致模型不能被设计得很大。或者说,正因为那时候的CNN普遍比较浅,因此还没有意识到CNN做深做宽之后产生的其他问题。

到了alexnet时代,利用有效的dropout机制、relu激活,已经可以超越lenet时代的限制。此时已经意识到除了算力问题之外,还存在梯度弥散的问题。信息在前向传播中的衰减,误差在反向传播中的衰减。

那么更深网络中误差收敛效果变差可以归因于梯度弥散吗??

不能。因为梯度弥散在浅层网络中同样会存在。比如说特征的第一次前向传播,如果模型初始化有问题,那么很有可能在第一次传播至输出层时,信息直接衰减到无法训练的程度。所以模型权值的初始化现在普遍是采用基于某种统计分布的初始化,比如说服从标准正态分布

可以归因于过拟合吗??

显然也是不能的。过拟合描述的是训练集误差小,测试集误差高的现象。的确,网络参数越多越有可能出现过拟合的现象,按照过拟合的定义,56层的网络显然应该拟合得更好才对。

也就说,这个现象不仅不是因为过拟合,反而是某种原因破环了大网络更容易过拟合这个规则

Python残差运算 残差计算方法_深度学习_05

 可以看到,网络变身之后误差收敛的效果反而变差了

那么我们将更深网络中误差收敛效果变差这个现象描述为 “网络退化”

resnet解决了这个问题,子豪兄直接就开始讨论解决的方法

但这个现象发生的原因是什么呢??

我们选择加深网络的层数,是希望深层的网络的表现能比浅层好,或者是希望它的表现至少和浅层网络持平(相当于直接复制浅层网络的特征),可实际的结果却是发生了网络退化

MobileNet V2的论文中提到,由于非线性激活函数Relu的存在,当输入小于0的时候,神经元的输出直接置为0,相当于神经元永远静默或者是死亡,神经元的死亡几乎是不可逆的,等价于发生了许多不可逆的信息损失。我们试想一下,一个特征的一些有用的信息损失了,那他的表现还能做到持平吗?答案是显然的。

这也只是其中的一个解释

可以换掉relu激活函数吗??

之后又出现了leaky relu, 将x<0的部分换成了y = 0.1x。

何为恒等映射??

这是resnet解决网络退化的核心机制。假设有两个网络a,b.b网络是a网络加深了三层的结果。

假设我们希望a,b两个网络最终的效果保持一致,那么假设b网络的输入是x,输出为h(x).则a,b两个网络表现持平就可以表示为h(x) = x.这种让输入与输出相等的操作就叫恒等映射。

这并不是一个陌生的概念,以前我们常常做的恒等变形就是这个东西

关于resnet解决网络退化的机理的一个猜想:resnet相当于几个浅层网络的集成ensemble(集成)

集成这个词,除了ensemble learning之外,还有dropout机制,其中一个作用相当于集成了多个模型。

但这又产生了一个问题:恒等映射从某种意义上是将深层网络变浅了,那我一开始做浅点不就行了?从实验结果看,毫无疑问采用这种模式的模型效果是更好的。这又是为什么??

Python残差运算 残差计算方法_Python残差运算_06

Python残差运算 残差计算方法_深度学习_07

 

resnet解决网络退化的原因:

Python残差运算 残差计算方法_git_08

梯度回传是怎么一回事??怎么回传??

Python残差运算 残差计算方法_github_09

比如说boosting这个技术

Python残差运算 残差计算方法_过拟合_10

 核心思想是强化之前分类错误的部分,多次迭代之后,将多个弱分类器进行直接叠加,就得到了一个强分类器

resnet也有类似的做法,我们的目标是令x = h(x),如果网络训练得足够好,那么残差f(x)就应该足够小

Python残差运算 残差计算方法_git_11

 这倒是,传统的神经网络本来的目标就是要迅速收敛Loss,这就要求每一次迭代尽可能有效,少做无用功,等到loss 不在收敛,我们就判断模型差不多训练完成

我们向模型加入非线性因素主要是为了增加分类器的分类能力,但是加的越多,反过来就造成了更为严重的信息损失

Python残差运算 残差计算方法_深度学习_12

 这里说了梯度回传,想了想,觉得应该就是梯度反向传播。这里说的梯度相关性或者说相邻像素的相关性,怎么在数学上表示呢??

Python残差运算 残差计算方法_过拟合_13

Python残差运算 残差计算方法_过拟合_14

上面这两个结构是等价的。但这个位置,跳过某些层是什么意思???不应该都是上面那样

h(x) = x + f(x),也没有看到做了if分支之类的结构啊??

在这个结构中f1,f2,f3可以称作是残差块,它的子结构就是CBL,卷积+BN+激活

在transformer里面讲的encoder,decoder也是有子结构

Python残差运算 残差计算方法_git_15

 resnet又跟dropout的更能有重合了,之前在yolo2当中讲到BN层的时候,也提到这一点,并且BN层和dropout是不能同时使用的。dropout又是alexnet提出的方法,这种方法可以有效的防止过拟合

那么总结来说,resnet改动的东西就是用于提取卷积特征的backbone