YOLOv5口罩检测实战:数据集、模型训练与部署全流程解析
2026/9/20 13:46:53 网站建设 项目流程

简介:目标检测是计算机视觉的核心任务之一,YOLOv5作为单阶段检测器的代表,凭借速度与精度的平衡,成为工程落地和课程项目的热门选择。从数据准备到模型部署,完整的工程链路是深度学习实践的关键。本文围绕口罩检测这一典型应用,基于2000张标注数据,详细梳理了从数据集构建、环境配置、模型训练到推理部署的完整流程,并总结了常见踩坑与优化建议,适合目标检测入门者、课程设计者和算法工程师参考。 最近帮人复盘了一份课程大作业,标题就是“YOLOv5口罩检测数据集+代码+模型,2000张标注好的数据”。做过目标检测项目的人都懂,这种题目在高校里出现频率极高——既不算太难,又覆盖了从数据准备、模型训练到实际部署的完整链路,作为大作业选题确实聪明。

如果你正被同样的题目卡住,或者准备做类似的目标检测项目,这篇内容应该能帮你省掉不少试错时间。我会从项目选型、数据整理、训练参数、代码解析到踩坑记录,把整个流程掰开揉碎讲清楚。

1. 项目整体设计与技术选型思路

1.1 为什么口罩检测项目适合作为课程大作业

口罩检测本质上是一个二分类目标检测问题:在图片或视频中定位人脸区域,并判断该人脸是否佩戴了口罩。相比通用物体检测,它有几个明显优势,非常适合课程项目。

第一,数据集获取难度低。口罩数据不像工业缺陷、遥感影像那样稀缺,公开数据集和现成标注资源都很丰富,自己补充采集也方便。你拿到手的2000张标注图片,规模适中,能比较快地完成训练,不至于像大规模数据集那样跑一次要等很久。

第二,模型效果易于可视化。目标检测的结果可以直观画框展示,准确率和召回率也有清晰指标。答辩的时候,现场跑一段摄像头检测,效果一目了然,比讲一堆理论更能打动老师。

第三,技术栈成熟。YOLOv5社区活跃,文档完善,预训练权重容易获取,遇到问题基本都能搜到解决方案。对课程项目来说,稳定可靠比花哨更重要。

1.2 技术选型:为什么选YOLOv5而不是其他检测框架

目前主流的目标检测框架不少,两阶段的有Faster R-CNN,单阶段的有YOLO系列、SSD,还有Transformer系的DETR等。选YOLOv5,我是基于这几个考虑。

首先是训练和推理速度的均衡。单阶段检测器直接回归边界框和类别,不需要像Faster R-CNN那样先生成候选区域再二次分类,速度天然快。口罩检测通常有实时性需求,YOLOv5在GPU上能跑到几十到上百FPS,完全够用。

其次是工程化程度。YOLOv5的官方仓库把数据准备、训练、验证、导出、推理全都封装成了命令行工具,detect.py、train.py、val.py 各司其职,对新手非常友好。你不需要从零搭训练循环,改改配置就能跑通。

再者是预训练模型迁移带来的收益。mask检测和人脸检测都属于通用目标检测的下游任务,从COCO上预训练的权重出发做微调,收敛速度比随机初始化快得多,需要的样本量也小。这个在你只用2000张图片的情况下特别关键。

如果换成Faster R-CNN,精度可能不错,但工程代码量更大,训练也更慢,对课程作业来说投入产出比不高。如果换成最新的YOLOv8或者YOLOv9,某些模块改进确实带来精度提升,但对作业而言没有本质差异,而且如果你的机器配置一般,大模型反而增加负担。YOLOv5作为“够用且好用”的中间选择,是我推荐的理由。

1.3 数据集和项目文件的整体规划

拿到手的项目文件一般包含这几块:数据集(JPEGImages图片 + labels标注)、YOLOv5代码仓库、训练好的权重(best.pt)、以及推理脚本。先搞清楚每块内容是什么,再做训练和修改,会顺手很多。

