PaddleDetection 少样本检测实战:基于 Label Co-tuning 与监督对比学习的 Few-shot 目标检测
2026/9/23 5:34:28 网站建设 项目流程
  • 人工智能
  • 深度学习
  • 计算机视觉

【免费下载链接】PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleDetection
点击查看免费下载

本文围绕 PaddleDetection 仓库中configs/few-shot目录下的少样本(Few-shot)目标检测方案展开,讲解如何利用Label Co-tuning(标签共调)Supervised Contrastive Learning(监督对比学习)两种迁移学习技术,在只有每类 10~30 个标注样本的极端数据条件下训练 Faster R-CNN 与 PPYOLOE 检测器。读完本文,你将掌握:少样本检测的数据准备与 "shots" 采样方式、两个官方配置文件的逐参数含义、底层损失函数与训练器的源码实现,以及完整的训练、评估、推理命令,可直接复现官方 Model Zoo 中的 Box AP 结果。

一、背景:少样本检测的挑战与两条技术路线

常规目标检测依赖大规模标注数据(如 COCO 的 11 万+ 图像)。但在工业质检、道路交通标志识别等真实场景中,标注成本极高,往往只能拿到每类十几张甚至几张样本,传统训练方式会严重过拟合。

configs/few-shot/目录给出了两种官方落地方案:

  1. Label Co-tuning(Faster R-CNN 路线):利用在大规模数据集(COCO 80 类)上预训练的检测模型作为"教师",先在少样本训练集上统计基类(base class)与新增类(novel class)之间的共现概率关系,再把这个关系矩阵注入检测头的分类分支,让少样本类别"借用"基类知识。对应配置为 faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign.yml,论文为Co-tuning for Transfer Learning(You et al., NeurIPS 2020)。
  2. Supervised Contrastive(PPYOLOE 路线):在 PPYOLOE 检测头上并联一个 128 维的对比编码器,用监督对比损失拉近同类别特征、推远异类别特征,增强少样本条件下的特征判别力。对应配置为 ppyoloe_plus_crn_s_80e_contrast_pcb.yml,论文为Supervised Contrastive Learning(Khosla et al., NeurIPS 2020)。

两条路线覆盖了当前少样本检测领域"参数迁移"与"表征学习"两大主流思路,下文分别深入展开。

二、数据准备:roadsign 与 PCB 工业数据集

原文档以两个真实数据集为例,说明了"自定义少样本数据"的完整准备流程。

2.1 road-sign-detection(道路交通标志)

  • 数据来源:Kaggle 竞赛数据集 road-sign-detection,共877 张图像4 个类别crosswalkspeedlimitstoptrafficlight
  • 下载方式:可从 Kaggle 页面下载,也可使用原文档提供的roadsign_coco.tar.gz下载链接(仓库中另有 dataset/roadsign_voc/download_roadsign_voc.py 可供参考 VOC 格式数据的下载脚本写法)。
  • "shots" 采样概念:从原始数据集中每类选取相同数量的样本作为训练集。例如10-shots 即每类只有 10 个训练样本(共 40 张训练图)。少样本训练的关键就在于把数据裁剪到极少量的程度,再验证算法的抗过拟合能力。
  • 使用前需转换为 COCO 标注格式(train_shots10.json/roadsign_valid.json),并放置到dataset/roadsign_coco目录下,目录内包含images/annotations/两个子目录。

2.2 PKU-Market-PCB(印刷电路板缺陷检测)

  • 工业数据集 PKU-Market-PCB,用于印刷电路板(PCB)的瑕疵检测,提供6 种常见 PCB 缺陷(对应配置中num_classes: 6)。
  • 训练时每类选取 30 个样本(30-shots),标注文件为pcb_cocoanno/train_shots30.json,数据集根目录为dataset/pcb
  • 该数据集覆盖了少样本检测在工业质检场景的典型应用:缺陷样本稀少、类别不平衡、且与自然图像分布差异大,正好考验对比学习的特征泛化能力。

