基于 PaddleDetection 和 PPYOLOE 的 few-shot 小样本目标检测

1,141 阅读5分钟

本文利用 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图片个数每类样本个数ContrastBox AP
PPYOLOE_crn_sPPYOLOE130False15.4
PPYOLOE_crn_sPPYOLOE130True17.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个样本作为数据支撑

image.png

# -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

五、推理一张图片

image.png

# -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

总结

总的来说,实现过程并不复杂,但是各种文件和文件夹的路径一定要仔细写对,否则会出现类型标错的错误。另外,网络要稳定,这样才能保证下载的数据集、预训练模型完整一致。