数据集层面,2000张图是一个比较合理的课程项目规模:比单纯调库演示有工作量,又不至于训练时间过长。一般会划分为训练集和验证集,比例可以按9:1或8:2来。图片中的人脸可能包含戴医用口罩、戴布口罩、不戴口罩、戴歪口罩等情况,标注越规范,训练出的模型越可靠。

代码层面,建议单独把代码仓库放在项目根目录,数据集放在外部目录,用软链接或路径配置关联,避免数据集太大拖慢Git管理,也防止误改代码文件导致版本混乱。

2. 环境搭建与数据集预处理

2.1 环境版本匹配:Python、PyTorch与CUDA

YOLOv5对环境的依赖不算苛刻,但版本匹配问题足以浪费新手半天时间。我建议按以下组合配置:Python 3.8或3.9,PyTorch 1.10以上(2.x也可以),CUDA对应你的显卡驱动版本。如果没有NVIDIA显卡,CPU也能跑,只是训练速度慢很多,建议学习用,正式训练还是找台有GPU的机器。

安装依赖的方式是进入项目目录后执行:

pip install -r requirements.txt

这里有个细节:requirements.txt里的torch版本可能与你的CUDA不匹配。如果你已经单独装好了适配自己显卡的PyTorch,就不要直接装requirements里指定的torch,可以先打开文件把torch和torchvision两行注释掉,再安装其余依赖。

验证环境是否可用,最直接的方法是运行一个最简单的推理:

python detect.py --source data/images/bus.jpg --weights yolov5s.pt

如果能看到一张画了检测框的输出图,说明环境基本没问题。这一步建议在训练前就确认,不要等到训练中途才发现某个依赖缺失。

2.2 数据集目录结构与YOLO标注格式

YOLOv5对数据集目录有约定,训练前需要把图片和标注按固定结构放好。推荐使用这样的目录结构:

datasets/mask/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── mask.yaml

images里放jpg或png图片,labels里放同名的txt文件。关键点:图片和标注文件的名称必须一一对应,否则训练时找不到标注,会直接跳过该图。

YOLO标注格式非常简洁,每个txt文件里每一行代表一个目标框,格式是:

class_id x_center y_center width height

注意这里的四个坐标值都是归一化后的相对值,范围在0到1之间。x_center和y_center是目标框中心点相对于图片宽度和高度的比例,width和height是框的宽高相对于图片宽高的比例。如果直接用像素坐标或者用左上角右下角的格式,训练时损失函数会直接乱套。

我见过不少同学从网上爬数据时拿到的标注是VOC格式的XML,里面是xmin、ymin、xmax、ymax的绝对像素坐标。如果遇到这种情况,需要先转成YOLO格式。转换公式很简单:

x_center = (xmin + xmax) / 2 / img_width y_center = (ymin + ymax) / 2 / img_height width = (xmax - xmin) / img_width height = (ymax - ymin) / img_height

标签文件里class_id从0开始,比如0代表“佩戴口罩”,1代表“未佩戴口罩”,这个映射关系要和yaml配置文件里一致。

2.3 数据划分与类别平衡

数据准备好后,需要将2000张图片划分为训练集和验证集。我习惯按9:1划分,也就是1800张训练、200张验证。如果你的数据集包含戴口罩和不戴口罩两类,建议检查一下两类的数量比例,不要一边有1500张、另一边只有500张,差距过大会导致模型对少数类别学习不充分。

处理这种情况的方法有两个:一是收集更多少数类别的样本,二是在训练时设置类别权重。在作业场景下,更推荐前者,因为如果原始数据里就严重不平衡,即使调整损失函数权重,模型对少数类别的泛化能力依然有限。

划分数据时还要注意:同一个人或者同一个场景的图片,尽量只出现在训练集或验证集中,不要让一张场景的图片既参与训练又被拿去验证,否则验证指标会虚高,到了新场景上效果打折扣,答辩现场演示时容易被问住。

3. 训练前的关键配置:模型选择与超参数

3.1 配置文件里需要改哪些内容

