☰
YOLOv5口罩检测实战:从数据标注到部署优化的完整指南
2026/10/17 3:15:52 网站建设 项目流程

口罩检测这几年是真没少做。从最早的“戴没戴”二分类,一路做到现在要区分“口罩歪了”“鼻子露出来”“下巴口罩”这种细粒度状态,YOLOv5几乎是大家在工程落地时的默认起点。我见过不少项目团队,从学术demo到闸机、门禁、工厂安监,后端模型五花八门,但前期的快速验证大多都落在YOLOv5上。这个系列文章想系统梳理一下基于YOLOv5做戴口罩检测时,从任务拆解、数据构造、模型改法到部署落地这一整套环节里,哪些问题是你一定会碰到的,哪些坑是文档里不会写的,以及为什么最终大家不约而同地选了某些方案。

这篇综述不会去堆叠论文列表,更多是站在实操角度,把“检测戴口罩”这件事作为一个完整的目标检测项目来拆。适合正在做类似安防、闸机、合规监测项目的开发者,也适合刚入行目标检测、想找一个不太难但细节很多的练手项目的同学。

1. 任务本质与难点拆解

1.1 戴口罩检测到底是什么任务

戴口罩检测在外人看来就是“框出人脸,判断有没有口罩”,但真正落到数据标注和模型训练上,你会发现它属于典型的多标签目标检测问题:同一个目标(人脸)上有两个高度重叠的类别,而类别之间的边界极其模糊。

比较常见的定义方式有两种。第一种是二分类检测:只检测人脸的“未戴口罩”状态,不检测“戴了口罩”的人脸。这种做法的好处是类别简单、误报率容易控制,适合只关心“谁没戴”的合规场景。第二种是双类别或多类别检测:同时检测“戴口罩人脸”和“未戴口罩人脸”,甚至增加“口罩佩戴不规范”第三类。后者的信息量更大,但类间混淆也更严重,尤其是“口罩拉到下巴”和“未戴口罩”在正面视角下几乎没有差异。

从目标检测的框架来看,无论哪种定义,模型输出的都是边界框加类别概率。区别在于你如何定义“正样本”和“负样本”,这直接决定了损失函数优化目标和最终模型的行为边界。我在实际项目里强烈建议:如果不是有明确的监管合规需求,第一版模型先做两类,也就是“戴口罩人脸”和“未戴口罩人脸”,第三类不规范的类别等两类模型的置信度分布稳定之后再考虑加。

1.2 三个绕不开的技术难点

口罩检测看起来是个简单的目标检测任务,但它有自己特有的难点,和通用的人脸检测、行人检测不太一样。

第一个难点是遮挡导致的特征缺失。人脸检测依赖五官关键点,而口罩会覆盖嘴巴、鼻子,剩下眉眼区域可用。这种情况下,模型能学到的判别特征大幅减少,小尺度人脸尤其容易被漏掉。头部稍微偏转,口罩边缘和肤色融为一体时,模型很容易把“戴口罩的人脸”漏检。

第二个难点是类别间相似度太高。口罩的材质、颜色五花八门,但“未戴口罩的下半张脸”和“颜色接近肤色的布口罩”在像素层面上高度相似。尤其是医用蓝色口罩和深色口罩在特定光照下,纹理特征非常弱,模型在没有足够上下文信息的情况下很难区分。这也是为什么分类头比检测框头的设计更关键。

第三个难点是环境干扰。实际场景里不可能只有一张干净的人脸。帽子、围巾、护目镜、屏风、反光玻璃,这些都会让模型把非人脸区域误判为人脸,或者把戴了口罩的人漏掉。疫情期间我做过一个园区门禁项目,最头疼的不是“没戴口罩的人”,而是“手拿着口罩在嘴边”这种瞬间状态,模型很容易把手上那团蓝色误判成“佩戴口罩”。

2. 为什么YOLOv5是合适的基线模型

2.1 检测器选型的底层逻辑

戴口罩检测本质上受限于数据规模,尤其是细粒度状态检测,很难拿到海量标注数据。所以选模型时,不能单看精度指标,更要看三个方面:训练效率、迭代速度和部署友好度。

