ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

MMDetection 数据集定制完全指南:从 COCO 格式转换到自定义 Dataset 实现

MMDetection 数据集定制完全指南:从 COCO 格式转换到自定义 Dataset 实现 MMDetection 数据集定制完全指南从 COCO 格式转换到自定义 Dataset 实现【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetection导读本指南系统讲解 MMDetection 中如何接入全新的检测数据集既包括把数据离线转换为 COCO / PASCAL 格式后仅修改配置的最小改动方案也包括使用 MMEngine 中间格式、编写自定义BaseDetDataset子类加载任意文本标注的进阶方案并覆盖数据集包装器Dataset Wrapper、类别子集训练与 COCO Panoptic 全景分割数据的接入方法。读完本文你将能够独立完成新数据集 → 配置文件 → 训练/评估的完整链路并理解 MMDetection 数据层在mmdet/datasets下的底层实现机制。支持新数据格式四条可选路径面对一个全新的数据格式MMDetection 提供了三种转换目标与两种转换时机转换目标说明后续工作COCO 格式标注转成images/annotations/categories三个 key 的 JSON修改配置中的标注路径与类别即可PASCAL VOC 格式转成 VOC XML 标注同上MMEngine 中间格式转成包含metainfo与data_list的 JSON / YAML / Pickle直接在配置中使用BaseDetDataset转换时机做法适用场景离线转换训练前用脚本一次性转换推荐做法在线转换实现新 Dataset 类在加载时转换标注格式特殊、无法离线归一MMDetection 官方推荐把数据离线转换为 COCO 格式转换完成后你只需要修改配置文件中的ann_file、data_prefix和类别信息无需改动任何训练代码同时实例分割类数据集目前只支持 COCO 格式的 mask AP 评估。方案一把新数据整理成 COCO 格式COCO 标注 JSON 的必要字段COCO 格式的标注 JSON 必须包含以下三个 key缺一不可images: [ { file_name: COCO_val2014_000000001268.jpg, height: 427, width: 640, id: 1268 }, ... ], annotations: [ { segmentation: [[192.81, 247.09, ... 219.03, 249.06]], # 如果有 mask 标注且为多边形 XY 点坐标格式 # 需要保证至少包含 3 个点否则为非法多边形。 area: 1035.749, iscrowd: 0, image_id: 1268, bbox: [192.81, 224.8, 74.73, 33.43], category_id: 16, id: 42986 }, ... ], categories: [ {id: 0, name: car}, ]images图片信息列表含file_name、height、width、idannotations实例标注列表categories类别名称与其 ID 的映射列表。步骤 1修改配置文件以5 个自定义类别 COCO 格式训练 Cascade Mask R-CNN R50-FPN 为例修改涉及两个层面data字段在train_dataloader.dataset、val_dataloader.dataset、test_dataloader.dataset中显式添加metainfodict(classesclasses)且classes必须是tuple 类型model字段中的num_classes把默认值COCO 为 80显式覆盖为你的类别数所有头都要改。在configs/my_custom_config.py中# 新配置继承基础配置突出必要修改 _base_ ./cascade_mask_rcnn_r50_fpn_1x_coco.py # 1. 数据集设置 dataset_type CocoDataset classes (a, b, c, d, e) data_rootpath/to/your/ train_dataloader dict( batch_size2, num_workers2, datasetdict( typedataset_type, # 显式把你的类别名写入 metainfo 字段 metainfodict(classesclasses), data_rootdata_root, ann_filetrain/annotation_data, data_prefixdict(imgtrain/image_data) ) ) val_dataloader dict( batch_size1, num_workers2, datasetdict( typedataset_type, test_modeTrue, # 显式把你的类别名写入 metainfo 字段 metainfodict(classesclasses), data_rootdata_root, ann_fileval/annotation_data, data_prefixdict(imgval/image_data) ) ) test_dataloader dict( batch_size1, num_workers2, datasetdict( typedataset_type, test_modeTrue, # 显式把你的类别名写入 metainfo 字段 metainfodict(classesclasses), data_rootdata_root, ann_filetest/annotation_data, data_prefixdict(imgtest/image_data) ) ) # 2. 模型设置 # 显式把所有 num_classes 字段从默认 80 覆盖为 5 model dict( roi_headdict( bbox_head[ dict( typeShared2FCBBoxHead, # 显式把所有 num_classes 字段从默认 80 覆盖为 5 num_classes5), dict( typeShared2FCBBoxHead, # 显式把所有 num_classes 字段从默认 80 覆盖为 5 num_classes5), dict( typeShared2FCBBoxHead, # 显式把所有 num_classes 字段从默认 80 覆盖为 5 num_classes5)], # 显式把所有 num_classes 字段从默认 80 覆盖为 5 mask_headdict(num_classes5)))这段配置的底层逻辑可以在 mmdet/datasets/coco.py 中印证CocoDataset.load_data_list通过self.coco.get_cat_ids(cat_namesself.metainfo[classes])按metainfo中的类别顺序解析cat_ids再构造self.cat2label {cat_id: i for i, cat_id in enumerate(self.cat_ids)}完成COCO category_id → 连续 label 索引的映射parse_data_info中遇到ann[category_id] not in self.cat_ids的标注会直接跳过。也就是说metainfo里的类别顺序直接决定了训练时 label 的编码顺序。步骤 2核对自定义数据集标注假设你的数据集已是 COCO 格式训练前请核对以下三点标注中categories字段的长度必须恰好等于配置中classes元组的长度本例为 5配置中classes的元素与顺序必须和标注categories里的name完全一致。MMDetection 会自动把categories中不连续的id映射为连续 label 索引因此name的字符串顺序会影响 label 索引顺序同时配置中classes的字符串顺序也决定了可视化预测框时的类别文本annotations中的category_id必须合法即所有取值都应属于categories中的id。下面是一份合法的标注示例categories的id不连续MMDetection 会自动映射为连续 labelannotations: [ { segmentation: [[192.81, 247.09, ... 219.03, 249.06]], # 如果有 mask 标注 area: 1035.749, iscrowd: 0, image_id: 1268, bbox: [192.81, 224.8, 74.73, 33.43], category_id: 16, id: 42986 }, ... ], # MMDetection 自动把不连续的 id 映射为连续 label 索引。 categories: [ {id: 1, name: a}, {id: 3, name: b}, {id: 4, name: c}, {id: 16, name: d}, {id: 17, name: e}, ]官方实例Cityscapes这套转换为 COCO 格式 微调的流程在 Cityscapes 上被官方验证过转换脚本位于 tools/dataset_converters/cityscapes.py内含collect_files、collect_annotations、cvt_annotations等函数通过parse_args解析--img-dir、--gt-dir、--out-json等参数后写出 COCO JSON配套的微调配置位于 configs/cityscapes。注意事项对于实例分割数据集MMDetection 目前只支持评估 COCO 格式数据集的 mask AP推荐在训练前离线完成数据转换这样仍可使用现成的CocoDataset只需要修改标注路径与训练类别。方案二把新数据整理成 MMEngine 中间格式如果不想把标注转成 COCO 或 PASCAL 格式也可以直接转换为 MMEngine 定义在BaseDataset中的简单中间格式。仓库中所有现有数据集最终都会被处理成与该格式兼容的结构无论是离线还是在线。中间格式的标注文件必须是json、yaml、yml、pickle或pkl之一文件内存储的字典必须包含两个字段metainfo字典存放数据集元信息如类别信息data_list列表每个元素是对应一张图片原始数据的字典可包含一个或多个训练/测试样本。示例{ metainfo: { classes: (person, bicycle, car, motorcycle), ... }, data_list: [ { img_path: xxx/xxx_1.jpg, height: 604, width: 640, instances: [ { bbox: [0, 0, 10, 20], bbox_label: 1, ignore_flag: 0 }, { bbox: [10, 10, 110, 120], bbox_label: 2, ignore_flag: 0 } ] }, { img_path: xxx/xxx_2.jpg, height: 320, width: 460, instances: [ { bbox: [10, 0, 20, 20], bbox_label: 3, ignore_flag: 1, } ] }, ... ] }有些数据集会提供 crowd / difficult / ignored 等类型的 bboxMMDetection 用ignore_flag统一表达1表示在训练/评估中忽略该实例。拿到上述标准格式后可以直接在配置中使用 mmdet/datasets/base_det_dataset.py 中注册的BaseDetDataset无需再写转换代码。从源码看BaseDetDataset继承自 MMEngine 的BaseDataset其full_init依次执行load_data_list从标注文件加载→load_proposals如配置了 proposal 文件→filter_data按filter_cfg过滤→ 子集切片与序列化这也解释了为何自定义数据集只需实现load_data_list即可接入完整训练流程。实战为全新文本标注格式编写自定义数据集类假设标注是如下文本格式#为图片分隔符第二行为图片名第三行为宽高第四行为 bbox 数量随后每行是一条x1 y1 x2 y2 label格式的标注。# 000001.jpg 1280 720 2 10 20 40 60 1 20 40 50 60 2 # 000002.jpg 1280 720 3 50 20 40 60 2 20 40 30 45 2 30 40 50 60 3我们可以在mmdet/datasets/my_dataset.py中新建数据集类来加载它import mmengine from mmdet.base_det_dataset import BaseDetDataset from mmdet.registry import DATASETS DATASETS.register_module() class MyDataset(BaseDetDataset): METAINFO { classes: (person, bicycle, car, motorcycle), palette: [(220, 20, 60), (119, 11, 32), (0, 0, 142), (0, 0, 230)] } def load_data_list(self, ann_file): ann_list mmengine.list_from_file(ann_file) data_infos [] for i, ann_line in enumerate(ann_list): if ann_line ! #: continue img_shape ann_list[i 2].split( ) width int(img_shape[0]) height int(img_shape[1]) bbox_number int(ann_list[i 3]) instances [] for anns in ann_list[i 4:i 4 bbox_number]: instance {} instance[bbox] [float(ann) for ann in anns.split( )[:4]] instance[bbox_label]int(anns[4]) instances.append(instance) data_infos.append( dict( img_pathann_list[i 1], img_idi, widthwidth, heightheight, instancesinstances )) return data_infos几个要点通过DATASETS.register_module()注册类名之后配置中可直接写typeMyDatasetMETAINFO中定义classes与palette调色板用于可视化只需要实现load_data_list返回符合中间格式的data_infos列表即可其余初始化、过滤、序列化逻辑全部由BaseDetDataset承接上述示例中instance[bbox_label] int(anns[4])实际上取的是整行字符串的字符严格应写为int(anns.split( )[4])即对每一行先split再取第 5 个字段作为类别标签请在实际实现时留意。随后在配置中像使用内置数据集一样使用它dataset_A_train dict( typeMyDataset, ann_file image_list.txt, pipelinetrain_pipeline )用数据集包装器混合与重分布数据MMEngine 还提供了多种数据集包装器Dataset Wrapper用于混合数据集或调整训练时的数据分布。目前支持以下三种RepeatDataset简单重复整个数据集ClassBalancedDataset按类别均衡的方式重复数据缓解类别不平衡ConcatDataset拼接多个数据集。它们与 MMDetection 注册体系兼容可在train_dataloader.dataset位置直接嵌套使用例如把多个MyDataset拼接后再送入训练。详细用法可查阅 MMEngine 的 Dataset Wrapper 文档。修改数据集类别只训练部分类别基于现有数据集类型我们可以通过修改其metainfo来训练标注的子集。例如只想训练当前数据集中三个类别时classes (person, bicycle, car) train_dataloader dict( datasetdict( metainfodict(classesclasses)) ) val_dataloader dict( datasetdict( metainfodict(classesclasses)) ) test_dataloader dict( datasetdict( metainfodict(classesclasses)) )数据集会自动过滤掉其他类别的 GT 框其机制见上文parse_data_info中ann[category_id] not in self.cat_ids的跳过逻辑。注意行为变更v2.5.0 起在此之前一旦设置了classes数据集会自动过滤无 GT 图片且无法通过配置关闭这引发了不少困惑——因为未设置classes时只有在filter_empty_gtTrue且test_modeFalse时才会过滤空 GT 图片。v2.5.0 之后图片过滤与类别修改被解耦无论是否设置classes只有filter_cfgdict(filter_empty_gtTrue)且test_modeFalse时才过滤空 GT 图片。因此设置classes只影响参与训练的标注类别是否过滤空 GT 图片完全由用户自己决定。从 mmdet/datasets/coco.py 的filter_data实现可见过滤条件确实只与filter_cfgfilter_empty_gt、min_size和test_mode相关与metainfo[classes]无关直接使用 MMEngine 的BaseDataset或 MMDetection 的BaseDetDataset时无法仅靠配置过滤无 GT 图片只能离线处理务必记得同步修改检测头中的num_classes。自 v2.9.0PR#4508起MMDetection 实现了 mmdet/engine/hooks/num_class_check_hook.py 中的NumClassCheckHook来校验二者是否一致。NumClassCheckHook训练前的自检机制NumClassCheckHook继承自 MMEngine 的Hook在before_train_epoch与before_val_epoch阶段调用_check_head遍历模型所有模块凡带有num_classes属性的模块排除rpn_head、VGG 与FusedSemanticHead都会断言module.num_classes len(classes)不匹配时直接报错若数据集metainfo中未设置classes则会输出警告。它同时强制要求classes必须是str 的 tuple而非单个字符串单类别需写成classes (cls,)这种带逗号的形式。该 Hook 已注册在HOOKS注册表中相关配置用法可见 configs/ssd/ssd300_coco.py、configs/ssd/ssdlite_mobilenetv2-scratch_8xb24-600e_coco.py 等在 configs/panoptic_fpn/panoptic-fpn_r50_fpn_1x_coco.py 中则可以看到移除该 Hook 的注释示例说明在个别特殊模型上可通过custom_hooks配置关闭这一自检。COCO Panoptic 数据集MMDetection 同样支持 COCO Panoptic全景分割数据集。其标注格式与普通 COCO 不同前景与背景同时存在于标注文件中。JSON 的必要字段如下images: [ { file_name: 000000001268.jpg, height: 427, width: 640, id: 1268 }, ... ] annotations: [ { filename: 000000001268.jpg, image_id: 1268, segments_info: [ { id:8345037, # 与标注图中的 id 一一对应 category_id: 51, iscrowd: 0, bbox: (x1, y1, w, h), # 背景的 bbox 是其 mask 的外接矩形 area: 24315 }, ... ] }, ... ] categories: [ # 同时包含前景类别与背景类别 {id: 0, name: person}, ... ]此外配置中必须通过data_prefix的seg字段指定全景标注图片panoptic annotation images的路径。从源码看mmdet/datasets/coco_panoptic.py 中的CocoPanopticDataset继承自CocoDataset其METAINFO中同时定义了classesthing stuff 全部类别、thing_classes与stuff_classes并通过seg_map_suffix关联seg前缀下的 PNG 标注图。dataset_type CocoPanopticDataset data_rootpath/to/your/ train_dataloader dict( datasetdict( typedataset_type, data_rootdata_root, data_prefixdict( imgtrain/image_data/, segtrain/panoptic/image_annotation_data/) ) ) val_dataloader dict( datasetdict( typedataset_type, data_rootdata_root, data_prefixdict( imgval/image_data/, segval/panoptic/image_annotation_data/) ) ) test_dataloader dict( datasetdict( typedataset_type, data_rootdata_root, data_prefixdict( imgtest/image_data/, segtest/panoptic/image_annotation_data/) ) )总结接入新数据集的核心决策树可以概括为优先离线转换为 COCO 格式改动最小实例分割 mask 评估也仅支持 COCO标注结构特殊时转换为 MMEngine 中间格式并直接使用BaseDetDataset若两者都不满足则继承BaseDetDataset实现load_data_list在线解析。无论走哪条路径都别忘了两个关键配套动作在三个 dataloader 的metainfo中写全 tuple 类型的classes并同步覆盖所有检测头的num_classes交给NumClassCheckHook兜底校验。配合 configs/base/datasets/coco_detection.py 中的基础数据配置、tools/dataset_converters/cityscapes.py 的转换脚本示例以及 mmdet/datasets 目录下丰富的内置数据集实现CocoDataset、CocoPanopticDataset、VOCDataset等即可在 MMDetection 中高效复现本文的全部流程。【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetection创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表