YOLOv5训练时需要准备两个配置文件:数据集配置文件mask.yaml和模型结构配置文件yolov5s.yaml。模型结构配置文件一般不用大改,主要改数据集配置文件,格式如下:

train: datasets/mask/images/train val: datasets/mask/images/val nc: 2 names: ['with_mask', 'without_mask']

train和val分别指向训练集和验证集图片目录,nc表示类别数量,这里口罩检测就是2类,names列表与标注文件里的class_id一一对应。

有个很容易踩的坑是路径写法。YOLOv5会自动将相对路径拼接在当前工作目录下,如果数据集明明放在datasets/mask下却报“image not found”,多半是路径写错。建议直接用绝对路径,简单直接,省得排查。

3.2 预训练权重与模型规模的选择

YOLOv5提供了n、s、m、l、x五种不同规模的模型,复杂度依次递增。课程项目的数据量是2000张,我推荐使用yolov5s或者yolov5m。yolov5s参数约700万,训练和推理都快,显存占用低;yolov5m参数约2100万,精度略高,但训练时间相应增加。用yolov5l或更大模型跑2000张数据,不仅慢,而且容易过拟合,对作业来说没有必要。

使用预训练权重的方式:

python train.py --weights yolov5s.pt --data mask.yaml --img 640 --epochs 100 --batch-size 16

yolov5s.pt是在COCO数据集上预训练好的权重。初始训练时,模型会冻结主干网络的前几层,因为预训练特征已经足够通用,只需要微调后几层来适应口罩检测这个任务。如果你自己有训练好的模型,也可以在此基础上继续训练,比如用之前某次训练的权重作为初始权重接着跑,这在数据有更新时很有用。

3.3 超参数选择:epochs、batch size与学习率

超参数是容易被忽略、但影响很大的地方。先说epochs。2000张图片的数据量,一般训练100到200个epoch就足够。如果设置过少,模型欠拟合,mAP偏低;设置过多,后段loss基本不再下降,纯属浪费时间。可以用一个简单的办法判断:观察训练日志里val精度是否还在持续上升,如果连续20个epoch没有提升,就停止训练。

batch size主要受显存限制。在8GB显存的GPU上,yolov5s + 640分辨率,batch size设16是安全范围。如果显存不够,优先减小batch size,同时可以考虑把分辨率从640降到512,但会损失对小目标的检测精度。如果显存充足,适当增大batch size有助于稳定训练。

学习率方面,YOLOv5默认是0.01,配合余弦退火调度器,大多数情况下不需要手动修改。如果训练开始后loss出现明显震荡,可以考虑降到0.005;如果loss下降特别慢,可以稍微调到0.02。不过课程项目场景下,保持默认参数往往是最稳妥的。

3.4 数据增强逻辑与注意事项

YOLOv5默认开启Mosaic增强,也就是把4张图拼成一张输入。这个设计的目的在于增加小目标样本的数量,同时让模型对遮挡、不同尺度更鲁棒。在口罩检测中,Mosaic增强特别实用,因为很多脸部区域占比不大,通过拼接可以模拟更多样的场景组合。

但Mosaic增强有个副作用:训练样本与真实场景差异变大,如果验证时不开Mosaic,训练和验证指标可能不完全一致。这是正常的,不用慌。另一个增强策略是HSV色域扰动,它会让模型对光线变化更鲁棒。口罩检测场景中,不同光照条件下人脸颜色差异客观存在,这个增强对提高泛化能力有帮助。

如果你想减少增强强度,可以在data/hyps/hyp.scratch-low.yaml里调整,比如把mosaic参数从1.0降到0.5。不过我的建议是保持默认,让模型多接触一些变化,对应对实际场景中的复杂情况更有帮助。

4. 模型训练全流程与效果评估

4.1 训练命令逐项说明

训练命令大致是这样的:

python train.py \ --weights yolov5s.pt \ --data mask.yaml \ --epochs 100 \ --batch-size 16 \ --img 640 \ --device 0 \ --name mask_exp

