ResNet在2015年由微软实验室提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。获得COCO数据集中目标检测第一名,图像分割第一名。
一、要点
- 超深的网络结构(突破1000层)
- 提出residual模块(即残差模块)
- 使用Batch Normalization加速训练(丢弃dropout)
- 在ResNet提出之前,所有的神经网络都是通过卷积层和池化层的叠加组成的。人们认为卷积层和池化层的层数越多,获取到的图片特征信息越全,学习效果也就越好。但简单的使用卷积层和池化层进行深度叠加,效果不会越来越好,这是由于梯度消失或梯度爆炸问题,解决这个问题可以用对数据进行标准化处理、权重初始化、BN(Batch Normalization)来解决
- 梯度消失:假设每一层的误差梯度是小于1的数,反向传播过程中每向前传播一层,都要乘以一个小于1的误差梯度。当网络越来越深时,所乘的小于1的系数就越多,梯度就越趋近于0
- 梯度爆炸:假设每一层的误差梯度是大于1的数,反向传播过程中每向前传播一层,都要乘以一个大于1的误差梯度。当网络越来越深时,梯度越来越大
- 尽管采取了解决办法来解决梯度消失或梯度爆炸的问题,但层数深的网络可能还是没有层数少的网络好,解决退化问题可以使用残差结构、BN
二、残差结构(residual结构)
- 左边针对网络层数较少的网络所使用的残差结构(34层)
- 右边针对网络层数较多的网络所使用的残差结构(50/101/152层)
- 主分支与侧分支(shortcut捷径分支)的输出矩阵shape必须相同(高、宽、通道数相同)
- 右边在输入和输出都加上了1×1的卷积层,降维再升维(256→64→256),保证shape相同的情况下减少参数。使用的残差结构越多,减少的参数就越多。
若左图改成输入通道数为256,卷积核个数也为256,即:
然后与右图进行对比,
左图的参数个数:256×3×3×256 + 256×3×3×256 = 1,179,648
右图的参数个数:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632
shortcut分支为实线的残差结构和shortcut分支为虚线的残差结构:
(34层)
- shortcut分支为实线的残差结构:stride=1
- 输入特征矩阵和输出特征矩阵的shape相同,可以直接进行相加
- shortcut分支为虚线的残差结构:stride=2
- 输入特征矩阵shape是[56,56,64],输出特征矩阵shape是[28,28,128]
- 虚线对特征矩阵的高、宽、深度都进行变换
- 通过步长stride变为2,使尺寸缩减为原来的一半
- 输入特征矩阵shape是[56,56,64],输出特征矩阵shape是[28,28,128]
(50/101/152层)
- shortcut分支为实线的残差结构:stride=1
- 输入特征矩阵和输出特征矩阵的shape相同,可以直接进行相加
- 第一层 stride=1,卷积核1×1×128,只降低特征矩阵深度,[56,56,128]
- 第二层 stride=2,卷积核3×3×128,宽高变为原来的一半,[28,28,128]
- 第一层 stride=1,卷积核1×1×512,只增加特征矩阵深度,[28,28,512]
- 输入特征矩阵和输出特征矩阵的shape相同,可以直接进行相加
- shortcut分支为虚线的残差结构:stride=2
- 输入特征矩阵shape是[56,56,256],输出特征矩阵shape是[28,28,512]
- 虚线对特征矩阵的高、宽、深度都进行变换
- 通过步长stride变为2,使尺寸缩减为原来的一半
- 输入特征矩阵shape是[56,56,256],输出特征矩阵shape是[28,28,512]
三、ResNet网络结构
- 对于浅层网络(18/34层)
- conv3_x、conv4_x、conv5_x的第一层均采用虚线残差结构
- 通过最大池化下采样得到的输出是[56,56,64],刚好是实现残差结构所需要的输入shape,此时conv2_x第一层不需要使用虚线残差结构
- 对于深层网络(50/101/152层)
- 通过最大池化下采样得到的输出是[56,56,64],而所需的shape为[56,56,256],此时conv2_x第一层需要使用虚线残差结构,但仅改变特征矩阵的深度,不改变宽高
- conv3_x、conv4_x、conv5_x的第一层虚线残差结构不仅改变特征矩阵的深度,还改变了宽高
四、Batch Normalization
https://blog.csdn.net/qq_37541097/article/details/104434557
Batch Normalization的目的:使我们的一批(Batch)数据所对应的feature map(特征矩阵)每一个通道所对应的维度满足均值为0,方差为1的分布规律。
我们在图像预处理过程中通常会对图像进行标准化处理,这样能够加速网络的收敛,如下图所示,
对于Conv1来说输入的就是满足某一分布的特征矩阵,但对于Conv2而言输入的feature map就不一定满足某一分布规律。而我们Batch Normalization的目的就是使我们的feature map满足均值为0,方差为1的分布规律。
注意这里所说满足某一分布规律并不是指某一个feature map的数据要满足分布规律,理论上是指整个训练样本集所对应feature map的数据要满足分布规律
计算公式:
“对于一个拥有d维的输入x,我们将对它的每一个维度进行标准化处理。” 假设我们输入的x是RGB三通道的彩色图像,那么这里的d就是输入图像的channels即d=3,,其中
就代表我们的R通道所对应的特征矩阵,依此类推。标准化处理也就是分别对我们的R通道,G通道,B通道进行处理。
- μ,σ²是在正向传播过程中统计得到
- γ,β是通过反向传播训练得到,初始值分别为1和0
- ϵ是一个很小的数,防止分母为0
Batch Normalization,也就是我们计算一个Batch数据的feature map然后在进行标准化(batch越大越接近整个数据集的分布,效果越好)。
根据公式可以知道代表着计算的feature map每个维度(channel)的均值(注意
是一个向量不是一个值,
向量的每一个元素代表着一个维度(channel)的均值)。
代表着我们计算的feature map每个维度(channel)的方差(注意
是一个向量不是一个值,
向量的每一个元素代表着一个维度(channel)的方差),然后根据和计算标准化处理后得到的值。
注意事项:
(1)训练时要将traning参数设置为True,在验证时将trainning参数设置为False。在pytorch中可通过创建模型的model.train()和model.eval()方法控制。
(2)batch size尽可能设置大点,设置小后表现可能很糟糕,设置的越大求的均值和方差越接近整个训练集的均值和方差。
(3)建议将bn层放在卷积层(Conv)和激活层(例如Relu)之间,且卷积层不要使用偏置bias,因为没有用,即使使用了偏置bias求出的结果也是一样的。