目录
1、背景
在 ResNet 之前,所有的神经网络都是通过卷积层和池化层的叠加组成的。人们认为卷积层和池化层的层数越多,获取到的图片特征信息越全,学习效果也就越好。但是在实际的试验中发现,随着卷积层和池化层的叠加,不但没有出现学习效果越来越好的情况,反而出现两种问题:
1、梯度消失和梯度爆炸
梯度消失:若每一层的误差梯度小于1,反向传播时,网络越深,梯度越趋近于0
梯度爆炸:若每一层的误差梯度大于1,反向传播时,网络越深,梯度越来越大2、退化问题
随着层数的增加,预测效果反而越来越差。如下图所示(论文原图)
针对问题1:
ResNet论文提出通过数据的预处理以及在网络中使用 BN(Batch Normalization)层来解决。
针对问题2:
ResNet论文提出了 residual结构(残差结构)来减轻退化问题。
残差块包含了跨越网络层的“跳跃连接”,这些跳跃连接直接将输入信号添加到了网络层的输出中,从而将之前传递的梯度留下来并保持梯度的大小。这种残差块的设计避免了网络层中梯度传递过程中的信息流失,同时允许梯度直接跨越多个层的较大变化。通过这种方式,ResNet能够处理非常深的网络层,同时保持较高的准确率。
2、BN(Batch Normalization)层
没怎么懂,参考自Batch Normalization详解以及pytorch实验_pytorch batch normalization_太阳花的小绿豆的博客-CSDN博客
定义:Batch Normalization是指批标准化处理,将一批数据的feature map满足均值为0,方差为1的分布规律。
简而言之,就是计算一个Batch数据的feature map然后再进行标准化(batch越大越接近整个数据集的分布,效果越好),计算公式如下:
根据上图的公式可以知道代表着我们计算的feature map每个维度(channel)的均值,注意是一个向量不是一个值,向量的每一个元素代表着一个维度(channel)的均值。代表着我们计算的feature map每个维度(channel)的方差,注意是一个向量不是一个值,向量的每一个元素代表着一个维度(channel)的方差,然后根据和计算标准化处理后得到的值。
下图给出了一个计算均值和方差的示例:
注:在原论文公式中还有,两个参数,是用来调整数值分布的方差大小,是用来调节数值均值的位置。这两个参数是在反向传播过程中学习得到的,的默认值是1,的默认值是0。
3、residual结构(残差结构)
residual结构使用了一种 shortcut 的连接方式,也可理解为捷径。让特征矩阵隔层相加,注意F(X)和X形状要相同,所谓相加是特征矩阵相同位置上的数字进行相加。
主要有以下两种不同的residual结构:
- 左边残差结构称为 BasicBlock,主要用于浅层网络(如:18-layer、34-layer)
- 右侧残差结构称为 Bottleneck,主要用于深层网络(如:50-layer、101-layer、152-layer)
Bottleneck
1)其中第一层的1× 1的卷积核的作用是对特征矩阵进行降维操作,将特征矩阵的深度由256降为64;第三层的1× 1的卷积核是对特征矩阵进行升维操作,将特征矩阵的深度由64升成256。降低特征矩阵的深度主要是为了减少参数的个数。
如果采用BasicBlock,参数的个数应该是:256×256×3×3×2=1179648
采用Bottleneck,参数的个数是:1×1×256×64+3×3×64×64+1×1×256×64=69632
2)先降后升为了主分支上输出的特征矩阵和捷径分支上输出的特征矩阵形状相同,以便进行加法操作。
当F(X)和X的shape不同,但仍要添加捷径 shortcut 时,该怎么办呢?
将残差块的 shortcut 由实线变为虚线,并在虚线的 shortcut 上通过1×1的卷积核进行了维度处理(特征矩阵在长宽方向降采样,深度方向调整成下一层残差结构所需要的channel)。
下图为原论文给出的不同深度的ResNet网络结构配置,注意表中的残差结构给出了主分支上卷积核的大小与卷积核个数,表中的xN表示将该残差结构重复N次。
对于我们ResNet18/34/50/101/152,表中conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层残差结构都是虚线残差结构。因为这一系列残差结构的第一层都有调整输入特征矩阵shape的使命(将特征矩阵的高和宽缩减为原来的一半,将深度channel调整成下一层残差结构所需要的channel)。
论文中给出了一个网络结构的对比示例: