数据加载器

数据加载器是向模型提供数据的组件。 数据加载器通常(但不一定)从数据集中获取原始信息, 并将其处理成模型所需的格式。

现有数据加载器的工作原理

Detectron2内置了一个数据加载管道。理解其工作原理很有帮助,以防您需要编写自定义管道。

Detectron2提供了两个函数 build_detection_{train,test}_loader 用于从给定配置创建默认数据加载器。以下是build_detection_{train,test}_loader的工作原理:

  1. 它接收一个已注册数据集的名称(例如“coco_2017_train”),并以轻量级格式加载代表数据集项的list[dict]。这些数据集项尚未准备好供模型使用(例如,图像尚未加载到内存中,随机增强尚未应用等)。关于数据集格式和数据集注册的详细信息可以在datasets中找到。

  2. 此列表中的每个字典都由一个函数(“mapper”)映射:

    • 用户可以通过在build_detection_{train,test}_loader中指定"mapper"参数来自定义这个映射函数。默认的映射器是DatasetMapper

    • 映射器的输出格式可以是任意的,只要能被该数据加载器的使用者(通常是模型)接受即可。默认映射器的输出在批处理后遵循Use Models中记录的默认模型输入格式。

    • 映射器(mapper)的作用是将数据项的轻量级表示转换为模型可直接使用的格式(包括读取图像、执行随机数据增强并转换为torch张量等操作)。如果您希望对数据执行自定义转换,通常需要自定义映射器。

  3. 映射器的输出会被批量处理(简单地放入一个列表中)。

  4. 这批数据是数据加载器的输出。通常,它也是model.forward()的输入。

编写自定义数据加载器

在大多数自定义数据加载的使用场景中,使用不同的"mapper"配合build_detection_{train,test}_loader(mapper=)即可实现。例如,若您希望在训练时将全部图像调整为固定尺寸,可使用:

import detectron2.data.transforms as T
from detectron2.data import DatasetMapper   # the default mapper
dataloader = build_detection_train_loader(cfg,
   mapper=DatasetMapper(cfg, is_train=True, augmentations=[
      T.Resize((800, 800))
   ]))
# use this dataloader instead of the default

如果默认的DatasetMapper参数无法满足您的需求,您可以编写自定义映射函数并使用它,例如:

from detectron2.data import detection_utils as utils
 # Show how to implement a minimal mapper, similar to the default DatasetMapper
def mapper(dataset_dict):
    dataset_dict = copy.deepcopy(dataset_dict)  # it will be modified by code below
    # can use other ways to read image
    image = utils.read_image(dataset_dict["file_name"], format="BGR")
    # See "Data Augmentation" tutorial for details usage
    auginput = T.AugInput(image)
    transform = T.Resize((800, 800))(auginput)
    image = torch.from_numpy(auginput.image.transpose(2, 0, 1))
    annos = [
        utils.transform_instance_annotations(annotation, [transform], image.shape[1:])
        for annotation in dataset_dict.pop("annotations")
    ]
    return {
       # create the format that the model expects
       "image": image,
       "instances": utils.annotations_to_instances(annos, image.shape[1:])
    }
dataloader = build_detection_train_loader(cfg, mapper=mapper)

如果您不仅想更改映射器(例如为了实现不同的采样或批处理逻辑), build_detection_train_loader将无法满足需求,您需要编写不同的数据加载器。 数据加载器本质上是一个 python迭代器,它会生成模型接受的格式。 您可以使用任何喜欢的工具来实现它。

无论要实现什么功能,都建议查阅detectron2.data的API文档,以了解更多关于这些函数API的信息。

使用自定义数据加载器

如果您使用DefaultTrainer, 可以通过重写其build_{train,test}_loader方法来使用自定义的数据加载器。 具体示例可参考deeplab dataloader

如果您编写自己的训练循环,可以轻松插入您的数据加载器。