MMdetection中Backbone的实现-ResNet50

ResNet50的源码路径为mmdet/models/backbones/resnet.py

ResNet系列网络是经典网络之一,后续很多变种(如ResNeXt和ResNeSt等)和其他网络都借鉴了其残差块结构,首先先对一些结构名词做一些解释,便于理解。残差块,即Residual Block,也就是接下来要讲解的BasicBlock和Bottleneck两个基本模块,若干卷积层、归一化层和激活层构成上述两个基本模块,若干基本模块构成一个stage,若干stage构成整体的网络。

ResNet根据网络层数不同,可分为5个模型。分别是ResNet-18、ResNet-34、ResNet-50、ResNet-101和ResNet-152。

MMdetection中Backbone的实现-ResNet50_第1张图片除了网络层数不同外,构成模型的基础结构也有所差异,ResNet-18和ResNet-34的基础结构为BasicBlock,其他模型的基础结构为Bottleneck。两者的结构如下图所示(图像截取自B站大佬的讲解视频),左侧为BasicBlock结构,右侧为Bottleneck结构。

 

MMdetection中Backbone的实现-ResNet50_第2张图片

一、BasicBlock

该结构较为简单,__init__()中定义了相关的卷积、归一化和激活函数操作,forward()中定义特征图的前向传播路径。

需要注意的是,每个stage之间输出特征矩阵的维度不同,例如第一个stage(即表格中的conv2_x)输出特征矩阵为56*56*64,该特征矩阵作为输入,会输入到第二个stage(即表格中的conv3_x)中,因此第二个stage中的第一个BasicBlock的捷径分支需要对channel维度进行相应的升维处理,由64变为128,;同时主分支对空间维度进行下采样,由56*56变为28*28,对通道维度进行升维处理,由64变为128,最后完成相加操作。

因此,我们需要对每一个stage的第一个残差块做特殊设置。

MMdetection中Backbone的实现-ResNet50_第3张图片

 

二、Bottleneck

该结构是构建层数较深模型的基本结构,采用1×1的卷积操作目的是减少参数量,特别是在层数较多的模型中,可以减少相当数量的参数,具体参数量的计算参考讲解视频。

在初始化函数中,style关键字参数有'pytorch'和'caffe'两种选择,区别在于前者将stride=2(即空间维度的下采样操作)整合在3×3卷积中,后者整合在第一个1×1卷积中;

同时,该结构还支持plugin(类似于插件),插入的位置在三个卷积层之后;

三、ResNet

首先介绍结构配置:

    arch_settings = {
        18: (BasicBlock, (2, 2, 2, 2)),
        34: (BasicBlock, (3, 4, 6, 3)),
        50: (Bottleneck, (3, 4, 6, 3)),
        101: (Bottleneck, (3, 4, 23, 3)),
        152: (Bottleneck, (3, 8, 36, 3))
    }

结构配置中指定了网络深度,残差块类型和每个stage中残差块的个数;

接下来介绍初始化参数的含义:

def __init__(self,
             # 网络深度
             depth,
             # 输入图像的channel数
             in_channels=3,
             # 主干卷积层的channel数,默认等于base_channels
             stem_channels=None,
             base_channels=64,
             # stage数量
             num_stages=4,
             # 每个stage第一个残差块的stride参数
             strides=(1, 2, 2, 2),
             # 膨胀(空洞)卷积参数设置
             dilations=(1, 1, 1, 1),
             # 输出特征图的索引,每个stage对应一个
             out_indices=(0, 1, 2, 3),
             # 风格设置
             style='pytorch',
             # 是否用3个3×3的卷积核代替主干上1个7×7的卷积核
             deep_stem=False,
             # 是否使用平均池化代替stride为2的卷积操作进行下采样
             avg_down=False,
             # 冻结层数,-1表示不冻结
             frozen_stages=-1,
             # 构建卷积层的配置
             conv_cfg=None,
             # 构建归一化层的配置
             norm_cfg=dict(type='BN', requires_grad=True),
             norm_eval=True,
             # 是否使用dcn(可变形卷积)
             dcn=None,
             # 指定哪个stage使用dcn
             stage_with_dcn=(False, False, False, False),
             plugins=None,
             with_cp=False,
             # 是否对残差块进行0初始化
             zero_init_residual=True,
             # 预训练模型(已弃用,若指定会自动调用init_cfg)
             pretrained=None,
             # 指定预训练模型
             init_cfg=None):

由于篇幅有限,暂不解析源码中每个函数的实现过程,大家可根据参数的含义推断函数功能并自行阅读源码。

你可能感兴趣的:(目标检测,MMdetection,深度学习,人工智能,python,目标检测,pytorch)