目录

1、配置文件以及权重命名规则

1.1 算法信息

1.2 模块信息

1.3训练信息

1.4 数据信息

1.5 配置文件命名案例

 2、权重命名规则

3、 配置文件结构

3.1模型配置信息

3.2数据配置信息

3.3 训练策略配置信息

3.4 运行设置配置信息

3.5继承并修改配置文件

3.6使用配置文件里的中间变量

3.7忽略基础配置文件里的部分内容

3.8 引用基础配置文件里的变量

3.9导入用户自定义模块

4、如何微调模型(迁移学习)

4.1 继承基础配置

4.2 修改模型

4.3 修改数据集

4.4修改训练策略设置

开始训练

5、如何自定义数据集  

6、如何设计数据处理流程 

7、 如何增加新模块

8、 如何自定义优化策略

9、如何自定义模型运行参数 

10、模型推理

6、模型训练 

11、可视化

前言:

参考官网:欢迎来到 MMClassification 中文教程! — MMClassification 0.25.0 文档

1、配置文件以及权重命名规则

        文件名总体分为四部分:算法信息,模块信息,训练信息和数据信息。逻辑上属于不同部分的单词之间用下划线 '_' 连接,同一部分有多个单词用短横线 '-' 连接。

    {algorithm info}_{module info}_{training info}_{data info}.py
  • algorithm info:算法信息,算法名称或者网络架构,如 resnet 等;

  • module info: 模块信息,因任务而异,用以表示一些特殊的 neck、head 和 pretrain 信息;

  • training info:一些训练信息,训练策略设置,包括 batch size,schedule 数据增强等;

  • data info:数据信息,数据集名称、模态、输入尺寸等,如 imagenet, cifar 等;

1.1 算法信息

指论文中的算法名称缩写,以及相应的分支架构信息。例如:

  • resnet50

  • mobilenet-v3-large

  • vit-small-patch32 : patch32 表示 ViT 切分的分块大小

  • seresnext101-32x4d : SeResNet101 基本网络结构,32x4d 表示在 Bottleneck 中 groups 和 width_per_group 分别为32和4

1.2 模块信息

指一些特殊的 neck 、head 或者 pretrain 的信息, 在分类中常见为预训练信息,比如:

  • in21k-pre : 在 ImageNet21k 上预训练

  • in21k-pre-3rd-party : 在 ImageNet21k 上预训练,其权重来自其他仓库

1.3训练信息

训练策略的一些设置,包括训练类型、 batch size、 lr schedule、 数据增强以及特殊的损失函数等等,比如: Batch size 信息:

  • 格式为{gpu x batch_per_gpu}, 如 8xb32

训练类型(主要见于 transformer 网络,如 ViT 算法,这类算法通常分为预训练和微调两种模式):

  • ft : Finetune config,用于微调的配置文件

  • pt : Pretrain config,用于预训练的配置文件

训练策略信息,训练策略以复现配置文件为基础,此基础不必标注训练策略。但如果在此基础上进行改进,则需注明训练策略,按照应用点位顺序排列,如:{pipeline aug}-{train aug}-{loss trick}-{scheduler}-{epochs}

  • coslr-200e : 使用 cosine scheduler, 训练 200 个 epoch

  • autoaug-mixup-lbs-coslr-50e : 使用了 autoaugmixuplabel smoothcosine scheduler, 训练了 50 个轮次

1.4 数据信息

  • in1k : ImageNet1k 数据集,默认使用 224x224 大小的图片

  • in21k : ImageNet21k 数据集,有些地方也称为 ImageNet22k 数据集,默认使用 224x224 大小的图片

  • in1k-384px : 表示训练的输出图片大小为 384x384

  • cifar100

1.5 配置文件命名案例

