![11554b4a267cd54440e6e8ae38784125.png](https://i-blog.csdnimg.cn/blog_migrate/788a21c46fa6f9eba0702a578d2b0ebc.jpeg)
1. 数据来源
AIZOO 数据集:https://github.com/AIZOOTech/FaceMaskDetection
RMFD 数据集 https://github.com/X-zhangyang/Real-World-Masked-Face-Dataset
自定义数据集:爬虫收集类似手捂脸等挡住脸的图片,并进行标注。
2. 运行环境
Windows10 + CUDA10.1 + OpenCV3.4.10 + python3.7 + VisualStudio2019
3. YoloV4简介
![3ceb2795506b36d4aebd82b0ce200e4b.png](https://i-blog.csdnimg.cn/blog_migrate/3d686d6acb4220ac86f10a61a731d20b.jpeg)
3.1 主要构成及改进
![06799e71a914384b86ab787f2148fcfb.png](https://i-blog.csdnimg.cn/blog_migrate/b346a49f8df76e2b9ccbfeade28d0220.jpeg)
1) 输入端:Mosaic 数据增强,cmBN,SAT 自对抗训练。
Mosaic 数据增强
- Mosaic 采用 4 张图片,以 随机缩放、随机裁剪、随机排布 的方式进行拼接。
- 丰富了数据集:随机使用 4 张图片,随机缩放(增加了很多小目标),随机分布进行拼接。
- 减少 GPU:一个 GPU 就可以达到比较好的效果。
![78a0e34b3df9525773aff411d38eeda6.png](https://i-blog.csdnimg.cn/blog_migrate/76570bb4a8f86dba002028228de70f6b.jpeg)
2)BackBone:CSPDarknet53,Mish激活函数,Dropblock
CSPDarknet53:
- CSPNet 的网络结构(分两路,然后concate合一),每个CSP模块前面的卷积核大小都是 3 × 3,可以起到下采样的作用,经过5次CSP后:608 -> 304 -> 152 -> 76 -> 38 -> 19
- 增强 CNN 的学习能力,在轻量化的同时保持准确性。
- 降低计算瓶颈,降低内存成本。
![67de61f812cd03bd1c2c7b56e4e6e258.png](https://i-blog.csdnimg.cn/blog_migrate/c76576774771f6f339307b9bdb1e91cb.jpeg)
Mish激活函数:主干网络中使用Mish激活函数
![e6ab146694b57da435ad5763e449f481.png](https://i-blog.csdnimg.cn/blog_migrate/714b81e9c6c9cdc4c7be0bcb95551b46.png)
Dropblock:缓解过拟合的一种正则化方式
-
- 由于卷积层对 dropout 的那种随机丢弃信息的方式并不敏感,即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息
- 因此,dropblock 进行的是整个局部区域的丢弃
![c49d3705a85971eacc79b68c8d784dd5.png](https://i-blog.csdnimg.cn/blog_migrate/6030789d26097e22f8518b51e3ca53e4.png)
3) Neck:SPP模块,FPN + PAN 结构
SPP:采用 1 × 1,5 × 5,9 × 9,13 × 13的最大池方式,进行多尺度融合,对任意尺寸的输入产生固定大小的输出
PAN:Path Aggregation Network for Instance Segmentation(以FPN为基准)
-
- PAN原理:a(FPN 结构) b(自下而上的路径扩充)
![c50ddaf68d8bd68bcf36ac91c26758f5.png](https://i-blog.csdnimg.cn/blog_migrate/1c10412ed08cfc4e1f288f75c273f4a9.png)
-
- 注意点:原PAN论文中是 add,yolov4论文中是 concate
![d8fc73fb95b0e4ed9f6053e6b155750c.png](https://i-blog.csdnimg.cn/blog_migrate/828489a88fe45532bb1db26bd3a48ecd.png)
4) Prediction:训练时的损失函数 CIOU_Loss,预测框筛选的nms变为 DIOU_nms
CIOU Loss
- 考虑:重叠面积、中心点距离、长宽比
- 在 DIOU 的基础上,增加一个影响因子,将预测框和目标框的长宽比都考虑进去
DIOU_nms
- 在重叠目标的检测中,DIOU_nms 的效果优于传统的 nms。
3.2 五个基本组件
CBM:Conv + BN + Mish,用于主干网络 BackBone
CBL:Conv + BN + Leaky relu
Res unit:Resnet 网络中的残差结构,可以构建更深的网络。
![f7c851143bbb63c997148862a7f8a1bd.png](https://i-blog.csdnimg.cn/blog_migrate/1e27d8962ad2a549d1bda55e47b540ac.png)
CSPX:每个CSP模块前面的卷积核大小都是 3 × 3,可以起到下采样的作用。
![91e6a180bc002494abbd5e884ae03868.png](https://i-blog.csdnimg.cn/blog_migrate/c510ee39712377ea8b008f1d21d0a434.png)
SPP:采用 1 × 1,5 × 5,9 × 9,13 × 13的最大池处理。
![a4a7c78dbd7350082bb541ac325a229b.png](https://i-blog.csdnimg.cn/blog_migrate/ca7a4c6153b5274313a26c355412dfab.png)
4. 数据集处理
对数据集进行清洗筛选后,共有 110200张图片:AIZOO 数据集(8000 张),RMFD 数据集( 3000 张),自定义数据集(200张)。
使用 labelImg 工具对所有图片进行标注(mask 和 nomask),生成xml文件。
![235fd51e8724d64f4923d0a4ed68eaa4.png](https://i-blog.csdnimg.cn/blog_migrate/5757e078106b77d447d4518281bfcbc2.jpeg)
5. 编译和配置YoloV4
1)环境要求:
- Visual Studio 2015/2017/2019
- CUDA> = 10.0
- cuDNN> = 7.0
- OpenCV> = 2.4
2)编译:
- 使用 Git 获取代码
git clone https://github.com/AlexeyAB/darknet.git
cd darknet
- 打开Powershell终端并启动
.build.ps1
3)检查是否编译成功:
- 下载yolov4.weights:https://drive.google.com/open?id=1cewMfusmPjYWbrnuJRuKhPMwRe_b9PaT
- 命令行测试:
darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights data/dog.jpg
- 结果:
![91f61d3e436cec55ffba7ef0c5a1537c.png](https://i-blog.csdnimg.cn/blog_migrate/6eeb6437434aa5ed69707b81aa3586e8.jpeg)
6. 训练模型
6.1 数据准备
创建 VOCdevkit/VOC2007/Annotations
,存放 xml 文件。
创建 VOCdevkit/VOC2007/JPEImages
,存放图片文件。
1)训练所需的数据文件:
VOCdevkit/VOC2007/JPEImages
里的图片。- 训练集和测试集(txt文件:每张图片的路径),存放在主目录中。
- yolo格式的标准文件(txt文件:类别,中心点坐标x,y,w,h),存放在
VOCdevkit/VOC2007/labels
中。
2)编写 python 脚本自动生成上述文件:
- 生成 mask_train.txt 和 mask_test.txt 作为训练集(80%)和验证集(20%)。
![00c56c28f613882b96fdf43514a9b8c8.png](https://i-blog.csdnimg.cn/blog_migrate/76289918ec486ede4ca2104edfb436fa.png)
- 生成 yolo格式的标准文件,由 Annotations 的 xml 标注文件转换来的。
![40c1316091ec99e2b340e60edc5dcf1e.png](https://i-blog.csdnimg.cn/blog_migrate/d59346de507f97ccffb70a0d0d8bd134.png)
6.2 配置
1)cfg文件配置:复制 yolov4-custom.cfg
到 yolo-mask.cfg
,创建自己的模型配置文件。
模型配置
-
- 更改所有
classes=80
-->classes=2
(根据需要预测的分类数设置) - 更改所有
[filters=255]
-->[fiters=21]
(filter=(classes + 5) × 3)
- 更改所有
训练参数配置
-
- 修改
batch=64
,subdivisions=16
(根据电脑配置而定) - 设置图片大小:
width=416
和height=416
(任何32的倍数均可,由于训练是有GPU内存溢出问题,我选了比较小的数,值越高精度越高) - 设置最大的训练次数:
max_batches=10000
(标准为 classes × 2000,想试看看训练10000次会出现什么效果) - 设置到达训练次数时,学习率衰减:
steps=8000, 9000
(这里是 max_batches 的 80% 和 90%)
- 修改
2)mask.names:data
目录中创建 mask.names
nomask
mask
3)mask.data:data
目录中创建 mask.data
classes= 2
train = mask_train.txt
valid = mask_test.txt
names = data/mask.names
backup = backup/ # 训练保存权重的位置
4)下载预训练的权重
https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137
5)开始训练
darknet.exe detector train data/mask.data cfg/yolo-mask.cfg yolov4.conv.137
如需查看训练效果可以使用 mAP 计算进行训练。
darknet.exe detector train data/mask.data cfg/yolo-mask.cfg yolov4.conv.137 -map
迭代大概了4000步的效果图,mAP已经达到了91%(单个CPU:NVIDIA GeForce GTX 1050 Ti,训练了快24个小时)。
![f8a462d7ef19cef2e3447639f241a206.png](https://i-blog.csdnimg.cn/blog_migrate/b6e671aa7148859d9a246a5bc0be4b65.jpeg)
loss 值已经趋向平稳,再迭代下去应该也得不到多大的提升了,最终还是训练迭代了10000次(训练了55个小时),结果提升了1%的mAP。
![42e0202e25b669b677873bbfee9fa921.png](https://i-blog.csdnimg.cn/blog_migrate/48a471d6a702abdb9bbe0cfde4574955.jpeg)
7. 测试模型
7.1 创建测试用的 cfg 文件
- 复制
yolov4-mask.cfg
到yolo-mask-test.cfg
,并修改batch=1
,subdivisions=1
- 说明:虽然测试时直接用
yolov4-mask.cfg
程序也会自动修改batch
和subdivisions
的值,但为了保险起见,进行了手动修改。
7.2 测试
1)图片测试
darknet.exe detector test data/mask.data cfg/yolov4-mask-test.cfg backupyolov4-mask_best.weights testfiles/test.jpg
能够正确识别有除口罩外的遮挡物,如花、手机、手捂脸等。
![c238fbd64be00640cd351b2e03317358.png](https://i-blog.csdnimg.cn/blog_migrate/9bb8b5e6c9f0d2108829f77a2a7e7749.jpeg)
能够正确识别有无佩戴口罩。
![442f9ae252eb28f7e6f34e437a06baa9.png](https://i-blog.csdnimg.cn/blog_migrate/b616e2abfb06fc11f8657b6536939a0e.jpeg)
2)视频测试
darknet.exe detector demo data/mask.data cfg/yolov4-mask-test.cfg backupyolov4-mask_best.weights testfiles/test.mp4
在人数多的时候也能正确识别。
知乎视频www.zhihu.com8. 评估模型
统计 mAP@IoU=0.50:
darknet.exe detector map data/mask.data cfg/yolov4-mask-test.cfg backupyolov4-mask_best.weights
![731e92fbf6160e17cce633147ccff184.png](https://i-blog.csdnimg.cn/blog_migrate/4e6914c3a2d5f23bebe1e8e7d56149f6.jpeg)
mAP@0.50 = 92.23%,得到了不错的效果。
统计 mAP@IoU=0.75:
darknet.exe detector map data/mask.data cfg/yolov4-mask-test.cfg backupyolov4-mask_best.weights -iou_thresh 0.75
![c701f2fcfb92812acccfde1dfeadb34b.png](https://i-blog.csdnimg.cn/blog_migrate/b5113b617776208509c7117d23f40c7a.jpeg)
9. 改进模型
9.1 先验框的聚类分析
默认的 anchors 为:
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
使用 K-means++ 聚类 获得自己数据集的先验框大小。
darknet.exe detector calc_anchors data/mask.data -num_of_clusters 9 -width 416 -height 416
结果存放在 anchors.txt 文件中:
anchors = 7, 13, 18, 29, 35, 49, 65, 61, 49, 101, 96, 102, 96, 168, 157, 197, 223, 270
修改 cfg/yolo-mask.cfg 文件中的先验框大小。
重新训练和测试,查看性能是否有所提升。
9.2 改变 NMS 方法
传统的NMS方法:Greedynms,YoloV4 的NMS方法:Diounms。
本文先采用传统的 Greedynms 进行训练,后用 Diounms 进行训练,看性能是否能得到提升。
修改 cfg/yolo-mask.cfg 文件中的 nms_kind 值:
nms_kind = diounms
重新训练和测试,查看性能是否有所提升。
10. 不足与展望
10.1 不足
本文在理想状态下(假设口罩佩戴规范)对有无戴口罩进行检测,并未考虑口罩佩戴不规范的情况:如佩戴口罩是否完全包住鼻子、是否戴反或是上下颠倒等情况。
![7035ecbb5180abdc598bff050454d352.png](https://i-blog.csdnimg.cn/blog_migrate/f5f742b30e310714744fa4310a9e271a.jpeg)
错误检测人脸:将其他类似人脸的情况错误检测为人脸。
![d7ef8e35c640d4590a9bbb583750e29c.png](https://i-blog.csdnimg.cn/blog_migrate/6b3854c3a2a9d56525398a1fef6f8c6c.jpeg)
10.2 展望
可针对口罩佩戴不规范的情况,增加这一类型的数据集,分为三类结果(mask,badmask, nomask),重新修改模型进行训练。
针对错误检测人脸的情况,检查检测错误的图片,统计分类错误率高的类型,增加该类型场景的数据,对模型进行微调或重新进行训练。
参考资料
YOLOV4论文:https://arxiv.org/abs/2004.10934
Mish激活函数:https://arxiv.org/abs/1908.08681
Dropblock:https://arxiv.org/abs/1810.12890
FPN:https://arxiv.org/abs/1612.03144
PAN:https://arxiv.org/abs/11803.01534
SSP:https://arxiv.org/abs/1406.4729