mmdetection-3.x学习笔记——数据集相关配置(coco_detection.py)

2023-03-28 Views mmdetection-3.x1289字6 min read

默认采用coco数据集,结构如下

├── data
│   ├── coco
│   │   ├── annotations
│   │   │   │--- instances_train2017.json
│   │   │   │--- instances_val2017.json
│   │   │   │--- image_info_test-dev2017.json    
│   │   │   │--- …… 
│   │   ├── train2017
│   │   │   │--- *.jpg(118287张图片)
│   │   ├── val2017
│   │   │   │--- *.jpg(5000张图片)
│   │   ├── test2017
│   │   │   │--- *.jpg(40670张图片)
# dataset settings
dataset_type = 'CocoDataset'  # 数据集类型,这将被用来定义数据集。
data_root = 'data/coco/'  # 数据的根路径。

# file_client_args = dict(
#     backend='petrel',
#     path_mapping=dict({
#         './data/': 's3://openmmlab/datasets/detection/',
#         'data/': 's3://openmmlab/datasets/detection/'
#     }))
file_client_args = dict(backend='disk')  # 文件读取后端的配置,默认从硬盘读取,上面的好像是网络存储设备

train_pipeline = [ # 训练数据处理流程
    # 第 1 个流程,从文件路径里加载图像。
    dict(type='LoadImageFromFile', file_client_args=file_client_args), 
    # 第 2 个流程,对于当前图像,加载它的注释信息。
    # with_bbox=True表示是否使用标注框(bounding box), 目标检测需要设置为 True。
    # 如果同时做语义分割,需要设with_mask=True 表示是否使用 instance mask。
    # poly2mask=False表示 是否将 polygon mask 转化为 instance mask, 设置为 False 以加速和节省内存。
    dict(type='LoadAnnotations', with_bbox=True),
    # 变化图像和其标注大小的流程。
    dict(
        type='Resize', 
        scale=(1333, 800),  # 图像的最大尺寸
        keep_ratio=True), # 是否保持图像的长宽比。
    # 翻转图像和其标注的数据增广流程。
    dict(
        type='RandomFlip',  
        prob=0.5), # 翻转图像的概率。
    # 将数据转换为检测器输入格式的流程
    # 数据增广过程中会产生很多中间数据并存放在同一个字典中,该流程主要是捡出目标检测需要的数据
    dict(type='PackDetInputs') 
]
test_pipeline = [ # 测试数据处理流程
    # 第 1 个流程,从文件路径里加载图像。
    dict(type='LoadImageFromFile', file_client_args=file_client_args),
    # 变化图像大小的流程。
    dict(type='Resize', scale=(1333, 800), keep_ratio=True),
    # 第 2 个流程,对于当前图像,加载它的注释信息。
    # If you don't have a gt annotation, delete the pipeline
    dict(type='LoadAnnotations', with_bbox=True),
    # 将数据转换为检测器输入格式的流程
    dict(
        type='PackDetInputs',
        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
                   'scale_factor'))
]
train_dataloader = dict( # 训练 dataloader 配置
    batch_size=2, # 单个 GPU 的 batch size
    num_workers=2, # 单个 GPU 分配的数据加载线程数
    persistent_workers=True, # 如果设置为 True,dataloader 在迭代完一轮之后不会关闭数据读取的子进程,可以加速训练
    sampler=dict(
        type='DefaultSampler',  # 默认的训练数据采样器,同时支持分布式和非分布式训练,其实就是打乱图片顺序
        shuffle=True), # 随机打乱每个轮次训练数据的顺序
    batch_sampler=dict(type='AspectRatioBatchSampler'), # 批数据采样器,用于确保每一批次内的数据拥有相似的长宽比,可用于节省显存
    dataset=dict( # 训练数据集的配置
        type=dataset_type,
        data_root=data_root,
        ann_file='annotations/instances_train2017.json', # 标注文件路径
        data_prefix=dict(img='train2017/'), # 图片路径前缀
        filter_cfg=dict(filter_empty_gt=True, min_size=32), # 图片和标注的过滤配置
        pipeline=train_pipeline))  # 这是由之前创建的 train_pipeline 定义的数据处理流程。

# 由上可见,mmdetection采用的是pytorch标准的数据集加载过程,
# 首先定义数据增广的流程train_pipeline,然后传入CocoDataset类,该类需要实现 def __getitem__(self, idx) 和  def __len__(self),然后把CocoDataset传入DataLoaders进行封装,DataLoaders可是实现数据批量获取

val_dataloader = dict( # 验证 dataloader 配置
    batch_size=1, # 单个 GPU 的 Batch size。如果 batch-szie > 1,组成 batch 时的额外填充会影响模型推理精度
    num_workers=2,
    persistent_workers=True,
    drop_last=False, # 是否丢弃最后未能组成一个批次的数据
    sampler=dict(type='DefaultSampler', shuffle=False), # 验证和测试时不打乱数据顺序
    dataset=dict(
        type=dataset_type,
        data_root=data_root,
        ann_file='annotations/instances_val2017.json',
        data_prefix=dict(img='val2017/'),
        test_mode=True,  # 开启测试模式,避免数据集过滤图片和标注
        pipeline=test_pipeline))
test_dataloader = val_dataloader # coco数据集的测试集不提供标注数据,所以一般就把验证集当测试集用

val_evaluator = dict( # 验证过程使用的评测器
    type='CocoMetric', # 用于评估检测和实例分割的 AR、AP 和 mAP 的 coco 评价指标
    ann_file=data_root + 'annotations/instances_val2017.json', # 标注文件路径
    metric='bbox', # 需要计算的评价指标,`bbox` 用于检测,还有`segm` 用于实例分割,如果同时做检测和分割,则设为 metric=['bbox', 'segm']
    format_only=False) # 是否只将模型输出转换为 coco 的 JSON 格式并保存,这里为否
test_evaluator = val_evaluator

#由于测试数据集没有标注文件,因此 MMDetection 中的 test_dataloader 和 test_evaluator 配置通常等于val。 如果要保存在测试数据集上的检测结果,则可以像这样编写配置:

# inference on test dataset and
# format the output results for submission.
#  注意:coco数据集并没有提供测试集的标注数据,如果想要知道测试集的准确率,
#  则需要导出预测结果并上传到COCO服务器进行评测,此时需要启用下面的test_dataloader
#  和test_evaluator,而且需要下载测试图片的信息放到annatations中
#(http://images.cocodataset.org/annotations/image_info_test2017.zip)
test_dataloader = dict(
    batch_size=1,
    num_workers=2,
    persistent_workers=True,
    drop_last=False,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type=dataset_type,
        data_root=data_root,
        ann_file=data_root + 'annotations/image_info_test-dev2017.json', # 测试图片信息
        data_prefix=dict(img='test2017/'),
        test_mode=True, 
        pipeline=test_pipeline))
test_evaluator = dict(
    type='CocoMetric',
    metric='bbox',
    format_only=True, # 这里是关键,设置为True之后只将模型输出转换为 coco 的 JSON 格式并保存
    ann_file=data_root + 'annotations/image_info_test-dev2017.json',
    outfile_prefix='./work_dirs/coco_detection/test') # 要保存的 JSON 文件的前缀

EOF