MMAction2 学习笔记 (二)——通用工具使用及网络DIY (上)

MMAction2 学习笔记 (二)——通用工具使用及网络DIY

0- 写在前面

继续上一篇骨骼关键点识别算法相关内容的学习,今天学习通用领域的工具使用以及网络的DIY
目前正在实习,具体的内容方向是基于骨骼关键点的动作识别(skeleton based action recognition)。 在经过了多多的调研之后,觉得目前还是mmaction2平台最香,因此希望后续工作(包括效果的验证、实验、对比等等)包括前期的端到端工作都在mmaction2工具箱上展开。

学习mmaction2的目的是能够借助该平台对数据集、算法、演示、流程、搭建等等环节都能够理解的更加清晰和透彻(毕竟目前是一个小白),为后续自己的真正实际问题解决做准备。

本篇文章主要是基于mmaction2的中文教程(链接见文末),此外还有一些参考的文章以及github库中的注释性教程。

1- MMAction2 简介

在这里插入图片描述

mmaction2是商汤和港中文联合研发的一个基于pytorch框架的人体动作识别的深度学习开源工具库,可以提供包括行为识别(分类)、时序动作检测、时空动作检测、骨骼动作识别(分类)等等多种子类问题的算法框架,包括数据集等等,可以非常方便的使用。
mmaction2 和广为人知的检测工具库mmdetection 一样,都属于open-mmlab 工具箱下属的一个模块,目前仍在不断更新与拓展功能及算法,可以预见的是,其在人体行为识别方面将被更多人使用。

2. 编写配置文件

《先放参考链接》

MAction2 使用 python 文件作为配置文件。其配置文件系统的设计将模块化与继承整合进来,方便用户进行各种实验。 MMAction2 提供的所有配置文件都放置在 $MMAction2/configs 文件夹下,用户可以通过运行命令 python tools/analysis/print_config.py /PATH/TO/CONFIG 来查看完整的配置信息,从而方便检查所对应的配置文件。

2.1 通过命令行参数修改配置信息

当用户使用脚本 “tools/train.py” 或者 “tools/test.py” 提交任务时,可以通过指定 --cfg-options 参数来直接修改所使用的配置文件内容。

  • 更新配置文件内的字典

用户可以按照原始配置中的字典键顺序来指定配置文件的设置。 例如,--cfg-options model.backbone.norm_eval=False 会改变 train 模式下模型主干网络 backbone 中所有的 BN 模块。

  • 更新配置文件内列表的键

配置文件中,存在一些由字典组成的列表。例如,训练数据前处理流水线 data.train.pipeline 就是 python 列表。 如,[dict(type='SampleFrames'), ...]。如果用户想更改其中的 ‘SampleFrames’ 为 ‘DenseSampleFrames’, 可以指定 --cfg-options data.train.pipeline.0.type=DenseSampleFrames

  • 更新列表/元组的值。

当配置文件中需要更新的是一个列表或者元组,例如,配置文件通常会设置 workflow=[('train', 1)],用户如果想更改, 需要指定 --cfg-options workflow="[(train,1),(val,1)]"。注意这里的引号 ” 对于列表/元组数据类型的修改是必要的, 并且 不允许 引号内所指定的值的书写存在空格。

2.2 配置文件结构

config/_base_ 文件夹下存在 3 种基本组件类型: 模型(model), 训练策略(schedule), 运行时的默认设置(default_runtime)。 许多方法都可以方便地通过组合这些组件进行实现,如 TSN,I3D,SlowOnly 等。 其中,通过 _base_ 下组件来构建的配置被称为 原始配置(primitive)。

对于在同一文件夹下的所有配置文件,MMAction2 推荐只存在 一个 对应的 原始配置 文件。 所有其他的配置文件都应该继承 原始配置 文件,这样就能保证配置文件的最大继承深度为 3。

为了方便理解,MMAction2 推荐用户继承现有方法的配置文件。 例如,如需修改 TSN 的配置文件,用户应先通过 _base_ = '../tsn/tsn_r50_1x1x3_100e_kinetics400_rgb.py’ 继承 TSN 配置文件的基本结构, 并修改其中必要的内容以完成继承