repvgg-D2se_deploy_4xb64-autoaug-lbs-mixup-coslr-200e_in1k.py
  • repvgg-D2se: 算法信息

    • repvgg: 主要算法名称。

    • D2se: 模型的结构。

  • deploy:模块信息,该模型为推理状态。

  • 4xb64-autoaug-lbs-mixup-coslr-200e: 训练信息

    • 4xb64: 使用4块 GPU 并且 每块 GPU 的批大小为64。

    • autoaug: 使用 AutoAugment 数据增强方法。

    • lbs: 使用 label smoothing 损失函数。

    • mixup: 使用 mixup 训练增强方法。

    • coslr: 使用 cosine scheduler 优化策略。

    • 200e: 训练 200 轮次。

  • in1k: 数据信息。 配置文件用于 ImageNet1k 数据集上使用 224x224 大小图片训练。

 2、权重命名规则

权重的命名主要包括配置文件名,日期和哈希值。

{config_name}_{date}-{hash}.pth
convnext-base_3rdparty_32xb128_in1k_20220124-d0915162.pth

3、 配置文件结构

在 configs/_base_ 文件夹下有 4 个基本组件类型,分别是:

  • 模型(model)

  • 数据(data)

  • 训练策略(schedule)

  • 运行设置(runtime)

ResNet原始配置文件:

_base_ = [
    '../_base_/models/resnet50.py',           # 模型
    '../_base_/datasets/imagenet_bs32.py',    # 数据
    '../_base_/schedules/imagenet_bs256.py',  # 训练策略
    '../_base_/default_runtime.py'            # 默认运行设置
]

3.1模型配置信息

模型参数 model 在配置文件中为一个 python 字典,主要包括网络结构、损失函数等信息:

  • type : 分类器名称, 目前 MMClassification 只支持 ImageClassifier, 参考 API 文档

  • backbone : 主干网类型,可用选项参考 API 文档

  • neck : 颈网络类型,目前 MMClassification 只支持 GlobalAveragePooling, 参考 API 文档

  • head : 头网络类型, 包括单标签分类与多标签分类头网络,可用选项参考 API 文档

  • train_cfg :训练配置, 支持 mixupcutmix 等训练增强。

备注

配置文件中的 ‘type’ 不是构造时的参数,而是类名。

model = dict(
    type='ImageClassifier',     # 分类器类型
    backbone=dict(
        type='ResNet',          # 主干网络类型
        depth=50,               # 主干网网络深度, ResNet 一般有18, 34, 50, 101, 152 可以选择
        num_stages=4,           # 主干网络状态(stages)的数目,这些状态产生的特征图作为后续的 head 的输入。
        out_indices=(3, ),      # 输出的特征图输出索引。越远离输入图像,索引越大
        frozen_stages=-1,       # 网络微调时,冻结网络的stage(训练时不执行反相传播算法),若num_stages=4,backbone包含stem 与 4 个 stages。frozen_stages为-1时,不冻结网络; 为0时,冻结 stem; 为1时,冻结 stem 和 stage1; 为4时,冻结整个backbone
        style='pytorch'),       # 主干网络的风格,'pytorch' 意思是步长为2的层为 3x3 卷积, 'caffe' 意思是步长为2的层为 1x1 卷积。
    neck=dict(type='GlobalAveragePooling'),    # 颈网络类型
    head=dict(
        type='LinearClsHead',     # 线性分类头,
        num_classes=1000,         # 输出类别数,这与数据集的类别数一致
        in_channels=2048,         # 输入通道数,这与 neck 的输出通道一致
        loss=dict(type='CrossEntropyLoss', loss_weight=1.0), # 损失函数配置信息
        topk=(1, 5),              # 评估指标,Top-k 准确率, 这里为 top1 与 top5 准确率
    ))

3.2数据配置信息

数据参数 data 在配置文件中为一个 python 字典,主要包含构造数据集加载器(dataloader)配置信息:

  • samples_per_gpu : 构建 dataloader 时,每个 GPU 的 Batch Size

  • workers_per_gpu : 构建 dataloader 时,每个 GPU 的 线程数

  • train | val | test : 构造数据集

    • type : 数据集类型, MMClassification 支持 ImageNet、 Cifar 等 ,参考API 文档

    • data_prefix : 数据集根目录

    • pipeline : 数据处理流水线,参考相关教程文档 如何设计数据处理流水线

