zl程序教程

您现在的位置是:首页 >  后端

当前栏目

MMAction2 全新升级:更强特性,更多算法

算法 升级 特性 全新 更强
2023-06-13 09:16:25 时间

MMAction2 是一款基于 PyTorch 的视频理解开源工具箱,目前支持四大主流视频理解任务,分别是行为识别(Action Recognition),骨架行为识别(Skeleton based Action Recognition),时空行为检测(Spatio-Temporal Action Detection),时序行为定位(Temporal Action Localization)。MMAction2 支持了 28 类视频理解模型,22 类视频理解数据集。

MMAction2 效果演示 demo:Kinetics-400 上的基于 skeleton 的时空动作检测和动作识别

感谢大家的支持和认可,MMAction2 目前已经收获了 2.4K 个 star,并且有多个知名项目是基于 MMAction2 实现的,比如 CVPR 2022 中的 Video Swin 和 PoseC3D。

MMAction2 V1.0 新版本基于 MMEngine 算法库进行了适配重构,带来了更多强大的特性,同时我们也带来了更多新算法的支持

下面我们将分别从新版本的新特性快速入门两个方面展开介绍。

新特性

基于新的训练引擎库 MMEngine

强大的执行器

深度学习算法的训练、验证和测试通常都拥有相似的流程,因此 MMEngine 抽象出了执行器(Runner)来负责通用范式,让用户在使用过程中无需关注工程性代码细节,聚焦于算法实现。

执行器核心模块及相关组件

灵活的循环控制器

MMEngine 的执行器同时也更加灵活,支持自定义循环控制器(Loop),利用继承重载可以实现更复杂的执行逻辑。

如下图所示,可以通过增加额外的验证循环,在多个验证集上评估精度。

优雅的配置和注册器

MMEngine 沿用了 OpenMMLab 的注册器(Registry)和配置(Config),注册器机制可以用来管理功能相似的各种模块,结合配置文件,可以通过只修改配置文件,来调整模型结构和训练过程,无需修改代码。MMAction2 代码库中,几乎所有的行为都可以通过配置文件调整,包括模型结构,训练超参,数据集,评估方式等等。

基于注册器和 PyTorch 原生代码对比

注:更详细的 MMEngine 介绍可以参考这篇文章

新算法支持

MMAction2 V1.0 新版本新增了两个算法模型的支持,分别是 VideoSwin(CVPR2022) 和 VideoMAE(NeurIPS 2022),在新的算法库中,可以方便快捷地使用最新的视频理解模型,更多的算法支持也在持续开发中。

Video Swin 网络结构

VideoMAE 整体框架

快速入门

MMAction2 V1.0 新版在适配 MMEngine 时,部分改动是不兼容旧版本的。这里我们对主要的改动进行介绍,帮助旧版本用户快速切换到新版本。同时我们提供了一个从零配置训练的教程,帮助新用户快速上手。

更加详细的迁移教程,欢迎大家参考 MMAction2 V1.0 的文档:

https://mmaction2.readthedocs.io/en/1.x/

改动范围

重构中的改动主要是适配 MMEngine 的相关接口,得益于 MMAction2 的接口封装设计,在重构中主要通过修改基类(如 BaseRecognizer,BaseDataset 等)适配 MMEngine,而对用户直接使用的类和方法改动较小,因而迁移成本很低。

旧版本用户基本上可以保留自定义实现的模型,而自定义的数据集需要对接口进行重命名。主要的改动来自配置文件,我们制定了新的命名规范,调整了一些不直观的名称,新版本的配置名称更加符合我们的直觉。

配置文件概述

MMAction2 通过配置文件定义整个实验流程,配置文件分为 5 个部分,分别是通用、数据、训练、模型和评估。

  • 通用部分包括训练环境、钩子、模型存储、日志等模块
  • 数据部分包括数据集、数据加载器、数据增强等模块
  • 训练部分包括优化器、参数调度器等模块
  • 模型部分包括模型的 Backbone、Neck、Head 等结构及损失函数
  • 评估部分包括评价指标和评测器

需要调整实验时,修改相应部分的配置即可。

