Shortcuts

从 MMAction2 0.x 迁移

MMAction2 1.x 引入了一些重构和修改,包括一些向后不兼容的更改。我们提供这个教程,帮助您从 MMAction2 0.x 迁移您的项目。

新的依赖项

MMAction2 1.x 依赖于以下库。建议您准备一个新的运行环境,并根据安装教程进行安装。

  1. MMEngine:MMEngine 是引入于 OpenMMLab 2.0 架构中的用于训练深度学习模型的基础库。

  2. MMCV:MMCV 是用于计算机视觉的基础库。MMAction2 1.x 需要 mmcv>=2.0.0,它比 mmcv-full==2.0.0 更紧凑和高效。

配置文件

在 MMAction2 1.x 中,我们重构了配置文件的结构。旧风格的配置文件将不兼容。

在本节中,我们将介绍配置文件的所有更改。我们假设您已经熟悉配置文件

模型设置

model.backbonemodel.neck 没有更改。对于 model.cls_head,我们将 average_clips 移到其中,原本设置在 model.test_cfg 中。

数据设置

data 中的更改

  • 原始的 data 字段被拆分为 train_dataloaderval_dataloadertest_dataloader。这样可以对它们进行细粒度的配置。例如,您可以在训练和测试过程中指定不同的采样器和批大小。

  • videos_per_gpu 改名为 batch_size

  • workers_per_gpu 改名为 num_workers

旧版本
data = dict(
    videos_per_gpu=32,
    workers_per_gpu=2,
    train=dict(...),
    val=dict(...),
    test=dict(...),
)
新版本
train_dataloader = dict(
    batch_size=32,
    num_workers=2,
    dataset=dict(...),
    sampler=dict(type='DefaultSampler', shuffle=True)  # 必要
)

val_dataloader = dict(
    batch_size=32,
    num_workers=2,
    dataset=dict(...),
    sampler=dict(type='DefaultSampler', shuffle=False)  # 必要
)

test_dataloader = val_dataloader

pipeline 中的更改

  • 原来的格式化变换 ToTensorCollect 被合并为 PackActionInputs

  • 我们不建议在数据集流水线中进行 Normalize。请从流水线中移除它,并在 model.data_preprocessor 字段中设置。

旧版本

train_pipeline = [
    dict(type='DecordInit'),
    dict(type='SampleFrames', clip_len=1, frame_interval=1, num_clips=8),
    dict(type='DecordDecode'),
    dict(type='Resize', scale=(-1, 256)),
    dict(
        type='MultiScaleCrop',
        input_size=224,
        scales=(1, 0.875, 0.75, 0.66),
        random_crop=False,
        max_wh_scale_gap=1),
    dict(type='Resize', scale=(224, 224), keep_ratio=False),
    dict(type='Flip', flip_ratio=0.5),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='FormatShape', input_format='NCHW'),
    dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]),
    dict(type='ToTensor', keys=['imgs', 'label'])
]
新版本
model.data_preprocessor = dict(
    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=False)

train_pipeline = [
    dict(type='DecordInit'),
    dict(type='SampleFrames', clip_len=1, frame_interval=1, num_clips=5),
    dict(type='DecordDecode'),
    dict(type='Resize', scale=(-1, 256)),
    dict(
        type='MultiScaleCrop',
        input_size=224,
        scales=(1, 0.875, 0.75, 0.66),
        random_crop=False,
        max_wh_scale_gap=1),
    dict(type='Resize', scale=(224, 224), keep_ratio=False),
    dict(type='Flip', flip_ratio=0.5),
    dict(type='FormatShape', input_format='NCHW'),
    dict(type='PackActionInputs')
]

evaluation 中的更改

  • evaluation 字段被拆分为 val_evaluatortest_evaluator。不再支持 intervalsave_best 参数。

  • interval 移到 train_cfg.val_intervalsave_best 移到 default_hooks.checkpoint.save_best

  • ‘mean_average_precision’、’mean_class_accuracy’、’mmit_mean_average_precision’、’top_k_accuracy’ 被合并为 AccMetric,您可以使用 metric_list 指定要计算的指标。

  • AVAMetric 用于评估 AVA 数据集。

  • ANetMetric 用于评估 ActivityNet 数据集。

旧版本
evaluation = dict(
    interval=5,
    metrics=['top_k_accuracy', 'mean_class_accuracy'])