评估参数 evaluation 也是一个字典, 为 evaluation hook 的配置信息, 主要包括评估间隔、评估指标等。

# dataset settings
dataset_type = 'ImageNet'  # 数据集名称,
img_norm_cfg = dict(       #图像归一化配置,用来归一化输入的图像。
    mean=[123.675, 116.28, 103.53],  # 预训练里用于预训练主干网络模型的平均值。
    std=[58.395, 57.12, 57.375],     # 预训练里用于预训练主干网络模型的标准差。
    to_rgb=True)                     # 是否反转通道,使用 cv2, mmcv 读取图片默认为 BGR 通道顺序,这里 Normalize 均值方差数组的数值是以 RGB 通道顺序, 因此需要反转通道顺序。
# 训练数据流水线
train_pipeline = [
    dict(type='LoadImageFromFile'),                # 读取图片
    dict(type='RandomResizedCrop', size=224),      # 随机缩放抠图
    dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),  # 以概率为0.5随机水平翻转图片
    dict(type='Normalize', **img_norm_cfg),        # 归一化
    dict(type='ImageToTensor', keys=['img']),      # image 转为 torch.Tensor
    dict(type='ToTensor', keys=['gt_label']),      # gt_label 转为 torch.Tensor
    dict(type='Collect', keys=['img', 'gt_label']) # 决定数据中哪些键应该传递给检测器的流程
]
# 测试数据流水线
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='Resize', size=(256, -1)),
    dict(type='CenterCrop', crop_size=224),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='Collect', keys=['img'])             # test 时不传递 gt_label
]
data = dict(
    samples_per_gpu=32,    # 单个 GPU 的 Batch size
    workers_per_gpu=2,     # 单个 GPU 的 线程数
    train=dict(            # 训练数据信息
        type=dataset_type,                  # 数据集名称
        data_prefix='data/imagenet/train',  # 数据集目录,当不存在 ann_file 时,类别信息从文件夹自动获取
        pipeline=train_pipeline),           # 数据集需要经过的 数据流水线
    val=dict(              # 验证数据集信息
        type=dataset_type,
        data_prefix='data/imagenet/val',
        ann_file='data/imagenet/meta/val.txt',   # 标注文件路径,存在 ann_file 时,不通过文件夹自动获取类别信息
        pipeline=test_pipeline),
    test=dict(             # 测试数据集信息
        type=dataset_type,
        data_prefix='data/imagenet/val',
        ann_file='data/imagenet/meta/val.txt',
        pipeline=test_pipeline))
evaluation = dict(       # evaluation hook 的配置
    interval=1,          # 验证期间的间隔,单位为 epoch 或者 iter, 取决于 runner 类型。
    metric='accuracy')   # 验证期间使用的指标。

3.3 训练策略配置信息

主要包含 优化器设置、 optimizer hook 设置、学习率策略和 runner设置:

  • optimizer : 优化器设置信息, 支持 pytorch 所有的优化器,参考相关 mmcv 文档

  • optimizer_config : optimizer hook 的配置文件,如设置梯度限制,参考相关 mmcv 代码

  • lr_config : 学习率策略,支持 “CosineAnnealing”、 “Step”、 “Cyclic” 等等,参考相关 mmcv 文档

  • runner : 有关 runner 可以参考 mmcv 对于 runner 介绍文档

# 用于构建优化器的配置文件。支持 PyTorch 中的所有优化器,同时它们的参数与 PyTorch 里的优化器参数一致。
optimizer = dict(type='SGD',         # 优化器类型
                lr=0.1,              # 优化器的学习率,参数的使用细节请参照对应的 PyTorch 文档。
                momentum=0.9,        # 动量(Momentum)
                weight_decay=0.0001) # 权重衰减系数(weight decay)。
 # optimizer hook 的配置文件
