从 MMAction2 0.x 迁移¶
MMAction2 1.x 引入了一些重构和修改,包括一些向后不兼容的更改。我们提供这个教程,帮助您从 MMAction2 0.x 迁移您的项目。
新的依赖项¶
MMAction2 1.x 依赖于以下库。建议您准备一个新的运行环境,并根据安装教程进行安装。
配置文件¶
在 MMAction2 1.x 中,我们重构了配置文件的结构。旧风格的配置文件将不兼容。
在本节中,我们将介绍配置文件的所有更改。我们假设您已经熟悉配置文件。
模型设置¶
model.backbone
和 model.neck
没有更改。对于 model.cls_head
,我们将 average_clips
移到其中,原本设置在 model.test_cfg
中。
数据设置¶
data
中的更改¶
原始的
data
字段被拆分为train_dataloader
、val_dataloader
和test_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
中的更改¶
原来的格式化变换
ToTensor
、Collect
被合并为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_evaluator
和test_evaluator
。不再支持interval
和save_best
参数。interval
移到train_cfg.val_interval
,save_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
|
学习率策略设置¶
optimizer
和 optimizer_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_cfg
、val_cfg
和 test_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_config
和 log_config
中的更改¶
checkpoint_config
移到 default_hooks.checkpoint
,log_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_from
和 resume_from
中的更改¶
删除了
resume_from
。现在我们使用resume
和load_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
¶
文档可以在这里找到。
函数 |
更改 |
---|---|
|
无需更改 |
|
无需更改 |
|
删除,使用 |
|
删除,使用 |
|
删除,使用 |
|
删除,使用 |
|
删除,使用 |
mmaction.core
¶
mmaction.core
包已被重命名为 mmaction.engine
。
子包 |
更改 |
---|---|
|
删除,使用 |
|
移动到 |
|
移动到 |
|
删除,分布式环境相关的函数可以在 |
mmaction.datasets
¶
文档可以在这里找到。
BaseActionDataset
中的更改:¶
方法 |
更改 |
---|---|
|
由 |
|
由 |
|
删除,使用 |
|
删除,使用 |
|
替换为 |
现在,您可以编写一个继承自 BaseActionDataset
的新 Dataset 类,并仅重写 load_data_list
。要加载更多的数据信息,您可以像 RawframeDataset
和 AVADataset
那样重写 get_data_info
。
mmaction.datasets.pipelines
被重命名为 mmaction.datasets.transforms
,mmaction.datasets.pipelines.augmentations
被重命名为 mmaction.datasets.pipelines.processing
。
mmaction.models
¶
文档可以在这里找到。所有 backbones、necks 和 losses 的接口没有更改。
BaseRecognizer
中的更改:
方法 |
更改 |
---|---|
|
增强的方法,现在支持三个阶段( |
|
现在只接受三个参数: |
|
已替换为 |
|
已替换为 |
|
|
|
原 |
|
新方法,与 |
BaseHead 中的更改:
方法 |
更改 |
---|---|
|
无需更改 |
|
接受 |
|
接受 |
mmaction.utils
¶
函数 |
更改 |
---|---|
|
无需更改 |
|
删除,使用 |
|
删除,使用 |
其他更改¶
我们将所有注册器的定义从各个包移动到了
mmaction.registry
。