- 人工智能
- 深度学习
- 计算机视觉
【免费下载链接】PaddleDetection
Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.
本文围绕 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/目录给出了两种官方落地方案:
- 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)。
- 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 个类别:
crosswalk、speedlimit、stop、trafficlight。 - 下载方式:可从 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.json | pcb_cocoanno/train_shots30.json |
| 验证标注 | annotations/roadsign_valid.json | pcb_cocoanno/val.json |
| 图像目录 | images | images |
| 数据集根目录 | dataset/roadsign_coco | dataset/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):
- 加载 COCO 预训练权重(
self.load_weights(self.cfg.pretrain_weights)); - 冻结模型,在少样本训练集上执行
relationship_learning,统计每个 novel 类对 80 个 base 类的平均预测概率,得到一个num_classes_novel × 80的条件概率关系矩阵; - 通过
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-vd(variant: 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)的实现要点:
- 依据标签将位置划分为正样本(
labels < num_classes)与负样本/背景(labels == num_classes); - 当正样本数不足
sample_num时,从负样本中随机采样补齐到固定 batch 大小; - 计算特征两两相似度
features·featuresᵀ / temperature,并做行内减最大值以稳定 softmax; - 构建标签掩码
label_mask(同标签为 1、对角线置 0),计算每个样本相对同标签样本的平均 log-probability; - 用
scores > thresh过滤低置信度位置,最终取负平均作为对比损失。
总损失为分类、回归、DFL 与对比损失的加权和(ppyoloe_contrast_head.py)。
五、Model Zoo 与消融对比结果
原文档给出的官方结果如下(数据来自仓库文档,复现环境为每张 GPU 1 张图片):
Model Zoo
| 骨架网络 | 网络类型 | 每张GPU图片个数 | 每类样本个数 | Box AP | 配置文件 |
|---|---|---|---|---|---|
| ResNet50-vd | Faster R-CNN | 1 | 10 | 60.1 | faster_rcnn_r50_vd_fpn_1x_coco_cotuning_roadsign.yml |
| PPYOLOE_crn_s | PPYOLOE | 1 | 30 | 17.8 | ppyoloe_plus_crn_s_80e_contrast_pcb.yml |
(权重下载链接见原文档 Model Zoo 表格。)
Co-tuning 消融(roadsign,10-shots)
| 骨架网络 | 网络类型 | 每张GPU图片个数 | 每类样本个数 | Cotuning | Box AP |
|---|---|---|---|---|---|
| ResNet50-vd | Faster R-CNN | 1 | 10 | False | 56.7 |
| ResNet50-vd | Faster R-CNN | 1 | 10 | True | 60.1 |
开启 Label Co-tuning 后 Box AP 从56.7 提升至 60.1(+3.4),验证了关系矩阵迁移的有效性。
对比学习消融(PCB,30-shots)
| 骨架网络 | 网络类型 | 每张GPU图片个数 | 每类样本个数 | Contrast | Box AP |
|---|---|---|---|---|---|
| PPYOLOE_crn_s | PPYOLOE | 1 | 30 | False | 15.4 |
| PPYOLOE_crn_s | PPYOLOE | 1 | 30 | True | 17.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: COCO与map_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.pngTestDataset采用!ImageFolder结构,只需提供dataset_dir与anno_path即可对任意图片目录批量推理。
七、复现与自定义数据的关键注意事项
- 目录与标注格式:数据必须按 COCO 格式组织,且
dataset_dir、anno_path与本地实际路径一致;roadsign 放在dataset/roadsign_coco,PCB 放在dataset/pcb。转换脚本可参考 tools/x2coco.py 与 dataset/voc/create_list.py 的标注处理思路。 - shots 采样:从全量数据中按类别随机采样相同数量样本生成训练集 JSON,如
train_shots10.json;验证集使用完整标注,避免采样偏差影响评估。 - 预训练权重:Co-tuning 的
relationship_learning强依赖预训练模型在基类上的判别能力,配置中的pretrain_weights指向 COCO 预训练的faster_rcnn_r50_vd_fpn_1x_coco与 Objects365 预训练的ppyoloe_crn_s_obj365_pretrained,首次运行需保证网络可下载或已本地化。 - 超参数基调:两条路线都大幅降低了学习率(0.001 / 0.0001)并延长训练 epoch(30 / 80),这是少样本训练"低学习率 + 长训练"的通用范式,可对比 optimizer_1x.yml 与 optimizer_80e.yml 的默认设置理解差异。
- 推理阶段行为差异: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.
相关推荐
APNSwift高级功能:广播频道管理与多设备推送策略完整指南
APNSwift高级功能:广播频道管理与多设备推送策略完整指南 在iOS 18+系统中,APNSwift引入了强大的广播频道管理功能,为开发者提供了更加灵活和高
ConvNeXt在小样本目标检测中的应用:Few-shot Faster R-CNN
ConvNeXt在小样本目标检测中的应用:Few shot Faster R CNN 引言:小样本目标检测的挑战与解决方案 你是否还在为目标检测任务中标注数据匮
人工智能计算机视觉深度学习预训练微调少样本学习开源项目指南:oscarknagg/few-shot
少样本学习开源项目指南:oscarknagg/few shot 该项目位于 oscarknagg/few shot https://github.com/osc
少样本学习机器学习深度学习人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考