在本教程中,我们将介绍一些有关如何按已支持的数据格式进行数据组织,和组合已有数据集来自定义数据集的方法。
最简单的方法是将数据集转换为现有的数据集格式(RawframeDataset 或 VideoDataset)。
有三种标注文件:
-
帧标注(rawframe annotation)
帧数据集(rawframe dataset)标注文件由多行文本组成,每行代表一个样本,每个样本分为三个部分,分别是
帧(相对)文件夹
(rawframe directory of relative path),总帧数
(total frames)以及标签
(label),通过空格进行划分示例如下:
some/directory-1 163 1 some/directory-2 122 1 some/directory-3 258 2 some/directory-4 234 2 some/directory-5 295 3 some/directory-6 121 3
-
视频标注(video annotation)
视频数据集(video dataset)标注文件由多行文本组成,每行代表一个样本,每个样本分为两个部分,分别是
文件(相对)路径
(filepath of relative path) 和标签
(label),通过空格进行划分示例如下:
some/path/000.mp4 1 some/path/001.mp4 1 some/path/002.mp4 2 some/path/003.mp4 2 some/path/004.mp4 3 some/path/005.mp4 3
-
ActivityNet 标注
ActivityNet 数据集的标注文件是一个 json 文件。每个键是一个视频名,其对应的值是这个视频的元数据和注释。
示例如下:
{ "video1": { "duration_second": 211.53, "duration_frame": 6337, "annotations": [ { "segment": [ 30.025882995319815, 205.2318595943838 ], "label": "Rock climbing" } ], "feature_frame": 6336, "fps": 30.0, "rfps": 29.9579255898 }, "video2": { "duration_second": 26.75, "duration_frame": 647, "annotations": [ { "segment": [ 2.578755070202808, 24.914101404056165 ], "label": "Drinking beer" } ], "feature_frame": 624, "fps": 24.0, "rfps": 24.1869158879 } }
有两种使用自定义数据集的方法:
-
在线转换
用户可以通过继承 BaseDataset 基类编写一个新的数据集类,并重写三个抽象类方法:
load_annotations(self)
,evaluate(self, results, metrics, logger)
和dump_results(self, results, out)
, 如 RawframeDataset,VideoDataset 或 ActivityNetDataset。 -
本地转换
用户可以转换标注文件格式为上述期望的格式,并将其存储为 pickle 或 json 文件,然后便可以应用于
RawframeDataset
,VideoDataset
或ActivityNetDataset
中。
数据预处理后,用户需要进一步修改配置文件以使用数据集。 这里展示了以帧形式使用自定义数据集的例子:
在 configs/task/method/my_custom_config.py
下:
...
# 数据集设定
dataset_type = 'RawframeDataset'
data_root = 'path/to/your/root'
data_root_val = 'path/to/your/root_val'
ann_file_train = 'data/custom/custom_train_list.txt'
ann_file_val = 'data/custom/custom_val_list.txt'
ann_file_test = 'data/custom/custom_val_list.txt'
...
data = dict(
videos_per_gpu=32,
workers_per_gpu=2,
train=dict(
type=dataset_type,
ann_file=ann_file_train,
...),
val=dict(
type=dataset_type,
ann_file=ann_file_val,
...),
test=dict(
type=dataset_type,
ann_file=ann_file_test,
...))
...
假设注释在文本文件中以新格式显示,并且图像文件名具有类似 “img_00005.jpg” 的模板。
那么视频注释将以以下形式存储在文本文件 annotation.txt
中。
#文件夹,总帧数,类别
D32_1gwq35E,299,66
-G-5CJ0JkKY,249,254
T4h1bvOd9DA,299,33
4uZ27ivBl00,299,341
0LfESFkfBSw,249,186
-YIsNpBEx6c,299,169
在 mmaction/datasets/my_dataset.py
中创建新数据集加载数据
import copy
import os.path as osp
import mmcv
from .base import BaseDataset
from .builder import DATASETS
@DATASETS.register_module()
class MyDataset(BaseDataset):
def __init__(self,
ann_file,
pipeline,
data_prefix=None,
test_mode=False,
filename_tmpl='img_{:05}.jpg'):
super(MyDataset, self).__init__(ann_file, pipeline, test_mode)
self.filename_tmpl = filename_tmpl
def load_annotations(self):
video_infos = []
with open(self.ann_file, 'r') as fin:
for line in fin:
if line.startswith("directory"):
continue
frame_dir, total_frames, label = line.split(',')
if self.data_prefix is not None:
frame_dir = osp.join(self.data_prefix, frame_dir)
video_infos.append(
dict(
frame_dir=frame_dir,
total_frames=int(total_frames),
label=int(label)))
return video_infos
def prepare_train_frames(self, idx):
results = copy.deepcopy(self.video_infos[idx])
results['filename_tmpl'] = self.filename_tmpl
return self.pipeline(results)
def prepare_test_frames(self, idx):
results = copy.deepcopy(self.video_infos[idx])
results['filename_tmpl'] = self.filename_tmpl
return self.pipeline(results)
def evaluate(self,
results,
metrics='top_k_accuracy',
topk=(1, 5),
logger=None):
pass
然后在配置文件中,用户可通过如下修改来使用 MyDataset
:
dataset_A_train = dict(
type='MyDataset',
ann_file=ann_file_train,
pipeline=train_pipeline
)
MMAction2 还支持组合已有数据集以进行训练。 目前,它支持重复数据集(repeat dataset)。
MMAction2 使用 “RepeatDataset” 作为包装器来重复数据集。例如,假设原始数据集为 “Dataset_A”, 为了重复此数据集,可设置配置如下:
dataset_A_train = dict(
type='RepeatDataset',
times=N,
dataset=dict( # 这是 Dataset_A 的原始配置
type='Dataset_A',
...
pipeline=train_pipeline
)
)