口罩佩戴检测毕设全流程:基于YOLOv5的目标检测与部署实战
1. 题目拆解这个毕设到底在做什么1.1 核心需求与功能边界口罩佩戴检测这个题目这几年在毕业设计里的出镜率一直很高。原因很简单它既有目标检测这个经典计算机视觉方向做核心又有真实落地场景做支撑做起来不容易跑偏答辩也有东西可讲。本质上它不是单纯的图像分类而是目标检测任务的两个层次先找到画面里的人脸再判断这张脸是否佩戴了口罩。别小看这句话它直接决定了后面所有环节的方案选型。很多同学最开始容易把问题理解成分类任务觉得套个分类网络就能交差结果做出来的东西一遇到多张人脸就崩。实际上你必须在一个框架里同时完成在哪和是什么两件事。功能边界上比较常见的需求拆解是输入支持单张图片、视频文件和摄像头实时画面输出画检测框并标注每个人脸的类别通常分三类——正确佩戴口罩、未佩戴口罩、佩戴不规范比如把口罩拉到下巴、只遮住嘴没遮住鼻子。有些课题还会附带统计功能比如记录某个时间段内未佩戴口罩的人次这类功能在门禁、考勤场景里很受欢迎答辩演示也直观。这里有个容易忽略的决策点佩戴不规范这个类别到底做不做。我见过不少课题明确要求三类检测也有课题只要求两类。三类检测的难点在于不规范本身有歧义标注标准不统一模型容易学偏。如果题目没写死建议做三类能讲的故事更多如果题目写死两类也别强行加避免给自己挖坑。1.2 为什么选深度学习方案而不是传统视觉这个题目如果放在七八年前用传统图像处理也能做个七七八八肤色检测找脸、颜色特征判断嘴巴区域有没有被遮挡。但这类方案有致命弱点人脸角度一变就丢、光照一变就翻车、肤色和口罩颜色相近就完蛋。说白了传统方法的特征都是人手工设计的泛化能力非常有限。深度学习方案把这个过程变成了数据驱动模型自己从大量样本里学到什么是脸口罩长什么样。只要数据够、场景覆盖全效果和鲁棒性都远不是传统方法能比的。而且现在目标检测框架非常成熟工程上不需要从零搭网络把精力放在数据处理和调参上就行——这对毕设来说是最务实的路径。还有个现实因素答辩老师几乎默认你会用深度学习。选传统方案除非做得特别漂亮否则很难拿到高分。深度学习方案配合消融实验、对比实验论文和PPT都能写得更扎实这也是这个题目长盛不衰的原因之一。2. 技术选型模型、框架与部署方案的权衡2.1 检测算法为什么单阶段检测更合适目标检测算法大体分两派。两阶段的代表是Faster R-CNN系列先产生候选区域再逐区域分类精度高但速度慢单阶段的代表是YOLO、SSD直接用回归的方式一步输出位置和类别速度快但早期版本精度略低。口罩检测这种场景尤其要做实时视频流对速度要求很高单阶段几乎是唯一合理的选择。在单阶段里YOLO系列又是首选。YOLOv5是社区里用得非常多的版本代码结构清晰、文档齐全、部署生态成熟从训练到导出再到推理的链路被验证过无数遍。新版YOLO在精度上有提升但对毕设来说YOLOv5的稳定性和资料密度更占优势——遇到问题搜索一下就能找到解决方案。这不是说新版本不好而是毕设讲究稳把一套成熟链路跑通比追新框架重要得多。我用一张表对比常见候选方案方便你根据硬件条件做选择方案精度速度显存需求部署难度适合场景Faster R-CNN高慢高中离线分析、论文对比实验SSD中中中中轻量场景YOLOv5s中高快低低实时检测、毕设首选YOLOv5m高较快中低精度要求更高的实时场景新版YOLO系列高快中中想展示新技术的场景2.2 模型规模s还是m怎么选YOLOv5按网络宽度和深度提供了n、s、m、l、x几个档位。这里存在一个典型的参数选择陷阱很多同学觉得越大越好直接上最大档结果显存不够、训练时间翻倍、推理帧率还上不去。实际上对口罩检测这个任务来说s档位已经完全够用。为什么这么说因为口罩是一个特征极其鲜明的大目标。相比行人检测、车辆检测这类有大量小目标和形变的场景人脸区域在画面里通常占比不小口罩和肤色之间的边界也足够清晰模型不需要特别深的网络也能学得很好。我做过一组对比在同样的数据集上s档位训练一百轮就能达到接近m档位的效果而推理速度能快一倍以上。如果毕设要求在嵌入式设备上跑比如常见的入门级开发板或边缘计算盒子那还得考虑更轻量的档位或者把骨干网络换成轻量化的MobileNet结构。这个选择的核心逻辑是先明确部署目标再反推模型规模而不是先选大模型再想办法压缩。2.3 开发框架与环境搭建框架层面PyTorch基本是当前目标检测领域的事实标准YOLOv5官方代码就是PyTorch写的。环境配置上Python版本、CUDA版本、PyTorch版本三者要匹配这个老生常谈但总有人栽跟头。我的建议是直接按官方环境配置装一遍别自己贪新鮮装一堆高版本包版本组合一旦不对各种莫名其妙的报错会让人怀疑人生。训练硬件方面一张中端独立显卡8GB以上显存就可以愉快地训练。如果实验室没有GPU也别慌有几个替代路子用云服务器租GPU按小时付费、用在线深度学习平台的免费额度、甚至用CPU训练小模型也不是不行就是慢得让人着急。我见过有同学用CPU从零训练花了三十多个小时才跑完虽然结果也能看但调参迭代效率完全没法保证。预算允许的话还是优先解决GPU问题。3. 数据集决定模型上限的关键一步3.1 数据从哪来公开数据、自采集与合成数据口罩检测的数据集来源大体有三条路开源社区已有的口罩检测数据、人脸数据加口罩合成、自己拍摄补充。一上来就扎进自采集的同学往往效率极低因为要覆盖各种角度、光照、人群密度人工拍摄几百张都未必够。正确的姿势是先汇集公开数据再用合成和自采做补充。我实际跑过的项目里常用组合是公开人脸检测数据用来保证模型对脸的召回能力 公开口罩遮挡数据用来学习口罩长什么样 自行采集或合成数据用来补齐特定场景覆盖率。合成这块有个很实用的技巧——用图像处理的方式给公开人脸数据戴上口罩。具体做法是准备一些口罩贴图做人脸关键点对齐后贴上去加上随机缩放和旋转能快速生成大批量带标注的口罩样本。这种方式生成的样本虽然和人眼看到的真实照片有差异但作为数据补充效果很好尤其能解决未佩戴和正确佩戴样本数量悬殊的问题。3.2 标注规范类别体系与边界框绘制标注这一步直接决定模型学什么千万不能马虎。先说类别体系如果按三类做标注时要把未佩戴正确佩戴佩戴不规范分开。最容易出问题的是不规范类比如口罩挂在下巴上、只罩住嘴露出一半鼻子不同标注员的理解不一样就会给模型喂矛盾信号。我的建议是制定一份简短的标注规范文档写清楚什么算不规范并且统一由同一个人完成核心标注减少标注标准漂移。边界框的绘制也有技巧。很多人标注时习惯把框画得特别紧贴着物体边缘这在目标检测里并不是最优的。框稍微留出一点边距让模型看到物体的完整上下文收敛更稳定。另外口罩遮挡导致人脸下半部分不可见时框的范围应该包含整个头部区域而不是只框口罩部分——因为模型学的类别是戴口罩的人脸不是口罩本身。标注工具建议用开源的图形化工具导出Pascal VOC格式后写个脚本转成YOLO需要的txt格式。转换脚本网上很多但要注意一个高频坑VOC的坐标是左上角和右下角YOLO格式是归一化的中心点和宽高换算公式容易写错。我帮某同学排查过一个问题模型loss一直降不下去最后发现就是坐标转换脚本里除以了图片宽度却没除以高度所有标注框全都错位了。3.3 数据增强与数据集划分数据增强是口罩检测里特别关键的环节。口罩场景天然会遇到光照变化、人脸角度变化、部分遮挡这些都可以通过增强模拟。我常用的增强手段有随机水平翻转注意标注坐标要同步变换、HSV色域扰动、随机缩放和裁剪、以及YOLOv5自带的马赛克增强。马赛克增强会把四张图拼成一张极大地丰富了上下文信息对提升小目标检测能力很有帮助训练初期开着就好。数据集划分上训练集、验证集、测试集按8:1:1是常规操作。但要注意一个隐蔽问题如果同一个人的多张照片分别进了训练集和测试集测试指标会被作弊式地抬高——模型相当于见过这个人了。所以划分时要尽量按人物维度或场景维度隔离保证测试集的陌生感。这个细节在答辩时提一下老师会觉得你考虑得很全面。4. 模型训练参数配置与调参实录4.1 从目录结构到配置文件跑通第一次训练拿到YOLOv5代码后别急着改代码先把目录结构和数据组织搞清楚。以YOLOv5的工程惯例为例数据集放外面按images和labels两个目录放图片和标签train、val子目录分别对应训练集和验证集。数据配置文件里要写清楚路径、类别数和类别名改了这三项基本就能开跑。第一次训练建议用官方预训练权重初始化而不是从零开始。预训练权重在大型视觉数据集上学到过通用的特征提取能力迁移到口罩检测上收敛快得多。我实测过用预训练权重一百轮能达到的效果从零训练可能要两百轮以上而且还未必追得上。成本差这么多没有理由不用迁移学习。启动训练这行命令本身不复杂核心参数也就那几个。我常用的配置是图像尺寸640、批大小16、训练一百到一百五十轮、使用SGD优化器。下面这个是我实测能稳定收敛的训练命令可以直接参考python train.py --img 640 --batch 16 --epochs 120 --data mask.yaml --weights yolov5s.pt --device 0如果显卡显存比较紧张比如只有6GB把批大小降到8图像尺寸降到480也能跑只是效果会略降。设备0表示使用第一张GPU多卡并行对毕设场景来说没什么必要单卡就足够了。4.2 学习率、批大小与权重衰减的取舍调参这件事新手最喜欢问最优参数是多少但更值得理解的是参数之间怎么互相牵制。学习率决定了每步更新的步长YOLOv5有自动学习率调度一般不用手动调但如果你换了优化器或者改了批大小就得重新审视。批大小和学习率是强相关的批大小翻倍保持收敛效果通常要把学习率也翻倍这叫线性缩放规则。SGD优化器配合动量0.937和权重衰减0.0005是YOLOv5的默认组合实测很稳。Adam优化器收敛更快但最终精度往往略逊而且对权重衰减更敏感新手别轻易换。我踩过的坑是把批大小从16提到32后忘了调整学习率结果训练直接发散loss曲线一路上涨。后来按线性缩放规则把初始学习率调上去才恢复正常。这个问题的排查思路很简单——loss不降反升优先怀疑学习率过大先把学习率降一个数量级试试。4.3 训练过程观察loss曲线和mAP指标怎么看训练不是启动完就等着看结果的你需要定期观察几个关键信号。第一个是总loss曲线理想情况是平滑下降并趋于平缓第二个是验证集上的mAP0.5这个指标反映检测质量第三个是精确率和召回率的平衡。这里补充一个容易理解错的概念mAP是多个召回率阈值下精确率的平均值它综合考察模型能不能既找得准又找得全。答辩时不需要把公式背得多熟但要知道三个指标的含义精确率是预测为正的里面有多少是真正召回率是真正的正样本里有多少被找出来了。口罩检测场景里漏检一个未戴口罩的人比误报一个戴口罩的人后果更严重所以在调参时可以适当偏向召回率——具体做法是训练后压低检测置信度阈值或者在NMS阶段放宽。训练过程中的过拟合也很常见典型表现是训练集loss持续下降但验证集loss先降后升mAP停在某个水平不再增长。遇到这种情况优先加数据增强、加Dropout或加大权重衰减而不是盲目加训练轮数。有同学训练三百轮验证集效果还不如一百五十轮的就是典型的过拟合拖垮了泛化。4.4 中途中断与恢复训练训练跑到一半断电、显存爆掉、机房维护导致进程被杀这些事故几乎每个跑深度学习的人都遇到过。YOLOv5的机制是每隔一段时间自动保存权重文件包括最好的一组和最后一组恢复训练直接用resume参数指定断点位置即可。这里有个实操提醒保存的权重文件包含优化器状态恢复训练时的学习率调度也会继续往下走所以别从网上随便下一份别人的权重来继续你的训练优化器状态对不上会直接影响收敛。另外每次跑实验前记得保存好训练日志YOLOv5会把超参数、loss曲线、指标变化都写入日志文件答辩时做图表展示这些日志就是第一手素材。5. 模型评估与效果优化5.1 评估指标与错误分析训练结束后模型在测试集上的表现要通过系统性的评估来确认而不是只拍几张效果图了事。最常规的做法是跑一遍测试集统计mAP、精确率、召回率、F1值再看混淆矩阵分析误判集中在哪两个类别之间。受口罩检测的特殊性影响最常见的混淆是佩戴不规范和未佩戴之间。原因是这两种状态下人脸下半部分的视觉信息差异本来就模糊——口罩拉到下巴时模型可能认为嘴巴区域有遮挡。遇到这种情况单纯调参收效有限更有效的路径是补数据专门收集一批口罩在下巴口罩捂嘴不捂鼻的样本加入训练集重训往往比调任何超参数都管用。另一个值得分析的是漏检和误检的分布。漏检多发生在小目标、远距离、背光场景误检则多发生在人像海报、手机屏幕里的人脸。前者要用多尺度训练和降低置信度阈值来缓解后者通常因为训练数据里缺少非人脸但像人脸的负样本。我的处理办法是收集一些包含海报、广告屏、玩偶的图片标注为空背景让模型学会拒绝效果立竿见影。5.2 针对口罩场景的专项优化做完常规评估再来看几个对口罩检测特别对症的优化手段。第一NMS参数调整。YOLOv5默认的NMS参数在通用场景下表现不错但口罩场景里人群密集、人脸重叠多框之间的IoU普遍偏高如果阈值设置不当会导致一个脸被框两次或者相邻的人被合并成一个框。我建议在验证集上做一个简单的阈值扫描实验把IoU阈值从0.1到0.9按步长0.1跑一遍看哪个点mAP最高通常在0.45到0.6之间。第二输入分辨率与多尺度。口罩检测对分辨率不敏感因为目标是中大型目标但如果你要识别的场景里有大量远距离人群适当提升输入分辨率小目标召回率会有明显改善。代价是推理变慢所以这个参数要结合部署设备的算力来定。第三置信度阈值的选择。训练评估时用的是偏保守的默认置信度阈值实际部署时要按场景容错要求选定。如果系统是门禁报警类宁可多报警也不能漏报阈值设低一点如果是通行记录类误报会污染统计结果阈值就设高一点。这里没有标准答案只有场景适配。6. 系统设计与部署实现6.1 整体架构与三种落地形态深度学习模型训完只算完成了一半毕设要想拿高分后面这个落地环节反而更拉分。一个完整的口罩检测系统至少包含三部分前端界面负责上传图片、播放视频流、展示结果后端服务负责接收请求、调用模型推理、返回结果推理引擎负责把训练好的模型跑起来提供检测能力。常见的落地形态有三种网页应用、桌面应用、嵌入式设备。网页应用的优势是跨平台、演示方便用浏览器就能访问适合大多数毕设桌面应用用Python的图形界面库写界面可以做得很精美交互自然但要装客户端嵌入式方案把模型跑到边缘设备上硬件成本高、实现复杂但如果课题方向就是边缘智能那必须走这条路。我推荐的工作量分配是模型部分占六成精力系统部分占四成。很多同学做完模型就松懈了系统随便套个模板答辩时只能干巴巴地讲技术缺乏直观演示。反过来一个界面清爽、交互流畅、带实时统计功能的系统哪怕模型本身中规中矩答辩观感都会好很多。6.2 模型导出与后端推理训练好的PyTorch模型直接用于生产环境不是最优选择。推理阶段通常把模型导出成ONNX格式好处是脱离开PyTorch运行时、推理速度更快、还能被不同推理框架加载。导出命令非常简洁python export.py --weights best.pt --img 640 --include onnx导出后建议用ONNX Runtime做一次推理验证对比一下输出结果和PyTorch原模型是否一致。我踩过的坑是导出时如果指定了动态轴但没设置对应的输入动态尺寸推理时换了尺寸就会报错另外某些自定义算子对ONNX支持不友好导出时看到warning要仔细阅读必要时回退到PyTorch直接推理别在导出上耗太久。后端推理服务我习惯用FastAPI搭建它是一个轻量级的异步框架写检测接口非常顺手。核心逻辑是接收上传的图片或视频帧做预处理缩放、归一化、转Tensor交给ONNX Runtime推理拿到检测框后画出来再返回给前端。多个人脸同时检测的场景要确保服务端一次性处理完一帧内的所有检测框不要在接口层面做循环调用否则性能损耗很大。6.3 前端演示与实时视频流处理前端部分最简单的方案是一个单页应用三个功能按钮图片检测、视频检测、摄像头实时检测。图片检测上传后展示标注结果视频检测支持上传视频文件逐帧处理摄像头检测调浏览器的媒体接口拿流然后推送到后端推理。实时视频流有个性能要点不要把每一帧都发到后端做同步推理否则画面会卡成幻灯片。更稳的做法是后端维护一个异步队列推理线程从队列取帧新的帧到来时如果上一帧还没处理完就丢弃保证输出帧率稳定。另外视频流检测要控制结果的平滑性不要每帧都在界面上闪烁新的框可以做一个简单的帧间结果过滤——只有连续两三帧都检测到同一个人时才更新状态误检干扰会小很多。我实际做完的效果是单张图片检测约五十到八十毫秒视频流能达到每秒十五帧以上中端独立显卡上表现流畅纯CPU做720p推理也能跑到五帧左右。这个成绩对毕设演示完全够用。7. 踩坑记录与问题排查速查表7.1 训练阶段的典型问题整个项目做完我把遇到的典型问题整理成一份速查表后面同学再做这个题目时可以直接对照排查。现象可能原因排查方向loss变成NaN学习率过大、标注数据异常、float溢出先降学习率再检查标签文件是否有越界坐标loss不下降坐标转换公式错误、类别名不匹配、数据增强过度逐条检查标签格式用可视化脚本画出标注框确认显存不足批大小太大、输入分辨率太高减小批大小、关闭部分增强、使用梯度累积训练集指标高但验证集差过拟合加数据增强、加权重衰减、减少训练轮数某个类别完全检测不到该类别样本太少做类别数据均衡对少样本类别做过采样或复制增强坐标转换错误这个问题值得多说一句因为它坑过不少人。YOLO格式的标签是归一化到0到1的如果一张图里目标中心x坐标计算出来大于1那一定是转换脚本里除错了参数。我习惯在训练前写一个可视化脚本把标注框画回原图上目检一遍这一步能省掉后面至少三天的排查时间。7.2 推理与部署阶段的典型问题到了推理阶段问题从学不出来变成跑不对路。常见的几类检测框偏移通常和预处理时的缩放方式有关训练时的填充策略在推理时没做一致误检率偏高往往和置信度阈值设置有关视频卡顿和帧处理逻辑有关排查方向是看是不是每帧都做了同步推理。还有一个细节部署时图片是从前端上传的手机拍的竖屏照片可能自带旋转元数据OpenCV读取时不会自动纠正导致检测结果旋转九十度。处理办法是在前端或后端统一规范化图片朝向否则竖屏场景会漏检很多。7.3 答辩演示的几个实用建议最后说说展示环节这部分往往被低估。至少准备三段内容一是数据集和标注过程的示意图让老师看到你在数据处理上的工作量和严谨性二是训练过程的指标变化曲线配上训练日志的真实截图展示调参过程三是一段包含各种典型场景的演示视频比现场连摄像头靠谱得多——现场网络、光线、摄像头驱动出问题的概率太高了。对比实验也值得提前准备。哪怕只做一组有预训练权重与无预训练权重或加入数据增强与未加数据增强的对照答辩时都能讲出故事来。老师核心关心的是你是否真的理解了整个链路而对比实验就是展示理解深度的最直接方式。8. 最后分享一点带项目的心得这个题目做完我最深的体会是口罩检测表面上是目标检测模型的训练实际上考察的是数据处理、调参分析、工程部署的综合能力。很多同学把大量时间花在调模型上觉得模型指标就是一切后来才发现让答辩现场流畅演示的系统架构、让老师眼前一亮的错误分析、让指标曲线显得可信的日志记录这些边缘工作才是真正拉开差距的地方。如果正在做这个题目规划时间时按数据三成、训练三成、系统三成、答辩材料一成来分配大概率比一头扎进模型调参要稳得多。我亲手带过的某同学就是这样模型精度算不上最顶尖但整个链路完整、逻辑自洽、演示流畅最后顺利通过。毕业设计考察的从来不只是模型精度而是你有没有能力把一个问题从头到尾地解决掉。把每个环节想清楚、留下记录、做出可演示的成果这个题目就能成为一份让人满意的答卷。