专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
程序员小灰  ·  清华大学《DeepSeek学习手册》(全5册) ·  昨天  
OSC开源社区  ·  升级到Svelte ... ·  3 天前  
程序猿  ·  “我真的受够了Ubuntu!” ·  2 天前  
程序员的那些事  ·  惊!小偷“零元购”后竟向 DeepSeek ... ·  2 天前  
51好读  ›  专栏  ›  SegmentFault思否

AIZOO开源人脸口罩检测数据+模型+代码+在线网页体验,通通都开源了

SegmentFault思否  · 公众号  · 程序员  · 2020-02-21 11:44

正文

本文作者:元峰
互联网 + AI 领域的创业者



近一个月来,新冠肺炎疫情牵动着全国人民的心,一线医护工作者在最前线抗击疫情的同时,我们也可以看到很多科技行业和人工智能领域的从业者,也在贡献着他们的力量。

近些天来,旷视、商汤、海康、百度都多家科技公司研发出了 带有AI人脸检测算法的红外测温、口罩佩戴检测等设备;

依图、阿里也研发出了 通过深度学习来自动诊断新冠肺炎的医疗算法。 可以说,各行各业的从业者都在为早日战胜这场疫情贡献着力量。

作为互联网 + AI 领域的创业团队,我们决定开源我们整理的口罩检测数据集和训练好的模型 (提供 keras 版本和 caffe 版本) 、代码,另外,我们也将模型转为了 TensorFlow.js 支持的格式,部署到了我们的网站 aizoo.com 上,方便大家在浏览器里面体验。

在文章末尾,有我们开源的所有资料的链接,如果您不想看文章内容,可以直接滑到文章底部查看资料链接。

首先,让我们先看一个效果视频。


视频中红色是未戴口罩,绿色是佩戴了口罩。可以看到,如果是双手捂住了嘴巴多半部分,模型会认为是未戴口罩 (关于这一点,下文会有讨论)

下面,我们将从模型结构、数据和 TensorFlow.js 部署三大方面介绍本项目。好了,废话不多说了,Let's go~





一. 模型介绍

在深度学习时代之前,人脸检测一般采用传统的、基于手动设计特征的方法,其中最知名的莫过于 Viola-Jones 算法,至今部分手机和数码相机内置的人脸检测算法,仍旧采用 Viola-Jones 算法。

然而,随着深度学习技术的蓬勃发展,基于深度学习的人脸检测算法逐步取代了传统的计算机视觉算法。

在人脸检测最常用的数据集 —— WIDER Face 数据集的评估结果上来看,使用深度学习的模型在准确率和召回率上极大的超过了传统算法。下图的青线是 Viola-Jones 的 Precision-Recall 图。


下图是众多基于深度学习的人脸检测算法的性能评估 PR 曲线。可以看到基于深度学习的人脸检测算法的性能,大幅超过了 VJ 算法 (曲线越靠右越好)

近两年来,人脸检测算法在 WIDER Face 的简单测试集 (easy 部分) 上可以达到 95% 召回率下,准确率也高达 90%,作为对比,VJ 算法在 40% 召回率下,准确率只有 75% 左右。


其实,基于深度学习的人脸检测算法,多数都是基于深度学习目标检测算法进行的改进,或者说是把通用的目标检测模型,为适应人脸检测任务而进行的特定配置。

而众多的目标检测模型 (Faster RCNN、SSD、YOLO) 中,人脸检测算法最常用的是 SSD 算法,例如知名的 SSH 模型、S3FD 模型、RetinaFace 算法,都是受 SSD 算法的启发,或者基于 SSD 进行的任务定制化改进, 例如将定位层提到更靠前的位置,Anchor 大小调整、Anchor 标签分配规则的调整,在 SSD 基础上加入 FPN 等。

在笔者个人看来,SSD 是最优雅、简洁的目标检测模型 ,因此,我们实现的人脸口罩检测模型,也是采用 SSD 的思想,限于篇幅原因,本文不会详细介绍 SSD 的原理,只会进行简单的模型配置介绍。

在本项目中,我们使用的是 SSD 架构的人脸检测算法,相比于普通的人脸检测模型只有人脸一个类别,而人脸口罩检测,只不过是增加了一个类别,变成戴口罩人脸和不戴口罩的人脸两个类别而已。