optimizer_config = dict(grad_clip=None)  # 大多数方法不使用梯度限制(grad_clip)。
# 学习率调整配置,用于注册 LrUpdater hook。
lr_config = dict(policy='step',          # 调度流程(scheduler)的策略,也支持 CosineAnnealing, Cyclic, 等。
                 step=[30, 60, 90])      # 在 epoch 为 30, 60, 90 时, lr 进行衰减
runner = dict(type='EpochBasedRunner',   # 将使用的 runner 的类别,如 IterBasedRunner 或 EpochBasedRunner。
            max_epochs=100)              # runner 总回合数, 对于 IterBasedRunner 使用 `max_iters`

3.4 运行设置配置信息

本部分主要包括保存权重策略、日志配置、训练参数、断点权重路径和工作目录等等。

# Checkpoint hook 的配置文件。
checkpoint_config = dict(interval=1)   # 保存的间隔是 1,单位会根据 runner 不同变动,可以为 epoch 或者 iter。
# 日志配置信息。
log_config = dict(
    interval=100,                      # 打印日志的间隔, 单位 iters
    hooks=[
        dict(type='TextLoggerHook'),          # 用于记录训练过程的文本记录器(logger)。
        # dict(type='TensorboardLoggerHook')  # 同样支持 Tensorboard 日志
    ])

dist_params = dict(backend='nccl')   # 用于设置分布式训练的参数,端口也同样可被设置。
log_level = 'INFO'             # 日志的输出级别。
resume_from = None             # 从给定路径里恢复检查点(checkpoints),训练模式将从检查点保存的轮次开始恢复训练。
workflow = [('train', 1)]      # runner 的工作流程,[('train', 1)] 表示只有一个工作流且工作流仅执行一次。
work_dir = 'work_dir'          # 用于保存当前实验的模型检查点和日志的目录文件地址。

3.5继承并修改配置文件

为了精简代码、更快的修改配置文件以及便于理解,我们建议继承现有方法。

在 ResNet 的基础上做了一些修改,用户首先可以通过指定 _base_ = './resnet50_8xb32_in1k.py'(相对于你的配置文件的路径),来继承基础的 ResNet 结构、数据集以及其他训练配置信息,然后修改配置文件中的必要参数以完成继承。如想在基础 resnet50 的基础上将训练轮数由 100 改为 300 和修改学习率衰减轮数,同时修改数据集路径,可以建立新的配置文件 configs/resnet/resnet50_8xb32-300e_in1k.py, 文件中写入以下内容:

_base_ = './resnet50_8xb32_in1k.py'

runner = dict(max_epochs=300)
lr_config = dict(step=[150, 200, 250])

data = dict(
    train=dict(data_prefix='mydata/imagenet/train'),
    val=dict(data_prefix='mydata/imagenet/train', ),
    test=dict(data_prefix='mydata/imagenet/train', )
)

3.6使用配置文件里的中间变量

用一些中间变量,中间变量让配置文件更加清晰,也更容易修改。

例如数据集里的 train_pipeline / test_pipeline 是作为数据流水线的中间变量。我们首先要定义 train_pipeline / test_pipeline,然后将它们传递到 data 中。如果想修改训练或测试时输入图片的大小,就需要修改 train_pipeline / test_pipeline 这些中间变量。

img_norm_cfg = dict(
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='RandomResizedCrop', size=384, backend='pillow',),
    dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='ToTensor', keys=['gt_label']),
    dict(type='Collect', keys=['img', 'gt_label'])
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='Resize', size=384, backend='pillow'),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='Collect', keys=['img'])
]
data = dict(
    train=dict(pipeline=train_pipeline),
    val=dict(pipeline=test_pipeline),
    test=dict(pipeline=test_pipeline))

3.7忽略基础配置文件里的部分内容

有时,您需要设置 _delete_=True 去忽略基础配置文件里的一些域内容。 可以参照 mmcv 来获得一些简单的指导。