早期做口罩检测常用两级检测器,精度确实高,但训练慢、调参复杂,在边缘设备上的推理速度也不乐观。单级检测器虽然起步精度稍低,但胜在结构简洁、速度极快,而且口罩检测本身不是极难的目标检测任务,单级检测器的精度上限足够用。

YOLOv5在设计上其实做了很多对工程落地友好的选择。它的CSPDarknet骨干网络在保持特征提取能力的同时控制了计算量;PANet结构让浅层细节和深层语义信息能充分融合;anchor机制相对成熟,不会像无anchor方法那样对正负样本分配策略要求很高。这些特性组合起来,让它成为“快速出效果”的最佳起点。

2.2 YOLOv5的核心结构回顾

YOLOv5由三个主要部分组成:骨干网络、颈部和检测头。

骨干网络以CSPDarknet为基础。CSP结构将特征图分成两部分,一部分经过密集卷积,另一部分直接拼接,这样在减少计算量的同时保持梯度传播的多样性。Focus层虽然不是YOLOv5首创,但通过切片操作把空间信息压缩到通道维度,在浅层特征保留上效果不错。

颈部采用PANet结构。FPN自顶向下传递语义信息,PANet额外增加一条自底向上的路径,让浅层的位置信息能反向融合到高层。对于口罩检测这种依赖细节纹理的任务,浅层高分辨率特征非常重要,PANet的贡献很直接。

检测头则仍然使用基于anchor的预测方式,在每个特征图位置预测多个尺度的边界框。YOLOv5的anchor是在训练数据上自适应计算出来的,这点在戴口罩检测这种边界框比例比较固定的任务里很省心。

2.3 不同规模版本的选择策略

YOLOv5提供了从n到x的多种模型规模。口罩检测的实际部署环境差异很大,选型逻辑也不同。

对于GPU服务器上的高精度需求,L或X版本更合适,它们参数量大、特征表达能力更强。对于嵌入式设备如树莓派或低成本边缘盒子,n或s版本几乎是唯一选择,这时候就要在精度和速度之间做权衡。

从我的经验来看,如果训练数据不是特别充足,不建议一上来就用x版本。大模型在数据量不足时更容易过拟合,泛化性能反而不如s或m版本。一个比较稳妥的策略是先用s版本跑通流程,确认数据没有问题后再切换到大模型做精度上限探索。

3. 数据集构建:决定模型上限的关键环节

3.1 公开数据与自采数据的取舍

戴口罩检测在初期有很多公开数据集可用,但用到项目里时你会发现一个尴尬:公开数据集大多是在理想条件下采集的,人脸角度正、光照均匀、口罩种类有限、背景干净。这种数据训练出来的模型,拉到真实场景里,性能会急剧下降。

如果项目预算允许,一定要有一条自采数据的流程。不需要追求数据量巨大,关键是场景覆盖率。门口、走廊、工位、户外、夜间、逆光,这些环境都要覆盖到;口罩颜色从医用蓝色到黑色、花色,都要有样本。我一般建议公开数据与自采数据的比例控制在7比3左右,自采数据主要用于补齐公开数据欠缺的分布。

3.2 数据清洗与标注规范

标注规范是戴口罩检测项目里最容易翻车的地方。很多新手直接拿开源标注工具框人脸,结果类别定义混乱,模型训出来之后行为完全不可控。

我遇到过最常见的标注问题有三个。第一,是否标注被遮挡的人脸。半张脸被手挡住、被帽子压住、侧脸超过120度,这些算不算正样本?我的建议是:如果没有明确业务需求,遮挡超过一半的人脸不要标注,否则模型会在遮挡和类别之间学到错误关联。第二,口罩佩戴不规范的边界。口罩在下巴上的框应该算“未戴口罩”还是“戴口罩”?这必须在标注规范里写明,我的做法是把“口罩完全覆盖口鼻”作为“戴口罩”的唯一标准,其余一律算“未戴口罩”。第三,小目标的标注,极远距离的模糊人脸是否标注,要规定一个最小像素阈值,我通常设置在32像素以上,低于这个值的人工标注噪声太大。

数据清洗方面,要去掉重复帧、跳跃帧、严重模糊帧,同时做类别平衡检查。未戴口罩样本和戴口罩样本的比例最好控制在1比1到1比3之间。如果类别极不平衡,模型会对多数类过拟合,推理时不管有没有口罩都倾向于输出那个类,这在安防场景里是致命的。

