Detectron2训练Faster-RCNN模型分类精度低问题求助
问题背景
我正在开展一项关于目标检测与合成数据集生成的大学科研项目,尝试使用Detectron2框架在GTSDB数据集上训练Faster-RCNN模型,但分类精度表现不佳。这是我首次接触AI相关工作,若问题表述有欠清晰或专业度不足,敬请谅解。
我已遵循官方Detectron2 Colab Notebook教程及其他同类教程,适配Faster-RCNN架构完成自定义数据集训练,训练代码如下:
# load_dataset function implementation omitted DatasetCatalog.register("GTSDB_train", lambda: helpers.load_dataset(helpers.GTSDB_TRAIN_PATH)) model = "COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml" # CONFIG SETUP cfg = get_cfg() cfg.merge_from_file(model_zoo.get_config_file(model)) cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(model) cfg.DATALOADER.NUM_WORKERS = 4 cfg.SOLVER.IMS_PER_BATCH = 2 cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 512 cfg.MODEL.ROI_HEADS.NUM_CLASSES = 43 # dataset does contain 43 classes # warmup for the first 200 iterations cfg.SOLVER.WARMUP_ITERS = 200 cfg.SOLVER.WARMUP_FACTOR = 1.0/100 cfg.SOLVER.WARMUP_METHOR = "linear" cfg.SOLVER.BASE_LR = 0.001 # divide LR by 10 every 400 steps, train for 2000 cfg.SOLVER.MAX_ITER = 2000 cfg.SOLVER.GAMMA = 0.1 cfg.SOLVER.STEPS = [400, 800, 1200, 1600] cfg.DATASETS.TRAIN = ("GTSDB_train",) cfg.DATASETS.TEST = () os.makedirs(cfg.OUTPUT_DIR, exist_ok=True) trainer = DefaultTrainer(cfg) trainer.resume_or_load(resume=False) trainer.train()
我使用以下代码验证数据集是否正确注册:
#imports dataset = helpers.GTSDB_train_dataset() metadata = helpers.get_GTSDB_metadata() # metadata only contains class names for d in random.sample(dataset, 5): img = cv2.imread(d['file_name']) visualizer = Visualizer(img[:,:,::-1], metadata=metadata, scale=1.2) out = visualizer.draw_dataset_dict(d) cv2.imshow("img", out.get_image()[:,:,::-1]) cv2.waitKey(0)
从示例图可见,数据集已正确注册,边界框与类别名称均无误。
训练后TensorBoard结果显示:cls_accuracy稳定在90%以上,但fg_cls_accuracy始终较低,维持在20%左右。推理时,候选边界框分类结果错误或置信度低,边界框定位准确但分类效果差。
我尝试延长训练时长、调整学习率,但模型性能已趋于稳定,无明显提升。
提出的问题
- 为何
cls_accuracy高但fg_cls_accuracy低?这反映了模型的什么行为?是否正常? - 如何提升分类精度?应调整哪些超参数?
- 是否需要调整模型架构?当前使用Detectron2模型库中的预构建Faster-RCNN,仅修改配置项,是否会因图像分辨率、目标相对尺寸等问题影响性能?
解答
问题1:cls_accuracy与fg_cls_accuracy差异的原因
cls_accuracy是所有ROI(包括前景fg和背景bg)的分类准确率,而fg_cls_accuracy仅针对前景目标的分类准确率。两者差异大,说明模型在区分背景上做得很好,但对前景类别的分类能力极差。- 这种情况不正常,核心原因是训练时正负样本不均衡:Faster-RCNN的ROI Head会采样大量背景样本(通常正负样本比例1:3),背景样本分类简单(只需判定为“非目标”),拉高了整体的
cls_accuracy,但前景样本的分类错误率很高,导致fg_cls_accuracy偏低。
问题2:提升分类精度的超参数调整建议
- 调整正负样本采样策略
- 降低
cfg.MODEL.ROI_HEADS.POSITIVE_FRACTION(默认0.25),比如设为0.5,让训练时每个batch中前景样本占比更高,迫使模型更多学习前景类别的特征。 - 检查
cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE(当前512),如果数据集前景目标数量少,可适当减小这个值,确保每个batch里的前景样本绝对数量足够。
- 降低
- 优化学习率与训练策略
- 当前
BASE_LR=0.001,对于从COCO预训练权重迁移到GTSDB(小数据集)来说可能过高,建议调低到0.0001或0.0002,避免预训练特征被过度破坏。 - 取消过于频繁的学习率衰减:当前
STEPS=[400,800,1200,1600],每400步就降一次LR,可能导致模型还没充分学习就过早进入低学习率阶段。改为STEPS=[1200, 1800],或者使用余弦退火学习率(cfg.SOLVER.LR_SCHEDULER_NAME = "CosineAnnealingLR"),让学习率更平滑下降。 - 增加训练迭代次数:GTSDB有43类,2000次迭代可能不足,建议调到5000-8000次,同时配合验证集监控,避免过拟合。
- 当前
- 增强数据扩增
- 在数据集加载时加入更多针对交通标志的扩增:随机裁剪、旋转、亮度/对比度调整、高斯噪声等,提升模型的泛化能力。Detectron2中可通过修改
cfg.INPUT.AUG相关配置,或者在load_dataset函数中自定义扩增逻辑。
- 在数据集加载时加入更多针对交通标志的扩增:随机裁剪、旋转、亮度/对比度调整、高斯噪声等,提升模型的泛化能力。Detectron2中可通过修改
问题3:模型架构与输入适配调整
- 输入分辨率适配
- GTSDB的图像是1360x800,而COCO预训练模型默认输入分辨率较小(比如800x1333),可调整
cfg.INPUT.MIN_SIZE_TRAIN和cfg.INPUT.MAX_SIZE_TRAIN,比如设为[800, 1024, 1360]和1360,让模型适应原始图像尺寸,避免小目标被压缩丢失特征。
- GTSDB的图像是1360x800,而COCO预训练模型默认输入分辨率较小(比如800x1333),可调整
- 针对小目标的架构调整
- 交通标志属于小目标,当前使用的X101-FPN模型虽然强大,但FPN的低层特征可能不够突出。可尝试添加
cfg.MODEL.FPN.NORM = "GN"(组归一化),提升小目标特征的稳定性;或者改用更轻量但对小目标友好的模型,比如COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml,减少模型复杂度,避免在小数据集上过拟合。
- 交通标志属于小目标,当前使用的X101-FPN模型虽然强大,但FPN的低层特征可能不够突出。可尝试添加
- 类别权重调整
- GTSDB中部分交通标志类别样本数量可能不均衡,可在ROI Head中加入类别权重,让模型对样本少的类别给予更高的损失权重。Detectron2中可通过自定义
Trainer类,修改损失函数的权重参数实现。
- GTSDB中部分交通标志类别样本数量可能不均衡,可在ROI Head中加入类别权重,让模型对样本少的类别给予更高的损失权重。Detectron2中可通过自定义
内容的提问来源于stack exchange,提问作者Diogo Delazare
相关产品推荐
相关产品推荐

