自定义数据流水线¶
在本教程中,我们将介绍如何为你的任务构建数据流水线(即,数据转换)的一些方法。
数据流水线设计¶
数据流水线指的是从数据集索引样本时处理数据样本字典的过程,它包括一系列的数据转换。每个数据转换接受一个 dict
作为输入,对其进行处理,并产生一个 dict
作为输出,供序列中的后续数据转换使用。
以下是一个例子,用于使用 VideoDataset
在 Kinetics 上训练 SlowFast 的数据流水线。这个数据流水线首先使用 decord
读取原始视频并随机采样一个视频剪辑,该剪辑包含 32
帧,帧间隔为 2
。然后,它对所有帧应用随机大小调整的裁剪和随机水平翻转,然后将数据形状格式化为 NCTHW
,在这个例子中,它是 (1, 3, 32, 224, 224)
。
train_pipeline = [
dict(type='DecordInit',),
dict(type='SampleFrames', clip_len=32, frame_interval=2, num_clips=1),
dict(type='DecordDecode'),
dict(type='Resize', scale=(-1, 256)),
dict(type='RandomResizedCrop'),
dict(type='Resize', scale=(224, 224), keep_ratio=False),
dict(type='Flip', flip_ratio=0.5),
dict(type='FormatShape', input_format='NCTHW'),
dict(type='PackActionInputs')
]
MMAction2 中所有可用的数据转换的详细列表可以在 mmaction.datasets.transforms 中找到。
修改训练/测试数据流水线¶
MMAction2 的数据流水线非常灵活,因为几乎每一步的数据预处理都可以从配置文件中进行配置。然而,对于一些用户来说,这种多样性可能会让人感到不知所措。
以下是一些用于构建动作识别任务数据流水线的一般实践和指南。
加载¶
在数据流水线的开始,通常是加载视频。然而,如果帧已经被提取出来,你应该使用 RawFrameDecode
并修改数据集类型为 RawframeDataset
。
train_pipeline = [
dict(type='SampleFrames', clip_len=32, frame_interval=2, num_clips=1),
dict(type='RawFrameDecode'),
dict(type='Resize', scale=(-1, 256)),
dict(type='RandomResizedCrop'),
dict(type='Resize', scale=(224, 224), keep_ratio=False),
dict(type='Flip', flip_ratio=0.5),
dict(type='FormatShape', input_format='NCTHW'),
dict(type='PackActionInputs')
]
如果你需要从具有不同格式(例如,pkl
,bin
等)的文件或从特定位置加载数据,你可以创建一个新的加载转换并将其包含在数据流水线的开始。有关更多详细信息,请参阅添加新的数据转换。
采样帧和其他处理¶
在训练和测试过程中,我们可能会有从视频中采样帧的不同策略。
例如,当测试 SlowFast 时,我们会均匀地采样多个剪辑,如下所示:
test_pipeline = [
...
dict(
type='SampleFrames',
clip_len=32,
frame_interval=2,
num_clips=10,
test_mode=True),
...
]
在上述例子中,每个视频将均匀地采样10个视频剪辑,每个剪辑包含32帧。 test_mode=True
用于实现这一点,与训练期间的随机采样相反。
另一个例子涉及 TSN/TSM
模型,它们从视频中采样多个片段:
train_pipeline = [
...
dict(type='SampleFrames', clip_len=1, frame_interval=1, num_clips=8),
...
]
通常,数据流水线中的数据增强只处理视频级的转换,例如调整大小或裁剪,而不处理像视频标准化或 mixup/cutmix 这样的转换。这是因为我们可以在批量视频数据上进行视频标准化和 mixup/cutmix,以使用 GPU 加速处理。要配置视频标准化和 mixup/cutmix,请使用 mmaction.models.utils.data_preprocessor。
格式化¶
格式化涉及从数据信息字典中收集训练数据,并将其转换为与模型兼容的格式。
在大多数情况下,你可以简单地使用 PackActionInputs
,它将以 NumPy Array
格式的图像转换为 PyTorch Tensor
,并将地面真实类别信息和其他元信息打包为一个类似字典的对象 ActionDataSample
。
train_pipeline = [
...
dict(type='PackActionInputs'),
]
添加新的数据转换¶
要创建一个新的数据转换,编写一个新的转换类在一个 Python 文件中,例如,名为
my_transforms.py
。数据转换类必须继承mmcv.transforms.BaseTransform
类,并重写transform
方法,该方法接受一个dict
作为输入并返回一个dict
。最后,将my_transforms.py
放在mmaction/datasets/transforms/
文件夹中。from mmcv.transforms import BaseTransform from mmaction.datasets import TRANSFORMS @TRANSFORMS.register_module() class MyTransform(BaseTransform): def __init__(self, msg): self.msg = msg def transform(self, results): # 修改数据信息字典 `results`。 print(msg, 'MMAction2.') return results
在
mmaction/datasets/transforms/__init__.py
中导入新类。... from .my_transform import MyTransform __all__ = [ ..., 'MyTransform' ]
在配置文件中使用它。
train_pipeline = [ ... dict(type='MyTransform', msg='Hello!'), ... ]