如果用户想实现一个独立于任何一个现有的方法结构的新方法,则需要像 configs/recognition, configs/detection 等一样,在 configs/TASK 中建立新的文件夹。

更多详细内容,请参考 mmcv

2.3 配置文件命名规则

MMAction2 按照以下风格进行配置文件命名,代码库的贡献者需要遵循相同的命名规则。

{
   model}_[model setting]_{
   backbone}_[misc]_{
   data setting}_[gpu x batch_per_gpu]_{
   schedule}_{
   dataset}_{
   modality}

其中,{xxx} 表示必要的命名域,[yyy] 表示可选的命名域。

  • {model}:模型类型,如 tsn,i3d 等。
  • [model setting]:一些模型上的特殊设置。
  • {backbone}:主干网络类型,如 r50(ResNet-50)等。
  • [misc]:模型的额外设置或插件,如 dense,320p,video等。
  • {data setting}:采帧数据格式,形如 {clip_len}x{frame_interval}x{num_clips}。
  • [gpu x batch_per_gpu]:GPU 数量以及每个 GPU 上的采样。
  • {schedule}:训练策略设置,如 20e 表示 20 个周期(epoch)。
  • {dataset}:数据集名,如 kinetics400,mmit等。
  • {modality}:帧的模态,如 rgb, flow等。
2.4 配置文件代码解读

为了方便更好的理解配置文件的设置命令及作用,mmaction2工具库在文档中已经对:时序动作检测、动作识别、时空动作检测 三种识别任务给出了代码的一个具体示例以及注释。目前针对骨骼关键点动作识别问题还没有进行具体注释实例的更新,因此本篇对: 动作识别 ;时空动作检测 官方所给实例进行记录与解读,并且附上Pose-C3D的以及 ST-GCN的配置文件做对比阅读(因为两者不是一个结构,差别还是挺大的)。

  • 动作识别配置文件解读 :TSN
    为了帮助用户理解 MMAction2 的配置文件结构,以及动作识别系统中的一些模块,这里以 TSN 为例,给出其配置文件的注释。 对于每个模块的详细用法以及对应参数的选择,请参照 API 文档
# 模型设置
model = dict(  # 模型的配置
    type='Recognizer2D',  # 动作识别器的类型
    backbone=dict(  # Backbone 字典设置
        type='ResNet',  # Backbone 名
        pretrained='torchvision://resnet50',  # 预训练模型的 url 或文件位置
        depth=50,  # ResNet 模型深度
        norm_eval=False),  # 训练时是否设置 BN 层为验证模式
    cls_head=dict(  # 分类器字典设置
        type='TSNHead',  # 分类器名
        num_classes=400,  # 分类类别数量
        in_channels=2048,  # 分类器里输入通道数
        spatial_type='avg',  # 空间维度的池化种类
        consensus=dict(type='AvgConsensus', dim=1),  # consensus 模块设置
        dropout_ratio=0.4,  # dropout 层概率
        init_std=0.01), # 线性层初始化 std 值
        # 模型训练和测试的设置
    train_cfg=None,  # 训练 TSN 的超参配置
    test_cfg=dict(average_clips=None))  # 测试 TSN 的超参配置

# 数据集设置
dataset_type = 'RawframeDataset'  # 训练,验证,测试的数据集类型
data_root = 'data/kinetics400/rawframes_train/'  # 训练集的根目录
data_root_val = 'data/kinetics400/rawframes_val/'  # 验证集,测试集的根目录
ann_file_train = 'data/kinetics400/kinetics400_train_list_rawframes.txt'  # 训练集的标注文件
ann_file_val = 'data/kinetics400/kinetics400_val_list_rawframes.txt'  # 验证集的标注文件
ann_file_test = 'data/kinetics400/kinetics400_val_list_rawframes.txt'  # 测试集的标注文件
img_norm_cfg = dict(  # 图像正则化参数设置
    mean=[123.675, 116.28, 103.53],  # 图像正则化平均值
    std=[58.395, 57.12, 57.375],  # 图像正则化方差
    to_bgr=False)  # 是否将通道数从 RGB 转为 BGR

