YOLO5face人脸检测模型论文和代码简析

  • YOLO5Face模型分析
    • 论文及源码下载
    • 论文创新点
    • 实验结果
    • 下载代码跑起来
    • 调整数据集
    • 训练完成之后检验结果
    • 一点点代码简析
      • 文件结构
      • data
      • models
        • common.py
      • utils
    • 一些问题
    • 参考文章

YOLO5Face论文发出以后,对YOLO5Face论文进行分析的文章较少,就想写一篇对YOLO5Face进行分析的文章,主要也是非常喜欢YOLO系列,博主也是刚刚入门人脸检测,写的就是一篇小白文,也第一次写文章,有不正确的地方希望大神们多多指正。

YOLO5Face模型分析

论文及源码下载

论文地址:https://arxiv.org/abs/2105.12931论文我们中国人写的,读起来还是挺顺的。
源码地址:https://github.com/deepcam-cn/yolov5-face
WiderFace地址:WIdeFace
Yolo5Face是深圳神目科技&LinkSprite Technologies(美国)在Yolov5模型基础上进行更新得到的人脸检测模型,在WiderFace上取得了SOTA。

论文创新点

正如论文名字的后半部分Why Reinventing a Face Detector?论文将人脸检测视为一般的目标检测任务,所以作者以现在比较热门的YOLOv5模型为基础,辅助以人脸特性,得到一个新的人脸检测器。
论文创新点:

  1. 在YOLOv5网络中添加五个人脸关键点回归,回归的损失函数用的是Wing loss。(类比MTCNN、RetinaFace)
    MTCNN中使用L2损失作为5个人脸关键点的回归损失,但是L2对小的误差并不敏感,为了克服这个问题,Wing-Loss出现了。


    可以看到Wing-loss是一个分段的复合损失函数,在训练初期误差较大时用L1损失,在训练后期误差相对小,用一个具有偏移量的对数函数。wing-loss的优点我也不能很好的论述清楚,感兴趣的可以去看这篇博客。https://blog.csdn.net/john_bh/article/details/106302026
    作者将五个人脸关键点回归损失加入到总的损失函数中去后,作者将这部分损失函数称为LossL并给这部分损失加上权重,加上YOLOv5本身的损失函数LossO,总的损失函数为Loss(s)。

    作者在配置文件里面写的:landmark: 0.005 # landmark loss gain,那应该这个权重就是0.005,具体的代码我还没有看到,看到以后如果不对再改。

  2. 用Stem模块替代网络中原有的Focus模块,提高了网络的泛化能力,降低了计算复杂度,同时性能也没有下降。
    Focus模块出来的时候,就有人说Focus模块比较鸡肋。可能是作者想改掉这部分又不想大改v5的整体模型,所以设计出一个相对更好的模块。
    Stem模块的图示中虽然都是用的CBS,但是看代码可以看出来第2个和第4个CBS是1x1卷积,第1个和第3个CBS是3x3,stride=2的卷积。配合yaml文件可以看到stem以后图像大小由604x640变成了160x160。

class StemBlock(nn.Module):def __init__(self, c1, c2, k=3, s=2, p=None, g=1, act=True):super(StemBlock, self).__init__()self.stem_1 = Conv(c1, c2, k, s, p, g, act) # 已经下采样一次了self.stem_2a = Conv(c2, c2 // 2, 1, 1, 0)self.stem_2b = Conv(c2 // 2, c2, 3, 2, 1)self.stem_2p = nn.MaxPool2d(kernel_size=2,stride=2,ceil_mode=True)self.stem_3 = Conv(c2 * 2, c2, 1, 1, 0)def forward(self, x):stem_1_out  = self.stem_1(x)stem_2a_out = self.stem_2a(stem_1_out)stem_2b_out = self.stem_2b(stem_2a_out)stem_2p_out = self.stem_2p(stem_1_out)out = self.stem_3(torch.cat((stem_2b_out,stem_2p_out),1))return out

  1. 对SPP模块进行更新,使用更小的kernel,使yolov5更适用于人脸检测并提高了检测精度。YOLOv5用的SPPkernel(5,9,13),YOLO5Face用的kernel(3,5,7)。
  2. 添加一个stride = 64的P6输出块,P6可以提高对大人脸的检测性能。(之前的人脸检测模型大多关注提高小人脸的检测性能,这里作者关注了大人脸的检测效果,提高大人脸的检测性能来提升模型整体的检测性能)。P6的特征图大小为10x10。
  3. 发现一些目标检测的数据增广方法并不适合用在人脸检测中,包括上下翻转和Mosaic数据增广。删除上下翻转可以提高模型性能。对小人脸进行Mosaic数据增广反而会降低模型性能,但是对中尺度和大尺度人脸进行Mosaic可以提高性能。随机裁剪有助于提高性能。
    这里主要还是COCO数据集和WiderFace数据集尺度有差异,WiderFace数据集小尺度数据相对较多。
  4. 基于ShuffleNetv2设计了两个轻量级模型,backbone和CSP网络不同,模型非常小,可以在嵌入式设备和移动设备达到SOTA。