3.3 数据增强策略

口罩检测的数据增强既有通用目标检测的常规操作,也有一些针对性的特殊策略。

常规操作包括随机裁剪、翻转、色彩抖动、亮度对比度调整、马赛克增强。其中马赛克增强非常有用,它将四张图拼成一张,大大丰富了目标尺度和上下文背景,对改善小目标检测效果尤其明显。但使用马赛克训练时要注意,如果batch size较小,每张图的目标分布差异很大,训练初期loss会剧烈震荡,需要配合warmup让模型先稳定下来。

口罩检测特有的增强策略是“口罩模拟”。简单说,就是用程序生成口罩贴在未戴口罩的人脸上,制造出大量正样本。具体实现可以用关键点定位人脸区域,然后随机贴一个掩膜图像。这种策略在数据量不足时非常有效,能快速扩充样本规模。我实际测试过,在只有5000张人脸数据的情况下,用口罩模拟增强可以额外生成两万张训练图,模型mAP提升约6到9个百分点。但要注意,模拟口罩的颜色、形状、贴合程度要和真实口罩有足够的多样性,否则模型会对模拟口罩过拟合。

4. 网络层面的改进方向

4.1 骨干网络的选择与替换

YOLOv5默认的CSPDarknet在大多数场景下表现均衡,但如果想在口罩检测上再进一步,替换骨干网络是最直接的手段。

我试过几种替换方案,几种轻量化骨干在嵌入设备上能明显提升推理速度,精度损失在一定范围内可以接受;而更强的大骨干虽然能提升精度,但在边缘设备上可能跑不动,需要谨慎权衡。常规替换思路是:如果数据量在几万张级别且需要高精度,可以换用更强的骨干网络;如果数据量不大,换骨干带来的收益有限,不如把时间花在数据上。

另一个容易忽略的点是骨干网络是否在大型数据集上预训练过。口罩检测数据规模一般不大,从零训练很难收敛。我会优先选择在大型视觉数据集上预训练过的权重作为初始化,然后冻结前几层,只训练高层特征部分,这样可以显著减少训练时间并改善收敛效果。

4.2 注意力机制与特征融合

口罩检测中一个很实用的技巧是加入注意力机制。SE模块、CBAM、ECA这些轻量级注意力模块,可以在几乎不增加计算量的情况下提升特征通道的判别力。实际测试表明,在特征提取网络的深层加入注意力模块,对区分“口罩遮挡的下半脸”和“没有遮挡的下半脸”有明显的帮助。

我个人比较推荐ECA或CBAM这类轻量方案,它们在边缘设备上的推理时间损失很小。在常规训练设定下,加入注意力机制后,未戴口罩类别的召回率能稳定提升1到3个百分点。

特征融合方面,除了PANet本身,还可以尝试在颈部网络增加额外的跨尺度连接。比如把骨干网络更浅层的输出直接引入检测头,增强对小型人脸和远距离人脸的感知。这对闸机、走廊这类摄像头距离较远的场景,改善效果比调任何超参数都明显。

4.3 损失函数与后处理策略

口罩检测任务的正负样本分布往往严重失衡,这会导致模型在训练时过度关注背景,而忽略正样本边缘细节。针对这个问题,调整损失函数是一项低成本高回报的改进。

最常用的方法是调整分类损失中的正负样本平衡参数,让模型更关注困难样本。也可以引入Focal Loss思想,降低容易样本的权重,逼迫模型学习那些“口罩颜色接近肤色”“姿态偏转”的困难样本。实测下来,Focal Loss对难例的改善很直接,但需要把超参数调好,否则训练初期loss会很大。

后处理方面,NMS的阈值选择也很关键。口罩检测场景经常出现两个高度重叠的框,一个是“戴口罩人脸”,一个是“未戴口罩人脸”,如果阈值设置不当,这两个框会互相压制,导致漏检。我一般将NMS阈值设置在0.4到0.5之间,然后额外对“未戴口罩”类别做一次soft-NMS或降低其置信度阈值,这样能减少漏报,代价是会稍微增加一些误报,在合规场景下,漏报的代价通常远高于误报。

