Shortcuts

教程 3:如何增加新数据集

在本教程中,我们将介绍一些有关如何按已支持的数据格式进行数据组织,和组合已有数据集来自定义数据集的方法。

通过重组数据来自定义数据集

将数据集重新组织为现有格式

最简单的方法是将数据集转换为现有的数据集格式(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), 如 RawframeDatasetVideoDatasetActivityNetDataset

  • 本地转换

    用户可以转换标注文件格式为上述期望的格式,并将其存储为 pickle 或 json 文件,然后便可以应用于 RawframeDatasetVideoDatasetActivityNetDataset 中。

数据预处理后,用户需要进一步修改配置文件以使用数据集。 这里展示了以帧形式使用自定义数据集的例子:

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
        )
    )
Read the Docs v: latest
Versions
latest
stable
1.x
v1.0.0rc1
dev-1.x
Downloads
pdf
html
epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.