依托YOLOv5可以调整网络宽度和深度的特点,作者可以方便的设计不同深度和宽度的网络模型,还用ShuffleNetv2设计了轻量级模型,也就是说从复杂到简单,从服务器到嵌入式或者移动设备,都有可以选择的模型。

实验结果


可以看到作者用的各种模块基本上都能提升map,忽略小人脸进行Mosaic数据增广Easy和Medium的map提升,但是hard的map下降了一些,模型整体的map提升。

对比实验主要还是和SCRFD进行对比,可以看到SCRFD的模型整体性能也很好,并且参数和计算量相对比YOLOv5l6小一些,但是YOLOv5l6的map稍微更高一些。
实验最后的一些图显示YOLO5Face的召回率相比还有一些提升空间,但是评估中没有TTA方法。(我觉得可以看看看图里面比YOLO5Face召回率高的论文,分析一下为什么别的论文里面召回率更高一些,大神分析出来了请告诉我好吗)。

下载代码跑起来

下载代码的地址就是上面的github地址,如果没有配环境就慢慢配环境,不过我觉得更好的方法是把yolov5的代码下载下来,主要里面有个requirements.txt,在pycharm里面直接就能自动下载了,太爽了,没有什么就下载什么,很快就能把环境配好,然后打开yolo5face的代码,用v5自动配好的环境,如果有不匹配的再改。

调整数据集

现在我用的数据集目录结构:widerface和widerfaceyolo都用到了。

调整数据集其实需要分两步,我是把两步的数据集都放到项目里面了:

  1. 将官网训练集标签替换成带人脸关键点的标签,并将验证所需要的wider_val.txt放到路径下面,将数据集放在项目下命名为widerface,用于验证模型检测精度。
  2. 将数据集调整成YOLO5face所需要的的目录格式,命名为widerfaceyolo,用于训练。

这两步生成的数据集我都上传到腾讯微云了,如果不想看具体怎么操作的,可以直接点击链接获取已经调整好的数据集,下载下来放到自己的文件夹就行了。

  1. WiderFace官网下载数据集链接已经放到最上面了。下载的地方是这样的:
    官网的数据集分三部分,Training和Validation是带标签的,test没有标签,可以暂时不下载。
  2. 下载人脸关键点的标签:因为官网的训练集中人脸是不带关键点,yolo5face需要用到人脸关键点,需要下载带人脸关键点的注释。官网上给的下载地址是goole drive的地址。更换标签就完成了初步转换,要把这个初步转换的数据集放到项目里面去,然后在网上找到wider_val.txt也放到下面。因为后面要做检测精度的验证,目录结构和我上面的图里面的结构保持一致。
  3. 调整目录结构:
    运行两个.py文件,就是官网上说的train2yolo.py和val2yolo.py。看名字也能看明白,这两个代码就是把数据集转成YOLO训练用的格式。
    先改train2yolo.py
    看名字应该看的懂的,save_path是转换之后的图片存到哪里,我是直接存到data下面了,注意文件夹一定要事先建好,不然会出错!第二行就是label.txt的位置,要根据label.txt找图片的位置,这就是为什么要调整好图片和labels.txt。
    再改val2yolo.py, root改到widerface层

    修改img和txt的输出路径,具体将图片和标签放不放在一起,看自己写的代码。

    调整完成的widerfaceyolo目录结构:

    和上面的总体结构一起看就能明白。
  4. 修改widerface.yaml文件,改为自己的数据集路径,记得把下载voc的代码注释掉,然后改成类似的格式就可以了。

训练完成之后检验结果

runs文件夹下面有对应的训练输出结果,可以看到召回率,检测精度,map。

  1. 验证检测准确度
    修改test_widerface.py文件,写入自己的训练好的权重路径

    修改验证集图片路径,指出wider_val.txt的路径,我这里就是用的widerface的路径,不是widerfaceyolo的路径,相应的改成自己的路径即可。

    这些步骤完成以后,运行test_widerface.py文件,运行完成以后,进入到widerface_evaluate文件夹下,点击widerface_txt可以看到生成的txt文件夹,和里面的txt文件,运行evalution.py即可得到检测准确度,跑不起来就先把对应的包先装好。
  2. 未完待续

一点点代码简析

