利用MMDetection进行模型微调和权重初始化

目录

  • 模型微调
    • 修改第一处:更少的训练回合Epoch
    • 修改第二处:更小的学习率Learning Rate
    • 修改第三处:使用预训练模型
  • 权重初始化
    • 实际使用案例
    • init_cfg 的具体使用规则
    • 初始化器配置汇总

本文基于 MMDetection官方文档,对模型微调和权重初始化进行第三方讲解。

在这里插入图片描述

模型微调

在 COCO 数据集上预训练的检测器可以作为其他数据集优质的预训练模型。
微调超参数与默认的训练策略不同。它通常需要更小的学习率和更少的训练回合。根据配置文件最上方继承父类文件路径_base_的位置找到与优化和训练测试相关的配置文件,我选择的Faster R-CNN子配置文件的对应父类文件位于mmdetection/configs/common/ms_3x_coco.py,为了不修改官方已经继承的配置文件,我们可以选择新建一个文件进行,例如修改为mmdetection/configs/common/ms_3x_coco_finetuning.py。在进行下列步骤之前,请确保数据集与配置文件相匹配,并且检测头roi_headnum_classes与数据集类别数相匹配,参考利用MMDetection在自定义数据集上进行训练

修改第一处:更少的训练回合Epoch

train_cfg = dict(type='EpochBasedTrainLoop', max_epochs=8, val_interval=1)
# max_epochs = 12 → 8

修改第二处:更小的学习率Learning Rate

optim_wrapper = dict(
    type='OptimWrapper',
    optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001))
# lr = 0.002 → 0.001

修改第三处:使用预训练模型

load_from = '/home/miqi/mmdetection/checkpoints/faster_rcnn_r50_fpn_mstrain_3x_coco_20210524_110822-e10bd31c.pth'

权重初始化

在训练过程中,适当的初始化策略有利于加快训练速度或获得更⾼的性能。 MMCV 提供了一些常⽤的初始化模块的⽅法,如 nn.Conv2d。 MMdetection中的模型初始化主要使⽤ init_cfg

实际使用案例

例如在mmdetection/mmdet/models/necks/fpn.py

@MODELS.register_module()
class FPN(BaseModule):
    def __init__(
            self,
            in_channels: List[int],
            out_channels: int,
            num_outs: int,
            start_level: int = 0,
            end_level: int = -1,
            add_extra_convs: Union[bool, str] = False,
            relu_before_extra_convs: bool = False,
            no_norm_on_lateral: bool = False,
            conv_cfg: OptConfigType = None,
            norm_cfg: OptConfigType = None,
            act_cfg: OptConfigType = None,
            upsample_cfg: ConfigType = dict(mode='nearest'),
            init_cfg: MultiConfig = dict(
                type='Xavier', layer='Conv2d', distribution='uniform')
        ) -> None:
        super().__init__(init_cfg=init_cfg)

我们可以对该文件的init_cfg部分进行修改,但这样会破坏该组件与其他配置文件之间的的集成性,最好的方法是在子类配置文件中复写init_cfg部分,例如在mmdetection/configs/_base_/models/faster-rcnn_r50_fpn.py中的model设置模块找到neck组件

# model settings
model = dict(
    type='FasterRCNN',
    neck=dict(
        type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        num_outs=5))

__init__初始化中的'Xavier'修改为'kaiming'并复写入neck组件的init_cfg,这一步就是完成了对卷积层从Xavier初始化更换为使用Kaiming初始化的操作

neck=dict(
        type='FPN',
        in_channels=[256, 512, 1024, 2048],
        out_channels=256,
        num_outs=5,
        init_cfg = dict(
            type='kaiming', layer='Conv2d', distribution='uniform'))