逐项说下这些参数的作用:weights指定初始权重,data指定数据集配置文件,epochs是训练轮数,batch-size每批样本量,img输入图片尺寸,device指定GPU编号(CPU就写cpu),name是实验名称,训练结果会保存在runs/train/mask_exp目录下。

还有一个容易被忽略的参数是--workers,控制数据加载的线程数。默认是8,如果你的电脑CPU核数较少或内存不大,建议降到4或2,否则可能因为数据加载瓶颈拖慢训练,甚至在Windows下报DataLoader worker相关的错误。我自己的经验是Windows环境下workers设成0或2最稳,Linux下可以放心用8。

训练开始后,终端会实时输出每个epoch的loss、精度和召回率。你不需要盯着每个数字看,重点关注两类:一类是box_loss和obj_loss是否持续下降,另一类是验证集的mAP是否在提高。

4.2 训练结果目录里有什么

训练结束后,runs/train/mask_exp目录下会生成很多文件,常见的有:weights/best.pt(验证集mAP最高的权重)、weights/last.pt(最后一个epoch的权重)、results.png(训练曲线汇总图)、混淆矩阵、验证集预测结果图等。

这里有个实际经验:best.pt和last.pt不一定是同一个。如果训练后期过拟合,last.pt在验证集上可能不如best.pt,所以作业演示时一定用best.pt,不要随意拿last.pt做推理。

results.png非常直观,包含:训练和验证的box_loss、obj_loss、cls_loss曲线,以及precision、recall、mAP@0.5和mAP@0.5:0.95曲线。答辩时给老师展示这个图,比展示一堆终端日志更有说服力。

4.3 评估指标怎么解读

YOLOv5训练日志里最核心的指标是mAP@0.5和mAP@0.5:0.95。mAP@0.5的含义是当预测框与真实框的IoU大于0.5时算检测正确,计算所有类别的平均精度。如果你看到mAP@0.5在0.9以上,说明模型在这个数据集上表现已经很不错了。

mAP@0.5:0.95则是一个更严格的指标,计算IoU从0.5到0.95(步长0.05)共10个阈值下的平均mAP。因为口罩检测对边界框的精确性要求不算特别高,mAP@0.5:0.95在0.6到0.7之间已经是不错的水平。

Precision(精确率)的含义是在所有预测为某类别的框中,正确框的比例;Recall(召回率)的含义是所有真实目标中被检出的比例。这两个指标往往存在权衡,如果检测框绝大多数是对的但不全,精确率高、召回率低;如果什么框都画出来,召回率高、精确率低。理想状态是在P和R都高的情况下达到平衡,也就是PR曲线下面积大,对应mAP更高。

4.4 实际训练时的观察记录

我自己在类似数据集上跑YOLOv5s的经验是,前10个epoch损失下降明显,大概从0.1级快速降低到0.05以下;到30个epoch左右mAP@0.5能到0.8以上;50个epoch后提升速度变缓;80到100个epoch时基本稳定在0.9以上。如果你的数据质量好、标注干净,这个曲线应该大体一致。

如果前几个epoch损失不降,要看几件事:一是学习率是不是设得过高;二是数据集路径是否配错,有没有可能模型一直在空数据上训练;三是标注文件有没有和图片对应上。这些排查方法我会在第6章展开说。

5. 核心代码解析与二次开发

5.1 用训练好的模型做图片推理

训练完成后,用detect.py做推理是最基础的用法:

python detect.py --weights runs/train/mask_exp/weights/best.pt --source test.jpg --conf-thres 0.5

--source可以是图片路径、视频路径、图片目录,也可以是摄像头设备编号(0表示默认摄像头)。--conf-thres是置信度阈值,只有超过这个值的检测框才会被保留。口罩检测场景,我建议设在0.4到0.5之间。设太高会漏检,尤其是远处人脸或戴着花色口罩的人脸;设太低会误检,出现各种奇怪的框。