2.3 数据目录组织要求

从两份配置文件中的TrainDataset/EvalDataset/TestDataset可以看到统一的数据组织约定:

数据项roadsign 示例PCB 示例
训练标注annotations/train_shots10.jsonpcb_cocoanno/train_shots30.json
验证标注annotations/roadsign_valid.jsonpcb_cocoanno/val.json
图像目录imagesimages
数据集根目录dataset/roadsign_cocodataset/pcb

训练集通过data_fields: ['image', 'gt_bbox', 'gt_class', 'is_crowd']声明读取字段,推理阶段则改用!ImageFolder直接读取图片目录,无需标注文件。

三、路线一:Label Co-tuning + Faster R-CNN 少样本检测

3.1 核心思想

Co-tuning 的核心假设是:类别之间并非独立,存在可迁移的共现关系。例如"人行横道"与"交通灯"经常同框出现,若模型在 COCO 基类上学到了"交通灯"的可靠特征,那么少量"人行横道"样本也能通过关系矩阵受益。

实现上分为三步(见 trainer_cot.py 的TrainerCot):

  1. 加载 COCO 预训练权重(self.load_weights(self.cfg.pretrain_weights));
  2. 冻结模型,在少样本训练集上执行relationship_learning,统计每个 novel 类对 80 个 base 类的平均预测概率,得到一个num_classes_novel × 80条件概率关系矩阵
  3. 通过init_cot_head(relationship)把关系矩阵注入BBoxHead,随后正常训练。

3.2 关系矩阵的源码计算过程

关系矩阵的计算实现在 faster_rcnn.py 的relationship_learning方法中:

  • 用预训练模型在训练集上逐 batch 调用target_bbox_forward,其内部以cot=True走检测头,输出的是80 维 base 类预测概率(见 bbox_head.py);
  • 同时收集每个框的真实 novel 标签gt_class
  • 对每个 novel 类 i,取出所有"预测为各类"的样本概率做平均:average = np.mean(this_class, axis=0),最终返回拼接后的条件概率矩阵。

即关系矩阵的每一项R[i, j]表示:当真实标签为 novel 类 i 时,预训练模型给出的 base 类 j 的平均预测概率。这个矩阵在训练过程中保持固定(stop_gradient=True),只作为分类头的软标签监督信号。

3.3 配置文件逐段精读

配置文件 的核心结构如下:

_BASE_: [ '../datasets/coco_detection.yml', # 基础数据与类别定义(COCO 风格) '../runtime.yml', # 运行环境、日志等全局配置 '_base_/optimizer_1x.yml', # 学习率与优化器 '_base_/faster_rcnn_r50_fpn.yml', # 骨干网络与 FPN 结构 '_base_/faster_fpn_reader.yml', # 数据读取与预处理 ] pretrain_weights: https://paddledet.bj.bcebos.com/models/faster_rcnn_r50_vd_fpn_1x_coco.pdparams weights: output/faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign/model_final snapshot_epoch: 5 # 每 5 个 epoch 保存一次 checkpoint

骨干网络段明确指定ResNet50-vdvariant: d),freeze_at: 0表示骨干不冻结、参与少样本微调:

ResNet: depth: 50 variant: d norm_type: bn freeze_at: 0 return_idx: [0,1,2,3] num_stages: 4

训练超参数与 COT 开关是这条路线最关键的配置:

epoch: 30 LearningRate: base_lr: 0.001 schedulers: - !PiecewiseDecay gamma: 0.1 milestones: [8, 11] # 第 8、11 epoch 学习率衰减 10 倍 - !LinearWarmup start_factor: 0.1 # 从 10% 学习率线性预热 steps: 1000 use_cot: True # 开启 Label Co-tuning BBoxHead: head: TwoFCHead roi_extractor: resolution: 7 sampling_ratio: 0 aligned: True bbox_assigner: BBoxAssigner cot_classes: 80 # 基类数量(对应 COCO 80 类) loss_cot: name: COTLoss cot_lambda: 1 # COT 损失权重 cot_scale: 1 # logits 缩放系数