train_pipeline = [  # 训练数据前处理流水线步骤组成的列表
    dict(  # SampleFrames 类的配置
        type='SampleFrames',  # 选定采样哪些视频帧
        clip_len=1,  # 每个输出视频片段的帧
        frame_interval=1,  # 所采相邻帧的时序间隔
        num_clips=3),  # 所采帧片段的数量
    dict(  # RawFrameDecode 类的配置
        type='RawFrameDecode'),  # 给定帧序列,加载对应帧,解码对应帧
    dict(  # Resize 类的配置
        type='Resize',  # 调整图片尺寸
        scale=(-1, 256)),  # 调整比例
    dict(  # MultiScaleCrop 类的配置
        type='MultiScaleCrop',  # 多尺寸裁剪,随机从一系列给定尺寸中选择一个比例尺寸进行裁剪
        input_size=224,  # 网络输入
        scales=(1, 0.875, 0.75, 0.66),  # 长宽比例选择范围
        random_crop=False,  # 是否进行随机裁剪
        max_wh_scale_gap=1),  # 长宽最大比例间隔
    dict(  # Resize 类的配置
        type='Resize',  # 调整图片尺寸
        scale=(224, 224),  # 调整比例
        keep_ratio=False),  # 是否保持长宽比
    dict(  # Flip 类的配置
        type='Flip',  # 图片翻转
        flip_ratio=0.5),  # 执行翻转几率
    dict(  # Normalize 类的配置
        type='Normalize',  # 图片正则化
        **img_norm_cfg),  # 图片正则化参数
    dict(  # FormatShape 类的配置
        type='FormatShape',  # 将图片格式转变为给定的输入格式
        input_format='NCHW'),  # 最终的图片组成格式
    dict(  # Collect 类的配置
        type='Collect',  # Collect 类决定哪些键会被传递到行为识别器中
        keys=['imgs', 'label'],  # 输入的键
        meta_keys=[]),  # 输入的元键
    dict(  # ToTensor 类的配置
        type='ToTensor',  # ToTensor 类将其他类型转化为 Tensor 类型
        keys=['imgs', 'label'])  # 将被从其他类型转化为 Tensor 类型的特征
]
val_pipeline = [  # 验证数据前处理流水线步骤组成的列表
    dict(  # SampleFrames 类的配置
        type='SampleFrames',  # 选定采样哪些视频帧
        clip_len=1,  # 每个输出视频片段的帧
        frame_interval=1,  # 所采相邻帧的时序间隔
        num_clips=3,  # 所采帧片段的数量
        test_mode=True),  # 是否设置为测试模式采帧
    dict(  # RawFrameDecode 类的配置
        type='RawFrameDecode'),  # 给定帧序列,加载对应帧,解码对应帧
    dict(  # Resize 类的配置
        type='Resize',  # 调整图片尺寸
        scale=(-1, 256)),  # 调整比例
    dict(  # CenterCrop 类的配置
        type='CenterCrop',  # 中心裁剪
        crop_size=224),  # 裁剪部分的尺寸
    dict(  # Flip 类的配置
        type='Flip',  # 图片翻转
        flip_ratio=0),  # 翻转几率
    dict(  # Normalize 类的配置
        type='Normalize',  # 图片正则化
        **img_norm_cfg),  # 图片正则化参数
    dict(  # FormatShape 类的配置
        type='FormatShape',  # 将图片格式转变为给定的输入格式
        input_format='NCHW'),  # 最终的图片组成格式
    dict(  # Collect 类的配置
        type='Collect',  # Collect 类决定哪些键会被传递到行为识别器中
        keys=['imgs', 'label'],  # 输入的键
        meta_keys=[]),  # 输入的元键
    dict(  # ToTensor 类的配置
        type='ToTensor',  # ToTensor 类将其他类型转化为 Tensor 类型
        keys=['imgs'])  # 将被从其他类型转化为 Tensor 类型的特征
]
test_pipeline = [  # 测试数据前处理流水线步骤组成的列表
    dict(  # SampleFrames 类的配置
        type='SampleFrames',  # 选定采样哪些视频帧
        clip_len=1,  # 每个输出视频片段的帧
        frame_interval=1,  # 所采相邻帧的时序间隔
        num_clips=25,  # 所采帧片段的数量
        test_mode=True),  # 是否设置为测试模式采帧
    dict(  # RawFrameDecode 类的配置
        type='RawFrameDecode'),  # 给定帧序列,加载对应帧,解码对应帧
    dict(  # Resize 类的配置
        type='Resize',  # 调整图片尺寸
        scale=(-1, 256)),  # 调整比例
    dict(  # TenCrop 类的配置
        type='TenCrop',  # 裁剪 10 个区域
        crop_size=224),  # 裁剪部分的尺寸
    dict(  # Flip 类的配置
        type='Flip',  # 图片翻转
        flip_ratio=0),  # 执行翻转几率
    dict(  # Normalize 类的配置
        type='Normalize',  # 图片正则化
        **img_norm_cfg),  # 图片正则化参数
    dict(  # FormatShape 类的配置
        type='FormatShape',  # 将图片格式转变为给定的输入格式
        input_format='NCHW'),  # 最终的图片组成格式
    dict(  # Collect 类的配置
        type='Collect',  # Collect 类决定哪些键会被传递到行为识别器中
        keys=['imgs', 'label'],  # 输入的键
        meta_keys=[]),  # 输入的元键
    dict(  # ToTensor 类的配置
        type='ToTensor',  # ToTensor 类将其他类型转化为 Tensor 类型
        keys=['imgs'])  # 将被从其他类型转化为 Tensor 类型的特征
]
data = dict(  # 数据的配置
    videos_per_gpu=32,  # 单个 GPU 的批大小
    workers_per_gpu=2,  # 单个 GPU 的 dataloader 的进程
    train_dataloader=dict(  # 训练过程 dataloader 的额外设置
        drop_last=True),  # 在训练过程中是否丢弃最后一个批次
    val_dataloader=dict(  # 验证过程 dataloader 的额外设置
        videos_per_gpu=1),  # 单个 GPU 的批大小
    test_dataloader=dict(  # 测试过程 dataloader 的额外设置
        videos_per_gpu=2),  # 单个 GPU 的批大小
    train=dict(  # 训练数据集的设置
        type=dataset_type,
        ann_file=ann_file_train,
        data_prefix=data_root,
        pipeline=train_pipeline),
    val=dict(  # 验证数据集的设置
        type=dataset_type,
        ann_file=ann_file_val,
        data_prefix=data_root_val,
        pipeline=val_pipeline),
    test=dict(  # 测试数据集的设置
        type=dataset_type,
        ann_file=ann_file_test,
        data_prefix=data_root_val,
        pipeline=test_pipeline))