推理结果会自动保存到runs/detect/exp目录下,包含原图叠加检测框和类别标签后的效果图。这里建议你在答辩前自己多测几张不同场景的图片,比如室内灯光、户外逆光、多人场景,提前知道模型在哪些场景下表现好,在哪些场景下可能误检。

5.2 摄像头实时检测的演示技巧

作业演示时,摄像头实时检测是最容易拉满印象分的环节。命令本身就很简单:

python detect.py --weights runs/train/mask_exp/weights/best.pt --source 0 --conf-thres 0.45

打开摄像头后,窗口会实时显示检测结果。这里有几个实战细节大家最好提前处理。

一是摄像头权限问题。在Windows下,如果提示摄像头被占用或找不到设备,检查是不是有别的软件正在用摄像头。在远程服务器或虚拟机环境下,摄像头可能根本没有被正确映射,这时建议改用视频文件演示。

二是实时性。如果你在低配电脑上跑,发现画面掉帧严重,可以把输入尺寸从640降到480,或者把--view-img改为保存视频而不实时显示。显卡够好的话一般没问题,但提前测试总是好的。

三是演示翻车预案。摄像头现场出意外的情况我见过不少,电源管理把摄像头禁用了、驱动掉了、光线太暗导致完全检测不到人脸。建议提前录制一个短视频,万一现场摄像头故障,直接播放视频检测结果,依然能展示检测效果。

5.3 批量推理与结果导出

如果需要对一批图片或视频批量检测,同样用detect.py,--source直接指向目录或视频文件即可。检测结果中有一个labels字段,记录了每个检测框的类别、置信度和归一化坐标,你可以把这些结果导出成CSV,方便做统计分析。

有些同学会在大作业里加一些数据统计功能,比如统计一段视频里出现未戴口罩的帧数、统计某个时间段的人流量。这个思路不错,但要提前想好数据口径,否则容易被老师追问。一个常见做法是每隔N帧记录一次检测结果,用这个采样结果近似估计整体比例,并把抽样方式和近似误差说明清楚。

5.4 将检测封装成函数方便复用

如果后续要做图形界面或者更复杂的业务逻辑,建议不要直接在detect.py上改,而是把检测过程封装成一个独立函数。YOLOv5提供了可调用的API,大致逻辑如下:

import torch model = torch.hub.load('ultralytics/yolov5', 'custom', path='runs/train/mask_exp/weights/best.pt', force_reload=True) model.conf = 0.45 model.iou = 0.45 results = model('test.jpg') results.print() results.show() results.save()

torch.hub.load会自动加载模型结构和权重,模型返回的结果对象里包含pandas格式的DataFrame,可以直接读取每个框的坐标、置信度和类别。用这种方式的好处是灵活,你可以方便地接入Flask写一个Web接口,或者用Tkinter写一个桌面程序。对大作业来说,这算是一个加分项。

那么接口怎么设计?我建议做两个参数:conf(置信度阈值)和imgsz(输入尺寸),其余参数直接写默认值。接口返回时明确给出检测框的像素坐标、类别名和置信度,方便上层做展示和统计。

6. 实操中的常见问题与避坑指南

6.1 CUDA out of memory显存不足

最经典的问题,训练中途报“CUDA out of memory”。处理思路从低风险到高风险排列:先把batch size减半,比如从16降到8;如果还不行,把--img从640降到512;如果还不行,换yolov5n模型。尽量不要在一开始就换小模型,因为yolov5s的精度更适合作为课程项目展示。

还有一个容易被忽略的点:同时跑多个训练任务会互相占显存。训练前用nvidia-smi检查一下当前显存占用情况,看到别人遗留的进程,能清就清一下,不能清就换GPU编号。

6.2 loss不下降或过早平稳

loss不下降或者下降速度极慢,优先怀疑数据问题。检查labels目录下是否有空txt文件;检查图片和txt名称是否完全一致;yaml文件里的nc和names是否和标注匹配。如果数据没问题,再考虑学习率。

