使用Detectron2训练自定义数据集时的类别ID错误问题
Detectron2自定义193类数据集报错category_id=194的解决办法
以下是针对该报错的排查和解决步骤:
1. 检查标注文件的category_id合法性
- 打开标注文件(如COCO格式的
annotations.json),统计所有category_id的最大值,确认是否存在194这个ID:- 若为标注错误,直接删除对应标注或修正category_id到1-193范围内;
- 若实际类别数确实是194,重新确认数据集类别数量,同步修改
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 194,并确保后续所有配置和元数据匹配。
- 若标注里的category_id是1-based(从1到193),需在自定义数据集加载代码中转换为Detectron2默认的0-based索引:
# 在加载标注的函数中添加转换逻辑 for ann in annotations: ann["category_id"] = ann["category_id"] - 1 # 转换为0开始的索引
2. 校验数据集元数据与配置一致性
- 检查数据集注册时的元数据类别列表长度是否为193:
from detectron2.data import MetadataCatalog metadata = MetadataCatalog.get("your_dataset_name") print(len(metadata.thing_classes)) # 输出必须为193 - 如果长度不符,修正注册代码中的
thing_classes列表,确保其包含193个类别名称,与数据集实际类别一一对应。
3. 处理预训练权重加载问题
- 若使用了COCO预训练模型,修改类别数后需确保ROI Heads权重正确初始化:
- 加载模型时设置
strict=False,跳过与当前类别数不匹配的预训练权重层:from detectron2.engine import DefaultTrainer trainer = DefaultTrainer(cfg) trainer.resume_or_load(resume=False, strict=False) - 或者直接在配置中指定仅加载主干网络权重,重新训练头部:
cfg.MODEL.WEIGHTS = "path/to/backbone/weights.pth" cfg.MODEL.BACKBONE.FREEZE_AT = 2 # 根据需求冻结主干部分层
- 加载模型时设置
4. 排查推理阶段的配置匹配
- 若报错出现在推理阶段,确认推理代码使用的配置文件与训练时完全一致:
- 确保推理时的
cfg.MODEL.ROI_HEADS.NUM_CLASSES设置为193; - 检查推理加载的数据集是否与训练集使用相同的标注规则(如category_id是否已转换为0-based)。
- 确保推理时的
内容的提问来源于stack exchange,提问作者Nitya Rakhe
相关产品推荐
相关产品推荐