# 优化器设置
optimizer = dict(
    # 构建优化器的设置,支持:
    # (1) 所有 PyTorch 原生的优化器,这些优化器的参数和 PyTorch 对应的一致;
    # (2) 自定义的优化器,这些优化器在 `constructor` 的基础上构建。
    # 更多细节可参考 "tutorials/5_new_modules.md" 部分
    type='SGD',  # 优化器类型, 参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/optimizer/default_constructor.py#L13
    lr=0.01,  # 学习率, 参数的细节使用可参考 PyTorch 的对应文档
    momentum=0.9,  # 动量大小
    weight_decay=0.0001)  # SGD 优化器权重衰减
optimizer_config = dict(  # 用于构建优化器钩子的设置
    grad_clip=dict(max_norm=40, norm_type=2))  # 使用梯度裁剪
# 学习策略设置
lr_config = dict(  # 用于注册学习率调整钩子的设置
    policy='step',  # 调整器策略, 支持 CosineAnnealing,Cyclic等方法。更多细节可参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py#L9
    step=[40, 80])  # 学习率衰减步长
total_epochs = 100  # 训练模型的总周期数
checkpoint_config = dict(  # 模型权重钩子设置,更多细节可参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.py
    interval=5)  # 模型权重文件保存间隔
evaluation = dict(  # 训练期间做验证的设置
    interval=5,  # 执行验证的间隔
    
  • 8
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值