loss一开始在0.1层级波动,然后很久不降,有可能是标注框质量太差,比如很多框位置偏移或者包含大量背景。这种情况需要用可视化工具检查几张训练图片,把标注画出来看看是否贴合目标。YOLOv5官方没有直接提供画标注的工具,但可以用OpenCV写几行代码把txt转成矩形框画在图片上,检查前20张图片基本就能发现问题。

6.3 检测结果中类别混淆

训练结束后测试,发现“未戴口罩”经常被检成“戴口罩”,或者反过来,这多半是数据问题,不是模型问题。排查思路:检查数据集中两类图片的特征是否足够区分,比如戴布口罩、手捂嘴、口罩戴在下巴上这些情况是否都被标注成了正确的类别。如果标注时把“口罩没戴好”也统一标成“戴口罩”,模型就会学出错误规律。

处理方式有两种:一是把不清楚的样本从数据集中剔除,宁缺毋滥;二是把“口罩没戴好”单独作为第三类,这样模型不用勉强把中间状态归到两边,检测效果反而更稳。但会增加标注工作量,最后会不会高,仁者见仁,需要你自己权衡。

6.4 验证集mAP高、实际场景检测差

这就是过拟合的典型表现。模型把训练集的背景和特殊场景记住了,而不是真正学会人脸和口罩的特征。缓解办法:增加数据增强的强度、降低模型规模、增加训练样本多样性。采集一些不同光线、不同角度、不同表情的数据,往往比调参更有用。

还有一种情况是实际场景中的人脸与你训练集里的人脸差异过大,比如训练集都是正脸、实际检测时都是侧脸。这种情况即使加大增强强度也未必有用,最直接的方法是补充侧脸和低头数据。

6.5 推理速度慢怎么办

课程项目通常不需要极致的推理速度,但如果演示时卡顿明显,可以按顺序优化:把输入尺寸从640降到416或320,这是立竿见影的;换用TensorRT或ONNX Runtime做推理,速度能显著提升,但配置复杂度也上升;使用yolov5s或yolov5n模型,比大模型快很多。对作业来说,建议做到第一步就够了,后面的优化可以写进“后续改进方向”里,表明你思考过这个问题。

6.6 几个小坑速查

根据我的经验,还有几个细节容易让人头疼:torch.hub.load下载权重时网络超时,手动把权重文件放到指定目录即可解决;中文路径会导致读图失败,项目路径和文件名尽量不要出现中文;detect.py保存结果的目录会按exp、exp2、exp3递增命名,找不到文件时可以回去看看这个规律;如果用了GPU训练而CPU加载模型,要加map_location参数,否则会报权重复制错误。

我建议把这些坑直接写进实验报告“问题与解决”一节,老师看到这些真实调试记录,比空泛的“解决了技术难点”更有说服力,也更像一个自主完成的“高分项目”。

7. 答辩演示与项目扩展建议

到了答辩环节,重点是讲清楚“我做了什么”“为什么这样做”“效果如何”,而不是念PPT。演示顺序可以参考:先展示一张未戴口罩和戴口罩的检测效果对比图,再现场摄像头实时检测,最后展示训练曲线和指标。如果时间充裕,再补充说明你踩过哪些坑,这会让老师觉得你是真正在做项目,而不是在应付作业。

关于项目后续扩展,你可以提出几个方向,比如把模型导出为ONNX并部署到手机或嵌入式设备、添加人脸身份识别功能、统计某区域口罩佩戴率并做可视化报表、用KAIST等类似数据集验证模型的泛化能力。这些方向都不需要你现在就实现,但能证明你对目标检测的工程链路有整体认知。

最后再分享一个我个人的经验:这类项目最大的价值不在于把mAP从0.95提到0.96,而在于完整走通“数据标注-模型训练-评估-部署”这条链路。2000张图片、一个预训练模型、一次微调,看起来简单,但其中每一环都可能出问题。真正把这些细节经历一遍,你对深度学习落地的理解会扎实很多。做项目时不光盯着准确率几个数字,多留意那些让你卡住半小时的小问题,它们才是你答辩时最宝贵的素材。

本文还有配套的精品资源,点击获取

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

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

立即咨询