以 TSN 模型的训练配置为例,配置文件目录结构如下图所示,_base_ 中给出了不同实验的基础配置,包括模型、训练和通用配置。

在具体的实验配置中,首先会直接继承基础配置,保证配置文件尽量简洁,然后是数据配置,包括数据集、数据构建流程、数据加载,接下来定义了评估配置,最后通过覆盖基础配置指定了存储模型的间隔以及最大存储数量。

上手实操:训练 TSN 模型

接下来仍然以 TSN 模型作为例子,带大家详细解读 V1.0 新版本的配置文件系统。

步骤一:设计配置文件

MMEngine 实现了强大的配置类 Config,用于读取解析配置文件,支持 python,json,yaml 等多种格式的配置文件,并且支持项目内、以及跨项目配置文件的继承。下面示例代码中,TSN 配置继承了 3 个基础配置。

# tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py
 _base_ = [
    ‘../../_base_/default_runtime.py’,
    ‘../../_base_/models/tsn_r50.py’,
    ‘../../_base_/sgd_100e.py’
]

继承机制可以让配置文件更加简洁,便于对比不同实验的差异。但也导致了实验配置不完整,影响了可读性,所以我们提供了一个工具方便大家快速查看完整配置,调用方式如下面代码所示:

python tools/analysis_tools/print_config.py \
     tsn_r50_8xb32-1x1x3-100e_kinetics400-rgb.py

步骤二:数据集与数据加载器

新版本的数据集和数据加载器相关配置如下所示。在 0.x 旧版本中,data 相关的配置与 torch 的 dataloader 接口不一致,需要进行一层转换,令人费解。而新版本的 data 配置会直接用于构建 dataloader,所见即所得,不再隐晦。

train_dataloader = dict(
    batch_size=32,
    num_workers=8,
    persistent_workers=True,
    sampler=dict(type='DefaultSampler', shuffle=True),
    dataset=dict(
        type='VideoDataset',
        data_prefix=dict(video='data/kinetics400/videos_train'),
        ann_file=ann_file_train,
        pipeline=train_pipeline))
val_dataloader = dict(
     …)
test_dataloader = dict(
     …)

步骤三:数据预处理

数据预处理包括数据读取、增强、打包等流程,OpenMMLab 算法库中将整个流程称为 pipeline,通过定义训练、验证、测试的 pipeline 来指定不同的流程。这样通过配置文件就可以清晰地看到整个数据预处理流程,调整数据预处理方式也十分便捷,增加或者修改相应的模块即可。

预处理配置代码如下所示。新版本中我们增加了 PackActionInputs 操作,替代旧版本中的 Collect 和 ToTensor,支持打包 image、skeleton、audio 等多种模态数据,并转换成 tensor,送到模型中。

# tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py
 train_pipeline = [
    dict(type='DecordInit'),
    dict(type='SampleFrames', clip_len=1, frame_interval=1, num_clips=3),
    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')
]

步骤四:模型设计与网络结构

模型配置如下面代码所示,这部分定义了网络结构以及数据预处理器参数。网络结构中主要包括识别器 Recognizer 类型,模型骨干网络(backbone),分类头(cls_head),以及损失函数(loss_cls)的定义。而pipeline 最后一步 PackActionInputs 中打包的 tensor,会被送到数据预处理器(data_preprocessor)中进行 Normalize 操作,这样可以将 Normalize 由 CPU 搬到 GPU 上进行,进一步加快处理速度。

# tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py
 model = dict(
    type='Recognizer2D',
    backbone=dict(
        type='ResNet',
        pretrained='https://download.pytorch.org/models/resnet50-11ad3fa6.pth',
        depth=50,
        norm_eval=False),
    cls_head=dict(
        type='TSNHead',
        num_classes=400,
        in_channels=2048,
        loss_cls=dict(type='CrossEntropyLoss'),
        spatial_type='avg',
        consensus=dict(type='AvgConsensus', dim=1),
        dropout_ratio=0.4,
        init_std=0.01),
    data_preprocessor=dict(
        type='ActionDataPreprocessor',
        mean=[123.675, 116.28, 103.53],
        std=[58.395, 57.12, 57.375],
        format_shape='NCHW'))