5. 训练实战与超参数调优

5.1 基础超参数设置与训练策略

我训练戴口罩检测模型的默认配置大概是这样的:

  • 输入分辨率640×640,这是速度和精度的平衡点
  • 初始学习率0.01,使用余弦退火或线性衰减
  • 批量大小16到32,根据显存调整
  • 训练100到150个epoch
  • SGD优化器,动量0.937,权重衰减0.0005

训练前几轮先用较小的学习率做warmup很重要,可以避免模型在初期因学习率过大产生梯度爆炸。训练中期要观察验证集上的mAP变化,当mAP趋于平缓时,可以降低学习率2到3个数量级进行微调。我这个项目里最有效的一次提升,就是把最后10个epoch的学习率降到0.0001,mAP直接涨了2个点。

训练过程中的模型选择不能只看最后的权重,要保存每个epoch的验证集结果,最终选用验证集mAP最高的那一个epoch的权重,而不是最后一个epoch的。我之前吃过亏,最后一个epoch因为数据增强的影响,精度反而比前几个epoch低。

5.2 负样本策略与难例挖掘

负样本在口罩检测里往往被忽视,但它恰恰是影响误报率的关键。

简单把背景区域作为负样本是不够的。要主动收集和标注“难负样本”:手部、手机、书本、衣领、杯子,这些物品在视觉上和口罩颜色接近,容易被误判为人脸或口罩。我在项目里专门构建了一个难例池,把模型在真实场景里产生的假阳性图片收集起来,重新标注后加入训练集,这个策略对压制误报非常有效。

难例挖掘可以分两轮进行。第一轮先训练一个初步模型,在大量无标签视频帧上推理,挑出置信度低于0.3的低置信度检测框和置信度高于0.9但实际是误报的框,人工筛选后加入训练集重训。第二轮重复这个过程,直到模型在难例池上的表现稳定为止。这个过程看起来繁琐,但比不停地调后处理参数有效得多。

5.3 训练过程的监控指标

训练时不要只盯着总loss曲线,要分别观察三个主要部分:box loss、obj loss、cls loss。戴口罩检测的类别关系比较复杂,cls loss的收敛情况最能反映模型是否真的学会了区分“戴口罩”和“未戴口罩”。

另外,要特别关注每一类别的precision和recall,而不是只关注mAP。合规场景更看重未戴口罩类别的召回率,漏检一个没戴口罩的人,比多报一个戴了口罩的人严重得多。我在监控时会让未戴口罩类别的召回率保持在95%以上,如果低于这个阈值,即使mAP再高也不会上线。

训练过程中的数据增强强度也要动态调整。训练后期如果验证集mAP一直不涨,可以尝试关闭部分强增强操作,比如马赛克和随机裁剪,让模型收敛得更干净。这是一个非常实用的技巧,能有效避免模型在训练集上过拟合。

6. 模型评估与部署优化

6.1 评估指标的选择与解读

对于戴口罩检测项目,评估不能只看一个mAP。mAP是一个综合指标,在类别不均衡时容易掩盖真实问题。

我一般会分开统计每个类别的AP,重点关注未戴口罩类别的召回率。此外还会统计误报率,也就是每1000帧视频中,模型产生假阳性检测的次数。误报率在闸机、门禁这类人流量大的场景中非常关键,因为每次误报都会触发不需要的告警。

测试场景的设计也很讲究。不要只在一个视频上测试,要准备室内正光、室内逆光、户外白天、户外夜间、远距离小目标、多人密集等不同场景的测试集,分别记录各类别的precision和recall。这样能清晰看出模型在哪个场景下最弱,然后针对性地补数据或调参。

6.2 模型压缩与加速

模型训练完只是第一步,部署环节会有另一批问题。YOLOv5默认的PyTorch权重体积较大,直接跑在边缘设备上很吃力,所以需要做模型压缩。

常用的手段有三个:剪枝、量化和知识蒸馏。

剪枝主要针对通道维度,将贡献度低的通道删掉。YOLOv5结构在剪枝方面相对友好,但剪枝比例要控制在20%到30%之间,否则精度会明显下降。剪枝完成后需要重新微调训练,恢复精度。