以下是一个简单应用案例。 如果在上述 ResNet50 案例中 使用 cosine schedule ,使用继承并直接修改会报 get unexcepected keyword 'step' 错, 因为基础配置文件 lr_config 域信息的 'step' 字段被保留下来了,需要加入 _delete_=True 去忽略基础配置文件里的 lr_config 相关域内容:

_base_ = '../../configs/resnet/resnet50_8xb32_in1k.py'

lr_config = dict(
    _delete_=True,
    policy='CosineAnnealing',
    min_lr=0,
    warmup='linear',
    by_epoch=True,
    warmup_iters=5,
    warmup_ratio=0.1
)

3.8 引用基础配置文件里的变量

有时,您可以引用 _base_ 配置信息的一些域内容,这样可以避免重复定义。 可以参照 mmcv 来获得一些简单的指导。

以下是一个简单应用案例,在训练数据预处理流水线中使用 auto augment 数据增强,参考配置文件 configs/_base_/datasets/imagenet_bs64_autoaug.py。 在定义 train_pipeline 时,可以直接在 _base_ 中加入定义 auto augment 数据增强的文件命名,再通过 {{_base_.auto_increasing_policies}} 引用变量:

_base_ = ['./pipelines/auto_aug.py']

# dataset settings
dataset_type = 'ImageNet'
img_norm_cfg = dict(
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='RandomResizedCrop', size=224),
    dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
    dict(type='AutoAugment', policies={{_base_.auto_increasing_policies}}),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='ToTensor', keys=['gt_label']),
    dict(type='Collect', keys=['img', 'gt_label'])
]
test_pipeline = [...]
data = dict(
    samples_per_gpu=64,
    workers_per_gpu=2,
    train=dict(..., pipeline=train_pipeline),
    val=dict(..., pipeline=test_pipeline))
evaluation = dict(interval=1, metric='accuracy')

3.9导入用户自定义模块

备注

本部分仅在当将 MMClassification 当作库构建自己项目时可能用到,初学者可跳过。

在学习完后续教程 如何添加新数据集如何设计数据处理流程 、如何增加新模块 后,您可能使用 MMClassification 完成自己的项目并在项目中自定义了数据集、模型、数据增强等。为了精简代码,可以将 MMClassification 作为一个第三方库,只需要保留自己的额外的代码,并在配置文件中导入自定义的模块。案例可以参考 OpenMMLab 算法大赛项目

只需要在你的配置文件中添加以下代码:

custom_imports = dict(
    imports=['your_dataset_class',
             'your_transforme_class',
             'your_model_class',
             'your_module_class'],
    allow_failed_imports=False)

4、如何微调模型(迁移学习)

已经证明,在 ImageNet 数据集上预先训练的分类模型对于其他数据集和其他下游任务有很好的效果。

该教程提供了如何将 Model Zoo 中提供的预训练模型用于其他数据集,已获得更好的效果。

在新数据集上微调模型分为两步:

假设我们现在有一个在 ImageNet-2012 数据集上训练好的 ResNet-50 模型,并且希望在 CIFAR-10 数据集上进行模型微调,我们需要修改配置文件中的五个部分。

4.1 继承基础配置

首先,创建一个新的配置文件 configs/tutorial/resnet50_finetune_cifar.py 来保存我们的配置,当然,这个文件名可以自由设定。

为了重用不同配置之间的通用部分,我们支持从多个现有配置中继承配置。要微调 ResNet-50 模型,新配置需要继承 _base_/models/resnet50.py 来搭建模型的基本结构。 为了使用 CIFAR10 数据集,新的配置文件可以直接继承 _base_/datasets/cifar10.py。 而为了保留运行相关设置,比如训练调整器,新的配置文件需要继承 _base_/default_runtime.py

要继承以上这些配置文件,只需要把下面一段代码放在我们的配置文件开头。

_base_ = [
    '../_base_/models/resnet50.py',
    '../_base_/datasets/cifar10.py', '../_base_/default_runtime.py'
]

