Deep Residual Learning for Image Recognition原论文名字

ResNet34层模型的结构简图:

resnet34 resnet34结构图_深度学习


图中有连接线的结构是残差结构,最后通过一个平均下采样操作和一个全连接层得到最终的输出。

网络中的亮点:

1.超深的网络结构(突破1000层)

从下图可以看出单纯的堆叠卷积层和最大池化下采样层去堆叠网络并不是层度越深效果越好

原作者提出了两个问题:

1.1随着网络的层数不断加深,梯度消失以及梯度爆炸这个问题会越来越明显

梯度消失和梯度爆炸
若每一层的误差梯度小于1,反向传播时,网络越深,梯度越趋近于0
反之,若每一层的误差梯度大于1,反向传播时,网路越深,梯度越来越大

resnet34 resnet34结构图_resnet34_02

1.2退化问题

在解决了梯度消失、爆炸问题后,仍然存在深层网络的效果可能比浅层网络差的现象

resnet34 resnet34结构图_卷积_03

  • 对于梯度消失或梯度爆炸问题,ResNet论文提出通过数据的预处理以及在网络中使用 BN(Batch Normalization)层来解决。
  • 对于退化问题,ResNet论文提出了 residual结构(残差结构)来减轻退化问题,下图是使用residual结构的卷积网络,可以看到随着网络的不断加深,效果并没有变差,而是变的更好了。(虚线是train error,实线是test error)

2.提出residual模块

redidual模块,也就是残差模块,才可以搭建这么深的网络。

这里有两个分支,主分支通过一系列卷积层,侧分支(short cut原论文为捷径的意思)和运算完后的主分支相加(这里要注意主分支和侧分支的高宽深度要相同)再进行和一次激励函数。

resnet34 resnet34结构图_深度学习_04


这里1*1的卷积核用来降温和升维,大大的减小了深层结构的所需参数量

可以计算一下,假设两个残差结构的输入特征和输出特征矩阵的深度都是256维,如下图:(注意左侧结构的改动)

resnet34 resnet34结构图_深度学习_05


那么两个残差结构所需的参数为:

  • 左侧:3 × 3 × 256 × 256 + 3 × 3 × 256 × 256 = 1 , 179 , 648
  • 右侧:1 × 1 × 256 × 64 + 3 × 3 × 64 × 64 + 1 × 1 × 64 × 256 = 69 , 632
    注:CNN参数个数 = 卷积核尺寸×卷积核深度 × 卷积核组数 = 卷积核尺寸 × 输入特征矩阵深度 × 输出特征矩阵深度
    明显搭建深层网络时,使用右侧的残差结构更合适。

下图是原论文给出的不同深度的ResNet网络结构配置,注意表中的残差结构给出了主分支上卷积核的大小与卷积核个数,表中 残差块×N 表示将该残差结构重复N次。

resnet34 resnet34结构图_深度学习_06


以34层网络结构为例

resnet34 resnet34结构图_方差_07


首先是一个77的卷积层,第二层一个33的最大池化下采样操作,在这里又将残差结构分为conv2_x一系列残差结构(对应图中使用了三个),conv3_x一系列残差结构(4个),conv4_x一系列残差结构(6个),conv5_x一系列残差结构(3个),然后就是平均池化下采样和全连接层。

细心的话可以看见在34层网络结构中short cut是存在不同的,有实线和虚线的区别。

residual结构

resnet34 resnet34结构图_resnet34_08


原文的标注中说明,在conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层残差结构都是虚线残差结构。因为这一系列残差结构的第一层都有调整输入特征矩阵shape的使命(将特征矩阵的高和宽缩减为原来的一半,将深度channel调整成下一层残差结构所需要的channel)

resnet34 resnet34结构图_方差_09


需要注意的是,对于ResNet50/101/152,其实conv2_x所对应的一系列残差结构的第一层也是虚线残差结构,因为它需要调整输入特征矩阵的channel。根据表格可知通过3x3的max pool之后输出的特征矩阵shape应该是[56, 56, 64],但conv2_x所对应的一系列残差结构中的实线残差结构它们期望的输入特征矩阵shape是[56, 56, 256](因为这样才能保证输入输出特征矩阵shape相同,才能将捷径分支的输出与主分支的输出进行相加)。所以第一层残差结构需要将shape从[56, 56, 64] --> [56, 56, 256]。注意,这里只调整channel维度,高和宽不变(而conv3_x, conv4_x, conv5_x所对应的一系列残差结构的第一层虚线残差结构不仅要调整channel还要将高和宽缩减为原来的一半)。

3.使用Batch Normalization加速训练(丢弃dropout)

Batch Normalization是google团队在2015年论文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》提出的。通过该方法能够加速网络的收敛并提升准确率。

3.1Batch Normalization原理

resnet34 resnet34结构图_卷积核_10


我们在图像预处理过程中通常会对图像进行标准化处理,这样能够加速网络的收敛,如下图所示,对于Conv1来说输入的就是满足某一分布的特征矩阵,但对于Conv2而言输入的feature map就不一定满足某一分布规律了(注意这里所说满足某一分布规律并不是指某一个feature map的数据要满足分布规律,理论上是指整个训练样本集所对应feature map的数据要满足分布规律)。而我们Batch Normalization的目的就是使我们的feature map满足均值为0,方差为1的分布规律。

resnet34 resnet34结构图_卷积_11


“对于一个拥有d维的输入x,我们将对它的每一个维度进行标准化处理。” 假设我们输入的x是RGB三通道的彩色图像,那么这里的d就是输入图像的channels即d=3,,其中就代表我们的R通道所对应的特征矩阵,依此类推。标准化处理也就是分别对我们的R通道,G通道,B通道进行处理。上面的公式不用看,原文提供了更加详细的计算公式:

注意的是这里的计算是一批数据所有在这一通道上的均值和方差

resnet34 resnet34结构图_resnet34_12


gama是用来调整数值分布的方差大小,beta是用来调节数值均值的位置。这两个参数是在反向传播过程中学习得到的,gama的默认值是1,beta的默认值是0。

下面是BN求解的一个实例,得到的是矩阵结果

resnet34 resnet34结构图_方差_13


3.2使用BN时需要注意的问题

(1)训练时要将traning参数设置为True,在验证时将trainning参数设置为False。在pytorch中可通过创建模型的model.train()和model.eval()方法控制。

(2)batch size尽可能设置大点,设置小后表现可能很糟糕,设置的越大求的均值和方差越接近整个训练集的均值和方差。

(3)建议将bn层放在卷积层(Conv)和激活层(例如Relu)之间,且卷积层不要使用偏置bias,因为没有用,参考下图推理,即使使用了偏置bias求出的结果也是一样的

resnet34 resnet34结构图_卷积核_14