量化是我最推荐的加速手段,尤其是8位动态量化或感知量化。在NVIDIA边缘设备上,TensorRT加速加上8位量化,推理速度通常能提升3到5倍,精度损失控制在2%以内。如果你使用其他平台,也有对应的推理引擎支持INT8量化,效果类似。

知识蒸馏是用大模型教小模型,在数据不足的场景下比单独训练小模型效果更好。我试过用YOLOv5x作为教师模型蒸馏到YOLOv5s,在同等速度下,蒸馏后的小模型mAP能提升3到5个百分点,性价比很高。

6.3 边缘设备部署的注意事项

部署到嵌入式设备时,有几个容易踩的坑。

第一个坑是输入图像的预处理方式。大多数深度学习框架训练时做了标准化,但推理时如果忘记保持一致,性能会明显下降。YOLOv5的预处理包括resize、归一化、通道变换这几个步骤,部署时要确保每一个细节都和训练时完全一致。

第二个坑是模型输出的解码逻辑。YOLOv5的原始输出包含边界框坐标、置信度和类别概率,需要经过解码、NMS等操作才能得到最终结果。很多新手直接在模型输出上画框,结果框的位置和大小完全不对。

第三个坑是内存带宽。嵌入式设备的算力往往够用,但内存带宽紧张。如果同时跑多个模型或输入分辨率过高,帧率会大幅下降。我一般会将输入分辨率降到480×480或544×544,这样既保留了检测能力,又减轻了内存压力。

7. 常见问题与排查技巧实录

7.1 问题速查表

我在多个口罩检测项目中积累了一些高频问题和对应的排查思路,整理成表格方便参考。

问题表现可能原因排查思路推荐解法
远距离人脸漏检严重小目标特征被深层网络丢弃检查小尺度特征图输出,看目标响应是否正常增加浅层特征融合,或提高输入分辨率
口罩颜色接近肤色时误检纹理特征不足,模型没学到判别信息查看困难样本的中间特征可视化增加此类样本数据,辅以颜色抖动增强
未戴口罩类别的误报率偏高难负样本不足,模型把衣服、手部当人脸统计误报目标的位置和类别构建难例池,加入对应负样本
训练loss下降但验证mAP不涨数据增强过强或过拟合对比训练集和验证集表现差异降低增强强度,早停或用验证集最优权重
部署后速度远低于预期预处理与解码未优化,或内存带宽瓶颈检查推理性能和CPU/GPU占用情况优化预处理、低精度推理、降低输入分辨率
同一张图片多次推理结果抖动后处理NMS阈值设置不稳定或随机性增强固定随机种子,检查NMS逻辑统一推理代码和NMS后处理逻辑

7.2 实战中的几点个人体会

最后分享几个我实际踩过坑之后形成的经验。

第一个经验是“先做端到端跑通,再优化精度”。很多人一开始就在调参、改网络,结果连基础的训练流程都没走通。我建议先把最简版本跑通:YOLOv5s、少量数据、默认参数、GPU训练,先得到一个可以出结果的模型,再逐步加数据、改结构、调参。这个节奏能帮你快速定位瓶颈在哪里,避免无效投入。

第二个经验是关于“模型要带着后处理一起评估”。YOLOv5模型的原始输出和经过NMS之后的结果差异很大,如果只评估模型输出的mAP,而忽略了后处理逻辑,最后部署时会发现实际效果远不如预期。我通常会把训练好的模型接上完整的后处理代码,模拟真实推理流程,再做端到端评估。

第三个经验是“数据集比网络结构重要得多”。在口罩检测这个任务上,我个人测试下来,扩充1000张高质量难例样本带来的精度提升,往往比改任何网络模块都要明显。如果你发现模型效果上不去了,先别急着改网络,回头看看数据:难例样本够不够,类别平不平衡,标注统不统一。这些问题不解决,网络改得再花哨也白搭。

口罩检测这个方向如今看起来热度稍减,但它的技术方法论却不局限于“口罩”本身。YOLOv5在这个任务里沉淀下来的数据标注规范、难例挖掘流程、轻量化部署方案,完全可以直接迁移到安全帽检测、反光衣检测、工服识别这类合规监测项目上。如果你正在找工作服或者安全装备检测的方向,把这篇综述里的思路换个检测目标,基本就够用了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询