除此之外,你也可以不使用继承,直接编写完整的配置文件,例如 configs/lenet/lenet5_mnist.py

4.2 修改模型

在进行模型微调是,我们通常希望在主干网络(backbone)加载预训练模型,再用我们的数据集训练一个新的分类头(head)。

为了在主干网络加载预训练模型,我们需要修改主干网络的初始化设置,使用 Pretrained 类型的初始化函数。另外,在初始化设置中,我们使用 prefix='backbone' 来告诉初始化函数移除权重文件中键值名称的前缀,比如把 backbone.conv1 变成 conv1。方便起见,我们这里使用一个在线的权重文件链接,它 会在训练前自动下载对应的文件,你也可以提前下载这个模型,然后使用本地路径。

接下来,新的配置文件需要按照新数据集的类别数目来修改分类头的配置。只需要修改分 类头中的 num_classes 设置即可。

model = dict(
    backbone=dict(
        init_cfg=dict(
            type='Pretrained',
            checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
            prefix='backbone',
        )),
    head=dict(num_classes=10),
)

小技巧

这里我们只需要设定我们想要修改的部分配置,其他配置将会自动从我们的父配置文件中获取。

另外,有时我们在进行微调时会希望冻结主干网络前面几层的参数,这么做有助于在后续 训练中,保持网络从预训练权重中获得的提取低阶特征的能力。在 MMClassification 中, 这一功能可以通过简单的一个 frozen_stages 参数来实现。比如我们需要冻结前两层网 络的参数,只需要在上面的配置中添加一行:

model = dict(
    backbone=dict(
        frozen_stages=2,
        init_cfg=dict(
            type='Pretrained',
            checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
            prefix='backbone',
        )),
    head=dict(num_classes=10),
)

备注

目前还不是所有的网络都支持 frozen_stages 参数,在使用之前,请先检查 文档 以确认你所使用的主干网络是否支持。

4.3 修改数据集

当针对一个新的数据集进行微调时,我们通常都需要修改一些数据集相关的配置。比如这 里,我们就需要把 CIFAR-10 数据集中的图像大小从 32 缩放到 224 来配合 ImageNet 上 预训练模型的输入。这一需要可以通过修改数据集的预处理流水线(pipeline)来实现。

img_norm_cfg = dict(
    mean=[125.307, 122.961, 113.8575],
    std=[51.5865, 50.847, 51.255],
    to_rgb=False,
)
train_pipeline = [
    dict(type='RandomCrop', size=32, padding=4),
    dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
    dict(type='Resize', size=224),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='ToTensor', keys=['gt_label']),
    dict(type='Collect', keys=['img', 'gt_label']),
]
test_pipeline = [
    dict(type='Resize', size=224),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='Collect', keys=['img']),
]
data = dict(
    train=dict(pipeline=train_pipeline),
    val=dict(pipeline=test_pipeline),
    test=dict(pipeline=test_pipeline),
)

4.4修改训练策略设置

用于微调任务的超参数与默认配置不同,通常只需要较小的学习率和较少的训练时间。

# 用于批大小为 128 的优化器学习率
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# 学习率衰减策略
lr_config = dict(policy='step', step=[15])
runner = dict(type='EpochBasedRunner', max_epochs=200)
log_config = dict(interval=100)

开始训练

现在,我们完成了用于微调的配置文件,完整的文件如下:

_base_ = [
    '../_base_/models/resnet50.py',
    '../_base_/datasets/cifar10_bs16.py', '../_base_/default_runtime.py'
]

# 模型设置
model = dict(
    backbone=dict(
        frozen_stages=2,
        init_cfg=dict(
            type='Pretrained',
            checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
            prefix='backbone',
        )),
    head=dict(num_classes=10),
)