注意点:

  • num_classes: 4是 novel 类数量(roadsign 的 4 类),而cot_classes: 80是 base 类数量,两者不同;
  • use_cot: True会触发BBoxHead构建双分类头(见下文);
  • 学习率 0.001 相比常规 1x 配置的 0.01 明显下调,这是少样本训练防止过拟合的常见手法(对比 optimizer_1x.yml 中 base_lr 为 0.01、epoch 为 12,而本配置改为 30 epoch + 0.001)。

3.4 双分类头与 COT 损失的源码实现

在 bbox_head.py 中,当use_cot=True时会创建两个独立的线性分类层:

  • cot_bbox_score:输入维度in_channel,输出num_classes + 1(4 个 novel 类 + 背景),用于最终预测
  • bbox_score:输出cot_classes + 1(80 个 base 类 + 背景),用于学习关系矩阵定义的软标签

训练时(bbox_head.py),scores(novel 分类头)参与常规分类损失,而cot_scores(base 分类头)与关系矩阵cot_relation一起送入COTLoss

if self.cot_relation is not None: loss_cot = self.loss_cot(cot_scores, targets, self.cot_relation) loss.update(loss_cot)

COTLoss(cot_loss.py)本质是一个加权交叉熵:以关系矩阵行cot_relation[label]作为软目标,对 base 分类头的 logits 施加cot_scale缩放后计算-soft_target * log_softmax(scores),再乘以cot_lambda作为整体损失权重。推理阶段(cot=True)则直接用 base 分类头的输出得到预测。

四、路线二:Supervised Contrastive + PPYOLOE 少样本检测

4.1 核心思想

监督对比学习的思路是:不直接约束分类边界,而是约束特征空间中的距离——同类的正样本特征相互靠近,异类的负样本特征相互远离。在少样本条件下,分类头极易过拟合到个别样本,而对比学习学到的判别式特征空间泛化性更强。

4.2 配置文件逐段精读

配置文件 的核心内容:

_BASE_: [ '../datasets/coco_detection.yml', '../runtime.yml', './_base_/optimizer_80e.yml', './_base_/ppyoloe_plus_crn.yml', './_base_/ppyoloe_plus_reader.yml', ] pretrain_weights: https://bj.bcebos.com/v1/paddledet/models/pretrained/ppyoloe_crn_s_obj365_pretrained.pdparams depth_mult: 0.33 # s 规模的深度缩放系数 width_mult: 0.50 # s 规模的宽度缩放系数 epoch: 80 LearningRate: base_lr: 0.0001 # 少样本微调用极小学习率 schedulers: - !CosineDecay max_epochs: 96 - !LinearWarmup start_factor: 0. epochs: 5

模型结构段将检测头替换为带对比分支的PPYOLOEContrastHead

YOLOv3: backbone: CSPResNet neck: CustomCSPPAN yolo_head: PPYOLOEContrastHead post_process: ~ PPYOLOEContrastHead: fpn_strides: [32, 16, 8] grid_cell_scale: 5.0 grid_cell_offset: 0.5 static_assigner_epoch: 100 # 整个训练过程使用静态标签分配 use_varifocal_loss: True loss_weight: {class: 1.0, iou: 2.5, dfl: 0.5, contrast: 0.2} # 对比损失权重 0.2 static_assigner: name: ATSSAssigner topk: 9 assigner: name: TaskAlignedAssigner topk: 13 alpha: 1.0 beta: 6.0 contrast_loss: name: SupContrast temperature: 100 # 温度系数 sample_num: 2048 # 每 batch 采样上限(正样本不足时用负样本补齐) thresh: 0.75 # 只对得分高于该阈值的位置计算对比损失 nms: name: MultiClassNMS nms_top_k: 1000 keep_top_k: 300 score_threshold: 0.01 nms_threshold: 0.7