新版本
val_evaluator = dict(
    type='AccMetric',
    metric_list=('top_k_accuracy', 'mean_class_accuracy'))
test_evaluator = val_evaluator

学习率策略设置

optimizeroptimizer_config 中的更改

  • 现在我们使用 optim_wrapper 字段来配置优化过程。optimizer 成为 optim_wrapper 的子字段。

  • paramwise_cfg 也是 optim_wrapper 的子字段,与 optimizer 平行。

  • 现在已删除 optimizer_config,其中的所有配置都移动到 optim_wrapper

  • grad_clip 改名为 clip_grad

旧版本
optimizer = dict(
    type='AdamW',
    lr=0.0015,
    weight_decay=0.3,
    paramwise_cfg = dict(
        norm_decay_mult=0.0,
        bias_decay_mult=0.0,
    ))

optimizer_config = dict(grad_clip=dict(max_norm=1.0))
新版本
optim_wrapper = dict(
    optimizer=dict(type='AdamW', lr=0.0015, weight_decay=0.3),
    paramwise_cfg = dict(
        norm_decay_mult=0.0,
        bias_decay_mult=0.0,
    ),
    clip_gard=dict(max_norm=1.0),
)

lr_config 中的更改

  • 删除了 lr_config 字段,我们使用新的 param_scheduler 来替代它。

  • 删除了与 warmup 相关的参数,因为我们使用策略组合来实现这个功能。

新的组合机制非常灵活,您可以使用它来设计多种学习率/动量曲线。

旧版本
lr_config = dict(
    policy='CosineAnnealing',
    min_lr=0,
    warmup='linear',
    warmup_iters=5,
    warmup_ratio=0.01,
    warmup_by_epoch=True)
新版本
param_scheduler = [
    # 学习率预热
    dict(
        type='LinearLR',
        start_factor=0.01,
        by_epoch=True,
        end=5,
        # 在每个迭代后更新学习率。
        convert_to_iter_based=True),
    # 主要的学习率策略
    dict(type='CosineAnnealingLR', by_epoch=True, begin=5),
]

runner 中的更改

原始 runner 字段中的大多数配置已移至 train_cfgval_cfgtest_cfg,用于配置训练、验证和测试的循环。

旧版本
runner = dict(type='EpochBasedRunner', max_epochs=100)
新版本
# `val_interval` 是原 `evaluation.interval`。
train_cfg = dict(type='EpochBasedTrainLoop', max_epochs=100, val_begin=1, val_interval=1)
val_cfg = dict(type='ValLoop')   # 使用默认验证循环。
test_cfg = dict(type='TestLoop')  # 使用默认测试循环。

事实上,在 OpenMMLab 2.0 中,我们引入了 Loop 来控制训练、验证和测试的行为。Runner 的功能也发生了变化。您可以在MMEngine 教程中找到更多详细信息。

运行时设置

checkpoint_configlog_config 中的更改

checkpoint_config 移到 default_hooks.checkpointlog_config 移到 default_hooks.logger。我们将许多钩子的设置从脚本代码中移动到运行时配置的 default_hooks 字段中。

default_hooks = dict(
    # 更新运行时信息,如当前迭代和学习率。
    runtime_info=dict(type='RuntimeInfoHook'),

    # 记录每个迭代的时间。
    timer=dict(type='IterTimerHook'),

    # 每 100 次迭代打印日志。
    logger=dict(type='LoggerHook', interval=100),

    # 启用参数策略器。
    param_scheduler=dict(type='ParamSchedulerHook'),

    # 每个 epoch 保存一次权重,并自动保存最佳权重。
    checkpoint=dict(type='CheckpointHook', interval=1, save_best='auto'),

    # 在分布式环境中设置采样器种子。
    sampler_seed=dict(type='DistSamplerSeedHook'),

    # 在每个 epoch 结束时同步模型缓冲区。
    sync_buffers=dict(type='SyncBuffersHook')
)

此外,我们将原来的 logger 拆分为 logger 和 visualizer。logger 用于记录信息,visualizer 用于在不同的后端(如终端、TensorBoard 和 Wandb)中显示 logger。

旧版本
log_config = dict(
    interval=100,
    hooks=[
        dict(type='TextLoggerHook'),
        dict(type='TensorboardLoggerHook'),
    ])
新版本
default_hooks = dict(
    ...
    logger=dict(type='LoggerHook', interval=100),
)

