本文利用 PaddleDetection 框架通过10个样本训练出路标检测模型。训练45轮左右,模型达到最优map:0.635,在小样本目标检测上取得较好的结果。
一. 项目背景
PaddleDetection团队提供了基于 PP-YOLOE+ 少样本学习的方案,引入了 Compare-Contrast 算法。在预训练模型的基础上,仅通过极少的标注数据,团队得到了较好的模型效果。
基于PaddleDetection v2.6中的PPYOLOE+网络,通过10个标注样本(10shots)的训练,本项目实现4类路标(crosswalk,speedlimit,stop,trafficlight)检测。
1.1 检测结果
1.2 小样本目标检测
目前,基于深度学习的目标检测模型需要大量的标注样本进行训练,但在实际场景当中,我们往往很难获取到相应规模的高质量标注样本。小样本目标检测技术是传统目标检测技术与小样本学习技术的融合,通过少量的标注样本学习,它具有较好泛化性能,对大规模标签数据的依赖很小。
二. Contrast算法介绍
监督对比学习(Supervised Contrastive Learning)是自监督对比学习(Self Supervised Contrastive Learning)的升级版,它设计了一个supervised contrastive loss 函数。这个函数让同类feature接近,异类feature远离,提高提取的feature质量,提升分类网络的性能。
2.1 Self Supervised Contrastive Learning
这种方法分别用来源相同的图片feature和来源不同的图片feature,跟图片的feature进行对比,然后让来源相同的图片feature越接近,来源不同的图片feature越远。
这种方式虽然能让模型学到不错的feature,但有一个不足是:它没有考虑到属于同类的不同图片之间feature的相关性。
例如下图所示的情况:左边的小狗和下面的小狗属于同类但是距离比较远,这显然不合理。
2.2 Supervised Contrastive Learning
基于以上问题,为了让同一类的图片feature距离接近,Google设计了一个supervised contrastive loss,将对比学习和监督学习相结合,达到更好的效果。下图所示同一小狗类相互接近,猫类和小狗类相互分开。
2.3 Supervised Contrastive loss
该loss函数表达的含义是:
1.对于任意图片i与图片属于同类的所有其它图片的feature,与图片i的feature的余弦距离的总和,越大越好
2.与图片i不属于同类的所有其它图片的feature,与图片i的feature的余弦距离的总和越小,越小越好 !
2.4 PP-YOLOE + Supervised Contrastive Learning
PP-YOLOE在Head损失权重上加入Supervised Contrastive loss函数,通过引入Contrast算法,提升了2.4 Box AP
| 骨架网络 | 网络类型 | 每张GPU图片个数 | 每类样本个数 | Contrast | Box AP |
|---|---|---|---|---|---|
| PPYOLOE_crn_s | PPYOLOE | 1 | 30 | False | 15.4 |
| PPYOLOE_crn_s | PPYOLOE | 1 | 30 | True | 17.8 |
三. 数据集介绍
数据集分为4类:crosswalk,speedlimit,stop,trafficlight,用于道路标志检测。本项目分别从原始数据集中每类选取10个标注框样本训练。左图为训练样本,categories表示类别数,annotations表示标注框个数即训练样本数,如下右图训练时一张图上有多个标注样本
三、安装PaddleDetection以及依赖
!git clone https://gitee.com/paddlepaddle/PaddleDetection.git
正克隆到 'PaddleDetection'...
remote: Enumerating objects: 257119, done.
remote: Counting objects: 100% (2116/2116), done.
remote: Compressing objects: 100% (1231/1231), done.
remote: Total 257119 (delta 1302), reused 1595 (delta 872), pack-reused 255003
接收对象中: 100% (257119/257119), 413.58 MiB | 17.77 MiB/s, 完成.
处理 delta 中: 100% (210330/210330), 完成.
检查连接... 完成。
cd PaddleDetection
# 安装依赖
!pip install -r requirements.txt --user
!python setup.py install --user
四、模型选型
PaddleDetection提供了多种模型进行选择,由于是few-shot(小样本)目标检测,因此我们找到configs文件下的few-shot文件夹,基于体验ppyoloe对小样本的检测效果,本次采用ppyoloe_plus_crn_s_80e_contrast_pcb.yml模型文件训练,包含以下几个配置文件。
4.1 主要更改部分
我们只需要修改数据集路径和部分参数即可,也就是把 snapshot_epoch :改为5,即每5轮对模型验证保存一次,将epoch(迭代轮数)改为60轮,TrainDataset、EvalDataset、TestDataset文件夹路径设对。
_BASE_:
[
"../datasets/coco_detection.yml",
"../runtime.yml",
"./_base_/optimizer_80e.yml",
"./_base_/ppyoloe_plus_crn.yml",
"./_base_/ppyoloe_plus_reader.yml",
]
log_iter: 100
snapshot_epoch: 5
weights: output/ppyoloe_plus_crn_s_80e_contrast_pcb/model_final
pretrain_weights: https://bj.bcebos.com/v1/paddledet/models/pretrained/ppyoloe_crn_s_obj365_pretrained.pdparams
depth_mult: 0.33
width_mult: 0.50
epoch: 60
LearningRate:
base_lr: 0.0001
schedulers:
- !CosineDecay
max_epochs: 96
- !LinearWarmup
start_factor: 0.
epochs: 5
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 }
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
thresh: 0.75
nms:
name: MultiClassNMS
nms_top_k: 1000
keep_top_k: 300
score_threshold: 0.01
nms_threshold: 0.7
num_classes: 4
metric: COCO
map_type: integral
TrainDataset: !COCODataSet
image_dir: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\JPEGImages
anno_path: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\train_shots10.json
dataset_dir: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\
data_fields: ["image", "gt_bbox", "gt_class", "is_crowd"]
EvalDataset: !COCODataSet
image_dir: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\JPEGImages
anno_path: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\roadsign_valid.json
dataset_dir: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\
TestDataset: !ImageFolder
anno_path: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\roadsign_valid.json
dataset_dir: C:\Users\xbk\Downloads\PaddleDetection-release-2.6\PaddleDetection-release-2.6\MyDataset\
4.2 开始训练
- 训练45轮左右模型达到最优map为0.635
- V100训练60轮时间大概只需要2分钟
- 继续训练模型map下降,模型不在收敛,这里应该是过拟合了,毕竟只有10个样本作为数据支撑
# -c 参数表示指定使用哪个配置文件
# --eval 参数表示边训练边评估,训练过程中会保存验证效果最佳的checkpoint
!python tools/train.py -c configs/few-shot/ppyoloe_plus_crn_s_80e_contrast_pcb.yml --amp --eval --use_vdl=True --vdl_log_dir=./visdrone/
4.3 训练可视化
4.4 模型评估
# -c 参数表示指定使用哪个配置文件
# -o 参数表示指定配置文件中的全局变量(覆盖配置文件中的设置)
!python tools/eval.py -c configs/few-shot/ppyoloe_plus_crn_s_80e_contrast_pcb.yml -o weights=output/ppyoloe_plus_crn_s_80e_contrast_pcb/best_model.pdparams
五、推理一张图片
# -c 参数表示指定使用哪个配置文件
# --infer_img 参数指定预测图像路径
# 推理后图片保存在output/road69.png
python tools/infer.py \
-c configs/few-shot/ppyoloe_plus_crn_s_80e_contrast_pcb.yml \
-o weights=output/ppyoloe_plus_crn_s_80e_contrast_pcb/best_model.pdparams \
--infer_img=./MyDataset/JPEGImages/road69.png
总结
总的来说,实现过程并不复杂,但是各种文件和文件夹的路径一定要仔细写对,否则会出现类型标错的错误。另外,网络要稳定,这样才能保证下载的数据集、预训练模型完整一致。