参数含义速查:

  • static_assigner_epoch: 100:大于总 epoch 数 80,意味着全程采用 ATSS 静态分配,避免动态分配在少样本下的不稳定;
  • temperature: 100:温度系数越大,对比损失对难分负样本的惩罚越平滑(与常规 0.1~1 的量级不同,这是针对检测密集位置特征调参的结果);
  • thresh: 0.75:过滤低置信度位置,防止大量背景特征干扰对比学习;
  • loss_weight['contrast']: 0.2:对比损失在总损失中的占比,主损失仍是分类(varifocal)、回归(IoU)与 DFL。

4.3 对比分支与 SupContrast 的源码实现

PPYOLOEContrastHead(ppyoloe_contrast_head.py)继承自PPYOLOEHead,额外并联了contrast_encoder:对 FPN 每个尺度的特征做Conv2D(in_c, 128, 3, padding=1)卷积,把特征压缩到128 维,展平后与分类/回归分支并行送入损失计算(ppyoloe_contrast_head.py)。

SupContrast(supcontrast.py)的实现要点:

  1. 依据标签将位置划分为正样本(labels < num_classes)与负样本/背景(labels == num_classes);
  2. 当正样本数不足sample_num时,从负样本中随机采样补齐到固定 batch 大小;
  3. 计算特征两两相似度features·featuresᵀ / temperature,并做行内减最大值以稳定 softmax;
  4. 构建标签掩码label_mask(同标签为 1、对角线置 0),计算每个样本相对同标签样本的平均 log-probability;
  5. scores > thresh过滤低置信度位置,最终取负平均作为对比损失。

总损失为分类、回归、DFL 与对比损失的加权和(ppyoloe_contrast_head.py)。

五、Model Zoo 与消融对比结果

原文档给出的官方结果如下(数据来自仓库文档,复现环境为每张 GPU 1 张图片):

Model Zoo

骨架网络网络类型每张GPU图片个数每类样本个数Box AP配置文件
ResNet50-vdFaster R-CNN11060.1faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign.yml
PPYOLOE_crn_sPPYOLOE13017.8ppyoloe_plus_crn_s_80e_contrast_pcb.yml

(权重下载链接见原文档 Model Zoo 表格。)

Co-tuning 消融(roadsign,10-shots)

骨架网络网络类型每张GPU图片个数每类样本个数CotuningBox AP
ResNet50-vdFaster R-CNN110False56.7
ResNet50-vdFaster R-CNN110True60.1

开启 Label Co-tuning 后 Box AP 从56.7 提升至 60.1(+3.4),验证了关系矩阵迁移的有效性。

对比学习消融(PCB,30-shots)

骨架网络网络类型每张GPU图片个数每类样本个数ContrastBox AP
PPYOLOE_crn_sPPYOLOE130False15.4
PPYOLOE_crn_sPPYOLOE130True17.8

加入监督对比损失后 Box AP 从15.4 提升至 17.8(+2.4)。PCB 缺陷检测的绝对精度不高,但对比学习带来的相对提升显著,说明其对少样本工业缺陷场景的判别力增强有效。

六、完整实操:训练、评估与推理

以下命令均在 PaddleDetection 仓库根目录执行(对应配置文件为 Co-tuning 路线,PPYOLOE 路线将-c参数替换为 ppyoloe_plus_crn_s_80e_contrast_pcb.yml 即可)。

6.1 训练

# -c 参数表示指定使用哪个配置文件 # --eval 参数表示边训练边评估,训练过程中会保存验证效果最佳的 checkpoint python tools/train.py -c configs/few-shot/faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign.yml --eval

启动后TrainerCot(trainer_cot.py)会先执行一次关系学习:打印computing relationship,遍历训练集统计关系矩阵并注入模型,之后才进入常规训练循环。由于snapshot_epoch: 5,每 5 个 epoch 会额外保存快照;验证效果最佳的模型会保存到weights字段指定的路径output/faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign/下(best_model)。