visualizer = dict(
    type='ActionVisualizer',
    vis_backends=[dict(type='LocalVisBackend'), dict(type='TensorboardVisBackend')],
)

load_fromresume_from 中的更改

  • 删除了 resume_from。现在我们使用 resumeload_from 来替代它。

    • 如果 resume=True 并且 load_from 不为 None,则从 load_from 中的权重恢复训练。

    • 如果 resume=True 并且 load_from 为 None,则尝试从工作目录中的最新权重恢复。

    • 如果 resume=False 并且 load_from 不为 None,则只加载权重文件,不恢复训练。

    • 如果 resume=False 并且 load_from 为 None,则既不加载也不恢复。

dist_params 中的更改

dist_params 字段现在是 env_cfg 的子字段。env_cfg 中还有一些新的配置。

env_cfg = dict(
    # 是否启用 cudnn benchmark
    cudnn_benchmark=False,

    # 设置多进程参数
    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),

    # 设置分布式参数
    dist_cfg=dict(backend='nccl'),
)

workflow 中的更改

删除了与 workflow 相关的功能。

新字段 visualizer

visualizer 是 OpenMMLab 2.0 架构中的新设计。我们在 runner 中使用一个 visualizer 实例来处理结果和日志的可视化,并保存到不同的后端,如终端、TensorBoard 和 Wandb。

visualizer = dict(
    type='ActionVisualizer',
    vis_backends=[
        dict(type='LocalVisBackend'),
        # 取消下面一行的注释,将日志和可视化结果保存到 TensorBoard。
        # dict(type='TensorboardVisBackend')
    ]
)

新字段 default_scope

所有注册表在不同包中的定义已移动到 mmaction.registry 包中。

Packages

mmaction.apis

文档可以在这里找到。

函数

更改

init_recognizer

无需更改

inference_recognizer

无需更改

train_model

删除,使用 runner.train 进行训练

multi_gpu_test

删除,使用 runner.test 进行测试

single_gpu_test

删除,使用 runner.test 进行测试

set_random_seed

删除,使用 mmengine.runner.set_random_seed

init_random_seed

删除,使用 mmengine.dist.sync_random_seed

mmaction.core

mmaction.core 包已被重命名为 mmaction.engine

子包

更改

evaluation

删除,使用 mmaction.evaluation 中的指标

hooks

移动到 mmaction.engine.hooks

optimizer

移动到 mmaction.engine.optimizers

utils

删除,分布式环境相关的函数可以在 mmengine.dist 包中找到

mmaction.datasets

文档可以在这里找到。

BaseActionDataset 中的更改:

方法

更改

prepare_train_frames

get_data_info 替换

preprare_test_frames

get_data_info 替换

evaluate

删除,使用 mmengine.evaluator.Evaluator

dump_results

删除,使用 mmengine.evaluator.DumpResults

load_annotations

替换为 load_data_list

现在,您可以编写一个继承自 BaseActionDataset 的新 Dataset 类,并仅重写 load_data_list。要加载更多的数据信息,您可以像 RawframeDatasetAVADataset 那样重写 get_data_infommaction.datasets.pipelines 被重命名为 mmaction.datasets.transformsmmaction.datasets.pipelines.augmentations 被重命名为 mmaction.datasets.pipelines.processing

mmaction.models

文档可以在这里找到。所有 backbonesneckslosses 的接口没有更改。

BaseRecognizer 中的更改:

方法

更改

extract_feat

增强的方法,现在支持三个阶段(backboneneckhead)的输出特征,并且可以处理不同的模式,如 train_modetest_mode

forward

现在只接受三个参数:inputsdata_samplesmode。详细信息请参阅文档

forward_train

已替换为 loss

forward_test

已替换为 predict

train_step

optimizer 参数被替换为 optim_wrapper,它接受 OptimWrapper

val_step

val_steptrain_step 相同,现在调用 predict

test_step

新方法,与 val_step 相同。

BaseHead 中的更改:

方法

更改

forward

无需更改

loss

接受 featsdata_samples,而不是 cls_scorelabels 来计算损失。data_samplesActionDataSample 的列表。

predict

接受 featsdata_samples 来预测分类分数。

mmaction.utils

函数

更改

collect_env

无需更改

get_root_logger

删除,使用 mmengine.MMLogger.get_current_instance

setup_multi_processes

删除,使用 mmengine.utils.dl_utils.setup_multi_processes

其他更改

  • 我们将所有注册器的定义从各个包移动到了 mmaction.registry