文件结构

  • data
  • models
  • runs
  • torch2tensorrt # 没看懂,也没用过,懂的教教我
  • utils
  • weights # 下载预训练权重的脚本
  • widerface_evaluate # 验证检测精度的文件夹
  • detect_face.py # 只能检测一张图片
  • hubconf.py #PyTorch Hub相关代码,没啥大用
  • LICENSE # 版权文件
  • README.md # README markdown文件
  • result.jpg # 检测人脸的输出结果
  • test.py # 不是用的这个
  • test_widerface.py # 用的是这个
  • train.py # 模型训练脚本

data

  • images,一些检测用得到的图片。
  • scripts,下载其他数据集的一些脚本文件,基本没用。
  • widerface,初步转换数据集,用来生成widerfaceyolo数据集和验证训练模型的检测精度。
  • widerfaceyolo,训练用的数据集。
  • argoverse_hd.yaml/coco.yaml/coco.yaml/voc.yaml,下载自动驾驶/COCO/VOC训练数据集,配置一下类别数,没啥用。
  • hyp.finetune.yaml,yolov5根据voc数据集设置的超参
  • hyp.finetune.yaml,真正用到的超参文件!
  • retinaface2yolo.yaml,没用过,不太懂
  • train2yolo.py,生成训练用的train数据集
  • val2yolo.py,生成训练用的val数据集
  • widerface.yaml,训练用到的配置文件!

models

  • common.py 模型组件的相关代码
  • experimental.py 实验性质的代码,作者的一些想法,没有加到模型里去
  • export.py 导出网络模型的结构,会很长很长
  • yolo.py Detect以及Model构建代码,写出网络模型的整体构建过程
  • …yaml 大大小小的模型配置文件,突出一个灵活。

common.py

  • def autopad:为same卷积或same池化自动零填充,具体填充多少就是用这个函数计算的,保证卷积和池化后的特征图大小不变。
  • def channel_shuffle:通道打乱,ShuffleV2Block的前置模块。
  • def DWConv:深度可分离卷积,没用到。
  • class Conv:Conv2d+BN+SiLU,也可以不进行BN操作。
  • class StemBlock:替代Focus的模块,注意每个卷积核的大小和输出尺度。
  • class Bottleneck:两次卷积+一次残差连接
  • class BottleneckCSP:有多少个n就会有多少个Bottleneck,外层用的激活函数是Leaky_ReLU(0.1)。
    一个分支做一次CBS(1x1),再做n次Bottleneck,再进行一次Conv2d(1x1);
    另一个分支做一次Conv2d(1x1);
    两个分支concat+BN+leakyRelu+CBS(1x1)。
  • class C3:论文里面的C3的图是错误的,图里面的浅绿色方块是做一次Conv2d,实际上C3没有进行Conv2d,而是全部用的CBS,也可能是我没看到更深层的代码。
    一个分支做CBS,做n次Bottleneck;
    另一个分支做CBS;
    两个分支concat以后做一次CBS。
  • class ShuffleV2Block:轻量化网络结构模块ShuffleV2Block,我没有对这个部分深入理解,后续用到再更新。
  • class SPP:SPP模块。
  • class Focus:Focus模块。
  • class Contract:收缩模块:调整张量的大小,将宽高收缩到通道中。
  • class Expand:扩张模块,将特征图像素变大,例如:x(1,64,80,80) to x(1,16,160,160)。
  • class Concat:自定义concat模块,dimension就是维度值,说明沿着哪一个维度进行拼接。
  • class NMS :非极大值抑制模块。
  • class autoShape:自动调整shape值:因为输入图像可能来自不同的地方和格式,例如filename,URI,numpy等,autoShape模块就是将这些数据进行预处理和调整。
  • class Detections:看名字是做检测,但是好像没用到这个模块。
  • class Classify:二级分类模块,人脸检测没用到。

utils

  • aws/goolge_app_engine/wandb_logging/google_utils.py 谷歌云和自动驾驶相关的东西,没啥用
  • activation.py 激活函数代码
  • autoanchor.py 自动计算先验框代码
  • datasets.py yolov5用来生成训练用数据的代码,yolo5face没用这个
  • face_datasets.py dataset和dataloader定义代码,只能读图片
  • general.py 设置一些通用的代码,如日志文件,随机数,获取最后一个权重文件等等
  • loss.py 损失函数相关代码
  • metrics.py 模型验证度量,计算ap,p,r等
  • plotting utils.py 画图工具
  • torch_utils pytorch工具,初始化随机数种子,git描述等

一些问题

  1. 有问题可以先去github官网源码那里看看,想在CSDN找答案实在是太难了。
  2. 官网的yolo5-face.pt预训练权重加入到模型中进行训练是会报错的,用yolov5官方的5.0的权重作为预训练权重就可以了。
  3. 验证检测精度的wider_val.txt文件链接:wider_val.txt

最后

参考文章

https://zhuanlan.zhihu.com/p/375966269
https://blog.csdn.net/john_bh/article/details/106302026