# 数据集设置
img_norm_cfg = dict(
    mean=[125.307, 122.961, 113.8575],
    std=[51.5865, 50.847, 51.255],
    to_rgb=False,
)
train_pipeline = [
    dict(type='RandomCrop', size=32, padding=4),
    dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
    dict(type='Resize', size=224),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='ToTensor', keys=['gt_label']),
    dict(type='Collect', keys=['img', 'gt_label']),
]
test_pipeline = [
    dict(type='Resize', size=224),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='ImageToTensor', keys=['img']),
    dict(type='Collect', keys=['img']),
]
data = dict(
    train=dict(pipeline=train_pipeline),
    val=dict(pipeline=test_pipeline),
    test=dict(pipeline=test_pipeline),
)

# 训练策略设置
# 用于批大小为 128 的优化器学习率
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# 学习率衰减策略
lr_config = dict(policy='step', step=[15])
runner = dict(type='EpochBasedRunner', max_epochs=200)
log_config = dict(interval=100)

当然,我们也可以使用单张 GPU 来进行训练,使用如下命令:

python tools/train.py configs/tutorial/resnet50_finetune_cifar.py

但是如果我们使用单张 GPU 进行训练的话,需要在数据集设置部分作如下修改:

data = dict(
    samples_per_gpu=128,
    train=dict(pipeline=train_pipeline),
    val=dict(pipeline=test_pipeline),
    test=dict(pipeline=test_pipeline),
)

这是因为我们的训练策略是针对批次大小(batch size)为 128 设置的。在父配置文件中, 设置了 samples_per_gpu=16,如果使用 8 张 GPU,总的批次大小就是 128。而如果使 用单张 GPU,就必须手动修改 samples_per_gpu=128 来匹配训练策略。

5、如何自定义数据集  

参考文档:教程 3:如何自定义数据集 — MMClassification 0.25.0 文档

6、如何设计数据处理流程 

参考文档:教程 4:如何设计数据处理流程 — MMClassification 0.25.0 文档

7、 如何增加新模块

参考文档:教程 5:如何增加新模块 — MMClassification 0.25.0 文档

8、 如何自定义优化策略

参考文档:教程 6:如何自定义优化策略 — MMClassification 0.25.0 文档

9、如何自定义模型运行参数 

教程 7:如何自定义模型运行参数 — MMClassification 0.25.0 文档 

10、模型推理

# 单 GPU
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--metrics ${METRICS}] [--out ${RESULT_FILE}]

可选参数:

  • RESULT_FILE:输出结果的文件名。如果未指定,结果将不会保存到文件中。支持 json, yaml, pickle 格式。

  • METRICS:数据集测试指标,如准确率 (accuracy), 精确率 (precision), 召回率 (recall) 等

6、模型训练 

        所有的输出(日志文件和模型权重文件)会被将保存到工作目录下。工作目录通过配置文件中的参数 work_dir 指定。

        默认情况下,MMClassification 在每个周期后会在验证集上评估模型,可以通过在训练配置中修改 interval 参数来更改评估间隔

evaluation = dict(interval=12)  # 每进行 12 轮训练后评估一次模型

 使用单个 GPU 进行训练

python tools/train.py ${CONFIG_FILE} [optional arguments]

可选参数为:

  • --no-validate (不建议): 默认情况下,程序将会在训练期间的每 k (默认为 1) 个周期进行一次验证。要禁用这一功能,使用 --no-validate

  • --work-dir ${WORK_DIR}:覆盖配置文件中指定的工作目录。

  • --resume-from ${CHECKPOINT_FILE}:从以前的模型权重文件恢复训练。

resume-from 和 load-from 的不同点: resume-from 加载模型参数和优化器状态,并且保留检查点所在的周期数,常被用于恢复意外被中断的训练。 load-from 只加载模型参数,但周期数从 0 开始计数,常被用于微调模型。

11、可视化

我们根据 flops-counter.pytorch 提供了一个脚本用于计算给定模型的 FLOPs 和参数量

python tools/analysis_tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}]

参考文档:可视化 — MMClassification 0.25.0 文档

分析 — MMClassification 0.25.0 文档

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