我们开源的模型是一个非常小的模型,输入是 260x260 大小,主干网络只有 8 层,有五个定位和分类层,一共只有 28 个卷积层。而每个卷积层的通道数,是 32、64、128 这三种,所有这个模型总的参数量只有 101.5 万个参数。下图是网络的结构图。

其中,上面八个卷积层是主干网络,也就是特征提取层,下面 20 层是定位和分类层(注意,为了方便显示,我们没有画出 BN 层)。

训练目标检测模型,最重要的合理的设置 anchor 的大小和宽高比,笔者个人在做项目时,一般会统计数据集的目标物体的宽高比和大小来设置 anchor 的大小和宽高比。例如,在我们标注的口罩人脸数据集上,我们读取了所有人脸的标注信息,并计算每个人脸高度与宽度的比值,统计得到高度与宽比的分布直方图,如下:
因为人脸的一般是长方形的,而很多图片是比较宽的,例如 16:9 的图片,人脸的宽度和高度归一化后,有很多图片的高度是宽度的 2 倍甚至更大。从上图也可以看出,归一化后的人脸高宽比集中在 1~2.5 之间。所以,根据数据的分布,我们将五个定位层的 anchor 的宽高比统一设置为 1,0.62,0.42。 (转换为高宽比,也就是约1,1.6:1,2.4: 1)

五个定位层的配置信息如下表所示:

卷基层
特征图大小
anchor大小
anchor宽高比
第一层
33x33
0.04, 0.056



1, 0.62, 0.42
第二层
17x17
0.08, 0.11
第三层
9x9
0.16, 0.22
第四层
5x5
0.32,  0.45
第五层
3x3
0.64, 0.72

笔者使用基于 Keras 实现的目标检测微框架训练的人脸口罩检测模型,为了避免一些网友提到的使用手挡住嘴巴就会欺骗部分口罩检测系统的情况,我们在数据集中加入了部分嘴巴被手捂住的数据,另外,我们还在训练的过程中,随机的往嘴巴部分粘贴一些其他物体的图片,从而避免模型认为只要露出嘴巴的就是没戴口罩,没露出嘴巴的就是带口罩这个问题,通过这两个规避方法,我们很好的解决了这个问题,大家可以在 aizoo.com 体验我们的模型效果。

后处理部分主要就是非最大抑制(NMS),我们使用了单类的 NMS,也就是戴口罩人脸和不戴口罩人脸两个类别一起做 NMS,从而提高速度。




二. 数据

其实,做这个项目,笔者使用个人实现的检测框架,只用两个小时就搞定了训练部分。但是,为了整理数据,笔者花了整整两天的时间。如果我们花两天时间写代码,我们不觉得痛苦,但是如果花两天时间标注数据,那是一个相当痛苦的事情。

最初,笔者使用了 B 站一个本科生小伙公开的的 1 千多张图片训练了一个模型,但是该数据集比较单一,很容易出现用手捂住嘴巴,模型就认为是戴口罩这种问题,后面,笔者决定自己整理数据集。

人脸检测数据集非常多,其中最常用的莫过于 WIDER Face 数据集,我们从中选择了 3894 张图片,并进行了校验,主要是将部分戴口罩的人脸标注为戴口罩。对于戴口罩的人脸,我们使用了中科院信工所葛仕明老师开源的 MAFA 数据集,该数据集本是一个遮挡人脸的数据集,其中有各种被遮挡的人脸图片,大多数都是被口罩遮挡的人脸图片,我们从中选择了 4064 张人脸戴口罩的图片。

MAFA 数据集的人脸位置定义与 WIDER Face 有较大区别,MAFA 的人脸框在靠近眉毛上方,是正方形的,而且标注框不严格 (框离脸部边缘有缝隙) ,而 WIDER Face 的人脸框在额头上方,如果不进行修改,会导致模型对于不戴口罩的人脸,检测框是到额头上方,而戴口罩的人脸,检测框只到眉毛上方。因此,我们重新标注了这部分 MAFA 数据。 (标注数据真的是一个非常难受的过程~)

我们最终对数据进行了随机划分为训练集和验证集。下表是数据统计。


来自
WIDER Face
来自
MAFA
共计
训练集/张
3114
3006
6120
验证集/张
780
1059
1839

关于数据部分,我们就介绍到这里。需要的朋友可以在文末找到下载链接。




三.  TensoFlow.js部署






请到「今天看啥」查看全文