步骤五:评估器配置

评估器的配置如下所示,在 V0.x 旧版本中,评测(evaluator)和对应的数据集(dataset)是绑定的,十分不灵活。在 V1.0 新版本中,我们对其进行了解耦,将评测和从数据集中剥离,独立了出来,为多指标评测任务提供了更自由的空间。

# tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py
val_evaluator = dict(type='AccMetric')
test_evaluator = val_evaluator

步骤六:通用配置

通用配置中定义了训练环境、日志、参数更新、模型存储等基础配置。而这些模块都是通过钩子组件控制的,如下面的代码所示,默认的配置(default_hooks)中指定了 6 个最基础的钩子组件,想要增加自定义钩子,也可以通过指定 custom_hooks 字段实现。

# tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py
 default_hooks = dict(
    runtime_info=dict(type='RuntimeInfoHook')
    timer=dict(type='IterTimerHook'),
    logger=dict(type='LoggerHook', interval=20, ignore_last=False),
    param_scheduler=dict(type='ParamSchedulerHook'),
    checkpoint=dict(
        type='CheckpointHook',
        interval=1,
        max_keep_ckpts=3,
        save_best='auto',
    ),
    sampler_seed=dict(type='DistSamplerSeedHook'),
    
)
custom_hooks = [dict(type='SyncBuffersHook')]

步骤七:训练配置

训练配置部分包括学习策略和优化器配置,在 V1.0 新版中采用 param_scheduler 的 list 来指定学习率策略。既然设计成 list,说明它支持多阶段学习率调整,例如下面示例代码中给出的 warmup + multi_step 学习率策略,只需要控制不同阶段的区间范围即可。优化器配置方面,我们相比旧版本进行了结构调整,差别不大。

# tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py
 param_scheduler = [
    dict(
        type='LinearLR', 
        start_factor=0.1, 
        by_epoch=True, 
        begin=0, 
        end=10, 
        convert_to_iter_based=True),
    dict(
        type='MultiStepLR',
        begin=10,
        end=100,
        by_epoch=True,
        milestones=[40, 80],
        gamma=0.1)
]

optim_wrapper = dict(
    optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001),
    clip_grad=dict(max_norm=40, norm_type=2))

步骤八:启动训练

配置好各个部分的 Config 之后,我们就可以愉快地启动训练了,启动命令还是一如既往的简洁。

python tools/train.py \
    tsn_imagenet-pretrained-r50_8xb32-1x1x3-100e_kinetics400-rgb.py

总结

我们对 MMAction2 V1.0 进行一个简单的总结,作为 OpenMMLab 2.0 的视频理解算法库,目前已在开源社区被广泛使用。基于全新的架构和生态,此次新升级的 MMAction2 统一了算法模块间接口参数,提升了训练、推理效率。

想了解更多 MMAction2 V1.0 相关内容,欢迎查看直播回放视频~

MMAction2 之后的发展,除了进一步紧跟学术热点,实时支持学术界最新的 sota 模型之外,我们也希望它能更高效、更强大,更灵活,应用场景更全面,更易上手,希望能助力视频理解新算法的诞生,和科技产业的落地。

目前 MMAction2 V1.0 处于公测期,源码已经开放,大家可以在 1.x 这个分支中查看源码:https://github.com/open-mmlab/mmaction2/tree/1.x,欢迎体验~

我们的开发维护计划见下图:

我们非常鼓励社区小伙伴们能够在公测期就可以尽早尝试 MMAction2 V1.0,然后能在兼容期很好地过渡到 MMAction2 V1.0,在这个过程中,我们一定也会帮助到大家。

  • 如果在使用过程中,你有任何的疑问,可以来 Github 的 Discussions 页面来进行讨论:https://github.com/open-mmlab/mmaction2/discussions
  • 如果你碰到了 bug 或者想要吐槽文档中遇到的问题,可以提出你的 issue:https://github.com/open-mmlab/mmaction2/issues
  • 如果你支持了新功能或者修复了 bug,那就更不要犹豫啦,快来提交你的修改,让你的代码在 MMAction2 中闪闪发光:https://github.com/open-mmlab/mmaction2/pulls