还是搬了个别人做的呀

要求

在工厂、工地等场所,由于可能存在易燃易爆物,都严禁抽烟,在办公区域、后厨、园区等一些公共场所,也禁止抽烟。鉴于此需求,本赛题希望开发者能够基于工厂、后厨、办公室、园区等多个场景,开发出算法以检测是否有人在进行抽烟。

难点

香烟检测属于小目标物体,检测存在难度。

抽烟和打电话/摸耳朵等动作很容易混淆,笔者之前参加过一个打手机识别的比赛,该比赛中很多打手机的负样本就是拿抽烟做的,因为两个行为在摄像头底下很容易被误解,因此需要解决这两个行为的区别,不能仅用目标检测来解决。

题目需要输出:

头部框位置并区分正脸 侧脸  背脸

人脸 五个关键点:左眼  右眼  鼻子  左嘴角 右嘴角

手部框位置

抽烟框位置

烟头框位置

烟头线位置

由于涉及隐私保护和数据保护, 编码环境里面的人脸都被打了马赛克,如下图:

吸烟识别方案_人脸检测

这样造成脸部几个关键点和烟头的关键点信息都被抹去了, 靠样本数据无法在编程环境中训练一个简单关键点模型来调试;。

这样会有些麻烦, 无法在编程环境中调试输出 ,除非你之前就在极市平台上面做过打榜的题目,熟悉题目要求,如果是像笔者一样第一次做这个题目的话,需要很多时间去摸索,我花了很多积分和时间在这上面做调试。

因此也推荐大家没事的时候也可以先到极市的打榜频道锻炼一下,据笔者观察他们的很多比赛题目都是从榜单这里选的,事先熟悉一下极市的数据和要求,这样在比赛开始后可以比别人快很多进入主题。

数据分析

比赛数据集共包含31065张图像 数据均为JPG格式,标注类型为VOC+关键点,标注文件格式为XML,标签类型bounding box、polyline、point。

训练集分辨率:

'38402160': 14189'19201080': 8558'19201440': 3663'1280720': 2084'25601440': 412'1512848': 289'2560*1920': 109

做了下标注的统计,基本还是均衡的,符合实际的情况

吸烟识别方案_数据_02

 模型选择

选择一个好的算法模型,往往要从以下几点入手:

1、更快更强的Backbone架构;

2、更有效的Neck特征集成方法;

3、更准确的检测Head方法

思路

通常看到题目的对脸部几个关键点的要求很容易想到这赛道需要一个脸部关键点检测的算法来实现。

因此直觉就是选择了retinaface 这个算法可以检测人脸并输出5个关键点:刚好是赛题要求的几个点。

最初的baseline 的流程如下图所示:

吸烟识别方案_目标检测_03

利用两个模型合并推理来实现  ,一开始我就是这样实现,但是在这个比赛上速度跟不上。

出于推理性能考虑,加上笔者对于yolov5的网络结构比较熟悉,笔者选择了另外一个模型yolo5face(其实retinaface也能改)

yolov5face是深圳神目科技推出的人脸检测模型。  

论文地址:https://arxiv.org/abs/2105.12931

吸烟识别方案_人脸检测_04

通过上图的表格我们可以看到相对于RetinaFace 和SCRFD ,Yolo5-Face在精度和计算量都要好一些.

Yolo5face算法把人脸检测视为一般的目标检测任务,以现在比较热门的YOLOv5模型为基础,辅助以人脸特性,得到一个新的人脸检测器。

主要特点是:

  1. 在YOLOv5网络中添加五个人脸关键点回归,回归的损失函数用的是Wing loss。(类比MTCNN、RetinaFace) MTCNN中使用L2损失作为5个人脸关键点的回归损失,但是L2对小的误差并不敏感,为了克服这个问题,Wing-Loss出现了;
  2. 用Stem模块替代网络中原有的Focus模块,提高了网络的泛化能力,降低了计算复杂度,同时性能也没有下降;
  3. 对SPP模块进行更新,使用更小的kernel,使yolov5更适用于人脸检测并提高了检测精度;
  4. 添加一个stride = 64的P6输出块,P6可以提高对大人脸的检测性能;
  5. 发现一些目标检测的数据增广方法并不适合用在人脸检测中,包括上下翻转和Mosaic数据增广;
  6. 基于ShuffleNetv2设计了两个轻量级模型,backbone和CSP网络不同,模型非常小,可以在嵌入式设备和移动设备达到SOTA。

该算法的网络架构图如下所示

吸烟识别方案_人脸检测_05

本方案最终的方案是修改yolo5face为从单一的人脸检测修改为多类别的目标检测(关键点)算法 ;

训练和推理

训练过程

首先是数据处理,需要将训练数据处理成yolov5所需要的格式;yolov5工程化做的比较好,各类比赛中使用的非常多,这里就不介绍这个VOC格式到yolov5格式转换,如果有疑问可以其他人的比赛总结或者极市打榜经验文章中均有提到;值得注意几点是:

1.需要处理人脸关键点坐标,注意输入输出的关键点顺序;

2.在本方案中,烟头的两个端点也作为关键点输入训练;

3.所有的关键点数据都要归一化处理;

4.增加对样本数据增强的处理: 比如高斯模糊, 随机裁剪等等;

本方案由于改变了模型backbone ,并没有使用任何预训练的权重,而是基于比赛数据从头训练的;

推理过程

1.为了加快速度, 需要使用TensorRT来推理模型,因此需要将训练好的模型转成tensorrt engine格式部署;

2.将图像resize成合适的大小,输入推理网络,这个需要做很多测试;

3.推理的前处理后处理尽量在放到GPU上面执行,以加快推理速度;

工程部分总结

1.选择一个能走通的方案作为base line ,在此基础上面迭代改进算法和流程;

2.修改算法backbone为你自己的方案,并且尝试不同的方案组合,以提高精度;

3.改变图像推理的尺寸大小,找到一个合适的大小作为输入;

4.将模型转到合适的部署方案,比如TensorRT/onnxruntime等;

5.将代码精简,理顺流程,减少不必要的处理过程;

6.不断调试,直到选择到合适的超参数;

最后也尝试了转换openvino的测试,在CPU上面也能获得较好的速度,如果没有GPU的情况可以使用openvino来推理;