6.2 评估

# -c 参数表示指定使用哪个配置文件 # -o 参数表示指定配置文件中的全局变量(覆盖配置文件中的设置) python tools/eval.py -c configs/few-shot/faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign.yml \ -o weights=output/faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign/best_model

评估使用EvalDataset中的roadsign_valid.json,指标类型由配置中的metric: COCOmap_type: integral决定。

6.3 单图推理

# -c 参数表示指定使用哪个配置文件 # --infer_img 参数指定预测图像路径 python tools/infer.py -c configs/few-shot/faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign.yml \ --infer_img=demo/road554.png

TestDataset采用!ImageFolder结构,只需提供dataset_diranno_path即可对任意图片目录批量推理。

七、复现与自定义数据的关键注意事项

  1. 目录与标注格式:数据必须按 COCO 格式组织,且dataset_diranno_path与本地实际路径一致;roadsign 放在dataset/roadsign_coco,PCB 放在dataset/pcb。转换脚本可参考 tools/x2coco.py 与 dataset/voc/create_list.py 的标注处理思路。
  2. shots 采样:从全量数据中按类别随机采样相同数量样本生成训练集 JSON,如train_shots10.json;验证集使用完整标注,避免采样偏差影响评估。
  3. 预训练权重:Co-tuning 的relationship_learning强依赖预训练模型在基类上的判别能力,配置中的pretrain_weights指向 COCO 预训练的faster_rcnn_r50_vd_fpn_1x_coco与 Objects365 预训练的ppyoloe_crn_s_obj365_pretrained,首次运行需保证网络可下载或已本地化。
  4. 超参数基调:两条路线都大幅降低了学习率(0.001 / 0.0001)并延长训练 epoch(30 / 80),这是少样本训练"低学习率 + 长训练"的通用范式,可对比 optimizer_1x.yml 与 optimizer_80e.yml 的默认设置理解差异。
  5. 推理阶段行为差异:Co-tuning 路线推理时走 base 分类头(cot=True),因此评估与推理必须使用训练产出的模型权重,不能直接套用普通 Faster R-CNN 的推理流程。

八、参考文献

@article{you2020co, title={Co-tuning for transfer learning}, author={You, Kaichao and Kou, Zhi and Long, Mingsheng and Wang, Jianmin}, journal={Advances in Neural Information Processing Systems}, volume={33}, pages={17236--17246}, year={2020} } @article{khosla2020supervised, title={Supervised contrastive learning}, author={Khosla, Prannay and Teterwak, Piotr and Wang, Chen and Sarna, Aaron and Tian, Yonglong and Isola, Phillip and Maschinot, Aaron and Liu, Ce and Krishnan, Dilip}, journal={Advances in Neural Information Processing Systems}, volume={33}, pages={18661--18673}, year={2020} }

总结

PaddleDetection 的 few-shot 方案提供了两条互补的少样本检测实践路径:Label Co-tuning通过类别共现关系矩阵把 COCO 基类知识迁移给新类,在 roadsign 10-shots 任务上将 Box AP 从 56.7 提升到 60.1;Supervised Contrastive通过 128 维对比编码器与 SupContrast 损失增强特征判别力,在 PCB 30-shots 任务上将 Box AP 从 15.4 提升到 17.8。两者都遵循"大预训练模型 + 极小学习率 + 长训练周期 + 极少量标注"的少样本训练范式,且实现细节(关系矩阵计算、对比采样策略、损失权重)均可在ppdet/modeling/losses/ppdet/modeling/heads/ppdet/engine/trainer_cot.py中直接阅读验证,适合作为自定义少样本检测场景的改造起点。

  • 人工智能
  • 深度学习
  • 计算机视觉

【免费下载链接】PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleDetection
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询