YOLOv5Face YOLO5Face人脸检测论文及代码简析相关推荐

  1. OpenFace库(Tadas Baltrusaitis)中基于Haar Cascade Classifiers进行人脸检测的测试代码

    Tadas Baltrusaitis的OpenFace是一个开源的面部行为分析工具,它的源码可以从 https://github.com/TadasBaltrusaitis/OpenFace 下载.O ...

  2. Dlib库中实现正脸人脸检测的测试代码

    Dlib库中提供了正脸人脸检测的接口,这里参考dlib/examples/face_detection_ex.cpp中的代码,通过调用Dlib中的接口,实现正脸人脸检测的测试代码,测试代码如下: #i ...

  3. OpenCV与图像处理学习十七——OpenCV人脸检测(含代码)

    OpenCV与图像处理学习十七--OpenCV人脸检测(含代码) 一.人脸识别概要 1.1 人脸检测 1.2 人脸对齐(Face Alignment) 1.3 人脸特征提取(Face Feature ...

  4. [2021-CVPR] Jigsaw Clustering for Unsupervised Visual Representation Learning 论文简析及关键代码简析

    [2021-CVPR] Jigsaw Clustering for Unsupervised Visual Representation Learning 论文简析及关键代码简析 论文:https:/ ...

  5. 人脸检测数据集评价代码FDDB evaluation运行方法

    人脸检测数据集评价代码运行方法: FDDB evaluation安装及使用 基本参考http://blog.csdn.net/u011783201/article/details/52119313,但 ...

  6. 图像显著性检测论文及代码汇总

    近年来,图像显著性检测研究引起了大量的学者关注.为了方便学术研究,本博客汇总了近几年比较经典的图像显著性检测论文及代码,同时也收集了一些显著性检测相关的Toolbox.Benchmark和大牛的主页等 ...

  7. 关于php车服务论文,「PHP」行车服务app后端代码简析

    之前发布了一篇关于我的 行车服务 app iOS 端代码简析的文章:文章地址. 此篇是对这个项目后端 iOS端代码地址: iOS代码,PHP代码.如果你觉得有帮助,希望能够点个 Star ,感谢~ 笔 ...

  8. Learning with Noisy Correspondence for Cross-modal Matching 文献翻译 代码简析

    Learning with Noisy Correspondence for Cross-modal Matching 基于噪声对应的跨模态匹配学习 Learning with Noisy Corre ...

  9. 智能机器人编程游戏robocode的运行代码简析

    智能机器人编程游戏robocode的运行代码简析 金庆 2007.6.1 阅读robocode1.3的源代码,查看运行的原理. (转载请注明来源于 金庆的专栏) 主线程Battle.run() --- ...

最新文章

  1. 另类L2TP Tunnel
  2. Assembly of long, error-prone reads using repeat graphs 使用重复图组装长且容易出错的读操作
  3. Node.js webpack中url-loader处理图片路径
  4. 利用计算机提高数学课堂教学,计算机技术在数学课堂教学中的应用微探
  5. Hibernate----Hibernate小配置
  6. Trouble Sort CodeForces - 1365B(思维)
  7. 阿里高级技术专家至简: Service Mesh 在超大规模场景下的落地挑战
  8. go标准库:time
  9. 20130418代码
  10. python批处理代码_Python文件夹批处理操作代码实例
  11. sql去某几个字段重复的记录
  12. 8个我使用过的免费Vue图标库
  13. 使用Python快速获取哥白尼数据开放访问中心购物车里的数据下载链接
  14. arm linux vi键盘错乱,Ubuntu Server 18.04安装后vi命令解决键盘错乱方法和wifi连接之后不能上网...
  15. 使用PS快速制作App logo图
  16. python 调用Google Translate API进行翻译
  17. 她二本科毕业,拿到阿里年薪40万offer!经验都记录在这几个公众号日记中
  18. MapGuide的历史
  19. 树莓派的mjpeg-streamer实现简单的监控功能
  20. 代码不朽笔记: 编写简单的代码单元

热门文章

  1. 叶问短线绝招之拨云见日
  2. CESIUM学习—— viewer.trackedEntity小坑坑
  3. 「AI白身境」一文览尽计算机视觉研究方向
  4. 关于用盐去黑头的亲身经历~ - 生活至上,美容至尚!
  5. 使用Goods类创建十个商品 第四章 面向对象(上)课堂作业2
  6. 在PRESS.one这片蛮荒沃土上,我们都是拓荒者
  7. DTX-1800还需要校准吗?
  8. 下载单词英语单词_单词如何塑造体验
  9. textpad设置Java版本_如何在textpad中保存设置以显示行号?
  10. python时分秒_python时间时分秒与秒数的互相转换