init_cfg 的具体使用规则

  1. layer 键初始化模型

    如果我们只定义了 layer, 它只会在 layer 键中初始化网络层。

    注意: layer 键对应的值是 Pytorch 的带有 weights 和 bias 属性的类名(因此不⽀持 MultiheadAttention 层)。

  • 定义⽤于初始化具有相同配置的模块的 layer 键。

    init_cfg = dict(type='Constant', layer=['Conv1d', 'Conv2d', 'Linear'], val=1)
    # ⽤相同的配置初始化整个模块
    
  • 定义⽤于初始化具有不同配置的层的 layer 键。

    init_cfg = [dict(type='Constant', layer='Conv1d', val=1),
                dict(type='Constant', layer='Conv2d', val=2),
                dict(type='Constant', layer='Linear', val=3)]
    # nn.Conv1d 将被初始化为 dict(type='Constant', val=1)
    # nn.Conv2d 将被初始化为 dict(type='Constant', val=2)
    # nn.Linear 将被初始化为 dict(type='Constant', val=3)
    
  1. 使⽤ override 键初始化模型
  • 当使⽤属性名初始化某些特定部分时,我们可以使⽤ override 键, override 中的值将忽略 init_cfg 中的值。

    # layers:
    # self.feat = nn.Conv1d(3, 1, 3)
    # self.reg = nn.Conv2d(3, 3, 3)
    # self.cls = nn.Linear(1,2)
    
    init_cfg = dict(type='Constant',
                    layer=['Conv1d','Conv2d'], val=1, bias=2,
                    override=dict(type='Constant', name='reg', val=3, bias=4))
    # self.feat and self.cls 将被初始化为 dict(type='Constant', val=1, bias=2)
    # 叫 'reg' 的模块将被初始化为 dict(type='Constant', val=3, bias=4)
    
  • 如果 init_cfg 中的 layer 为 None,则只会初始化 override 中有 name 的⼦模块,⽽ override 中的 type 和其他参数可以省略。

    # layers:
    # self.feat = nn.Conv1d(3, 1, 3)
    # self.reg = nn.Conv2d(3, 3, 3)
    # self.cls = nn.Linear(1,2)
    
    init_cfg = dict(type='Constant', val=1, bias=2, 	override=dict(name='reg'))
    
    # self.feat and self.cls 将被 Pytorch 初始化
    # 叫 'reg' 的模块将被 dict(type='Constant', val=1, bias=2) 初始化
    
  • 如果我们不定义 layeroverride 键,它不会初始化任何东西。

  • 无效的使用

    # override 没有 name 键的话是无效的
    init_cfg = dict(type='Constant', layer=['Conv1d','Conv2d'], val=1, bias=2,
                	override=dict(type='Constant', val=3, bias=4))
    
    # override 有 name 键和其他参数但是没有 type 键也是无效的
    init_cfg = dict(type='Constant', layer=['Conv1d','Conv2d'], val=1, bias=2,
                    override=dict(name='reg', val=3, bias=4))
    
  1. 使⽤预训练模型初始化模型

    init_cfg = dict(type='Pretrained',
                 checkpoint='torchvision://resnet50')
    

初始化器配置汇总

我们可以通过配置 init_cfg 为模型中任意组件灵活地选择初始化方式。目前我们可以在 init_cfg 中配置以下初始化器:

InitializerRegistered nameFunction
ConstantInitConstant将 weight 和 bias 初始化为指定常量,通常用于初始化卷积
XavierInitXavier将 weight Xavier 方式初始化,将 bias 初始化成指定常量,通常用于初始化卷积
NormalInitNormal将 weight 以正态分布的方式初始化,将 bias 初始化成指定常量,通常用于初始化卷积
TruncNormalInitTruncNormal将 weight 以被截断的正态分布的方式初始化,参数 a 和 b 为正态分布的有效区域;将 bias 初始化成指定常量,通常用于初始化 Transformer
UniformInitUniform将 weight 以均匀分布的方式初始化,参数 a 和 b 为均匀分布的范围;将 bias 初始化为指定常量,通常用于初始化卷积
KaimingInitKaiming将 weight 以 Kaiming 的方式初始化,将 bias 初始化成指定常量,通常用于初始化卷积
Caffe2XavierInitCaffe2XavierCaffe2 中 Xavier 初始化方式,在 Pytorch 中对应 “fan_in”, “normal” 模式的 Kaiming 初始化,,通常用于初始化卷
PretrainedPretrainedInit加载预训练权重

本贴后续会利用Faster R-CNN对预训练权重初始化和常用初始化进行实验,详情教程请见MMEgine权重初始化

### 训练自定义模型 为了使用 `mmdetection` 框架训练自己的检测模型,需遵循一系列配置操作流程。首先,环境搭建至关重要。通过克隆官方仓库并安装必要的依赖来初始化工作环境[^3]。 ```bash git clone https://github.com/open-mmlab/mmdetection.git cd mmdetection pip install mmcv cython pip install albumentations>=0.3.2 imagecorruptions pycocotools six terminaltables python setup.py develop ``` #### 准备数据集 对于特定应用的数据集准备是必不可少的一环。通常情况下,这涉及到将原始图像及其标注转换成 COCO 或者其他支持的格式。确保标签文件与图片路径匹配,并按照文档说明组织好文件夹结构。 #### 修改配置文件 创建一个新的配置文件用于描述所要训练的新模型参数设置。此过程可能涉及调整网络架构、优化器选项以及学习率策略等方面的内容。基于现有模型进行微调时可以利用预训练权重加快收敛速度[^2]。 ```yaml # example of a config file snippet model = dict( type='FasterRCNN', pretrained='torchvision://resnet50', # Use pre-trained model weights backbone=dict(type='ResNet', depth=50), ... ) data = dict( samples_per_gpu=2, workers_per_gpu=2, train=dict(...), val=dict(...), test=dict(...) ) optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) lr_config = dict(policy='step', warmup='linear', warmup_iters=500, warmup_ratio=0.001, step=[8, 11]) total_epochs = 12 ``` #### 开始训练 完成上述准备工作后即可启动训练进程。可以通过简单的命令行指令指定使用的GPU数量以及其他运行参数: ```bash ./tools/dist_train.sh ${CONFIG_FILE} ${GPUS} ``` 其中 `${CONFIG_FILE}` 是之前编辑好的配置文件路径;`${GPUS}` 表示参与计算的 GPU 数量。此外,在遇到网络连接问题无法获取某些软件包的情况下,建议尝试清华镜像源加速下载,必要时采用离线方式解决依赖关系。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值