资讯动态

YOLOV5口罩检测实战:数据集、训练与部署全流程

发布时间:2026/9/28 7:15:14 来源:尧图企业网站定制
简介这份资源是面向计算机相关专业学生与项目实战学习者的YOLOV5口罩检测完整方案可直接用于毕业设计、课程设计或期末大作业。内容涵盖标注好的数据集、可运行的项目代码、训练好的模型权重以及配套配置文件帮助读者跳过繁琐的数据采集与标注环节快速复现并理解目标检测全流程。压缩包共149个文件约922.84MB以yaml配置、py源码、pyc缓存、jpg与jpeg样本图片为主另含pt模型权重、sh脚本、md说明文档、Dockerfile及ipynb教程等覆盖训练、推理与部署各环节。该资源经导师指导并获评审98分已有193人学习适合作为高分项目参考。读者可据此掌握数据组织、模型训练、权重调用与结果可视化等关键技能并在此基础上进行二次开发或功能扩展。1. 从一份口罩检测数据集说起YOLOV5 项目到底能省掉哪些重复劳动如果你正在准备毕业设计或期末大作业选题是「口罩佩戴检测」大概率已经体会过那种从零开始的窒息感找数据、清洗、标注、配环境、调参、训练、部署每一步都能卡住三天。而一份打包好的「YOLOV5 口罩检测数据集 代码 训练好的模型 标注好的数据」本质上就是把这条链路上最耗时的前 70% 直接跳过让你把精力放在真正能体现工作量的地方——模型对比、场景优化、界面集成或者部署验证。这个方向适合三类人一是时间紧、只想跑通完整流程拿到结果的同学二是想在此基础上做改进换主干、加注意力、做轻量化但不想被数据准备拖住的人三是需要快速验证某个部署方案比如树莓派、边缘盒子是否可行的工程师。核心价值不在于「有现成模型」而在于「有标注好的数据 可复现的训练代码」这两样才是你能改、能写进论文、能讲清楚的东西。下面按「数据怎么用 → 环境怎么配 → 训练怎么跑 → 坑在哪 → 怎么验证」的顺序拆开讲。2. 口罩检测数据集的结构、标注格式与 YOLOV5 适配2.1 拿到数据集先看什么目录结构与类别定义一份能直接用于 YOLOV5 的口罩检测数据集常见目录结构是images/和labels/平行放置再按train/val/test划分。标注格式通常是 YOLO 的 txt每行class_id x_center y_center width height坐标全部归一化到 0~1。类别一般只有两类mask和no_mask有些数据集会多一个mask_incorrect露鼻子或下巴这个第三类对实际场景很有用但也会让训练难度上升。先别急着训练用下面这段脚本统计一下每类样本数和标注框尺寸分布心里有数再动手import os from collections import Counter label_dir dataset/labels/train class_counter Counter() box_sizes [] for txt in os.listdir(label_dir): if not txt.endswith(.txt): continue with open(os.path.join(label_dir, txt)) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cid int(parts[0]) w, h float(parts[3]), float(parts[4]) class_counter[cid] 1 box_sizes.append((w, h)) print(类别分布:, class_counter) if box_sizes: avg_w sum(b[0] for b in box_sizes) / len(box_sizes) avg_h sum(b[1] for b in box_sizes) / len(box_sizes) print(f平均框尺寸(归一化): w{avg_w:.3f}, h{avg_h:.3f})逻辑说明遍历标签文件统计每个类别的框数量同时计算平均宽高。参数上label_dir换成你自己的路径即可。如果发现某一类样本数不到另一类的三分之一训练时就要考虑用--weights做类别加权或者在数据增强里对少样本类做复制粘贴增强。平均框尺寸偏小比如 w、h 都小于 0.1说明大量目标是小脸或远距离这时候输入分辨率不能设太低后面会讲。2.2 从原始标注到 YOLOV5 可训练格式转换与划分脚本很多数据集给的是 VOC 的 XML 或者 LabelMe 的 JSON需要转成 YOLO txt。下面这个脚本处理 VOC 格式同时按 8:1:1 划分训练集、验证集和测试集import os, random, shutil import xml.etree.ElementTree as ET voc_img_dir raw/images voc_ann_dir raw/annotations out_root dataset classes [mask, no_mask, mask_incorrect] def convert(xml_path, img_w, img_h): tree ET.parse(xml_path) lines [] for obj in tree.findall(object): name obj.find(name).text if name not in classes: continue cid classes.index(name) bnd obj.find(bndbox) x1 float(bnd.find(xmin).text) y1 float(bnd.find(ymin).text) x2 float(bnd.find(xmax).text) y2 float(bnd.find(ymax).text) xc (x1 x2) / 2 / img_w yc (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h lines.append(f{cid} {xc:.6f} {yc:.6f} {w:.6f} {h:.6f}) return lines # 假设图片尺寸已知实际可用 PIL 读取 IMG_W, IMG_H 640, 640 all_files [f for f in os.listdir(voc_ann_dir) if f.endswith(.xml)] random.shuffle(all_files) n len(all_files) train_files all_files[:int(n*0.8)] val_files all_files[int(n*0.8):int(n*0.9)] test_files all_files[int(n*0.9):] for split, files in [(train, train_files), (val, val_files), (test, test_files)]: os.makedirs(f{out_root}/images/{split}, exist_okTrue) os.makedirs(f{out_root}/labels/{split}, exist_okTrue) for xml_name in files: stem xml_name.replace(.xml, ) img_src os.path.join(voc_img_dir, stem .jpg) if not os.path.exists(img_src): continue shutil.copy(img_src, f{out_root}/images/{split}/{stem}.jpg) lines convert(os.path.join(voc_ann_dir, xml_name), IMG_W, IMG_H) with open(f{out_root}/labels/{split}/{stem}.txt, w) as f: f.write(\n.join(lines))逻辑说明先解析 XML 拿到边界框再归一化写入 txt。参数上classes列表顺序必须和后续data.yaml里的names完全一致否则类别会错位。IMG_W、IMG_H如果每张图不一样要用 PIL 逐张读取不能写死。划分比例 8:1:1 是常见做法如果数据量少于 2000 张建议改成 7:2:1 或者做交叉验证否则验证集太小mAP 波动会很大。2.3 data.yaml 的写法与三个容易写错的字段YOLOV5 训练靠一个data.yaml指定数据路径和类别。常见写法path: ../dataset train: images/train val: images/val test: images/test nc: 3 names: [mask, no_mask, mask_incorrect]三个容易翻车的地方第一path是相对路径时相对的是你执行训练命令时所在的目录不是 yaml 文件所在目录很多人在这里绕晕第二nc必须等于names长度多一个少一个都会在训练启动时报错第三names里不要用中文或空格否则某些版本的 dataloader 会解析异常。改完 yaml 后用python -c import yaml; print(yaml.safe_load(open(data.yaml)))确认能正常加载。3. YOLOV5 环境配置与训练从 conda 到第一个 best.pt3.1 用 conda 建环境版本组合与依赖安装顺序YOLOV5 对 PyTorch 和 CUDA 的版本比较敏感尤其是你要用 GPU 训练的时候。我一般这样建环境conda create -n yolov5_mask python3.8 -y conda activate yolov5_mask # 先装 PyTorch根据你的 CUDA 版本选对应命令 pip install torch1.12.1cu113 torchvision0.13.1cu113 -f https://download.pytorch.org/whl/torch_stable.html # 再装 YOLOV5 依赖 pip install -r requirements.txt逻辑说明先建独立环境避免和系统 Python 冲突PyTorch 版本要和 CUDA 驱动匹配。参数上cu113表示 CUDA 11.3如果你机器是 CUDA 11.6 就换成cu116。装完用python -c import torch; print(torch.cuda.is_available())验证输出True才算 GPU 可用。如果输出False先别急着训练检查驱动版本和 PyTorch 是否匹配否则会退到 CPU 训练速度差几十倍。3.2 训练命令与关键超参数epochs、batch-size、imgsz 怎么定启动训练的命令本身不复杂难的是参数怎么设。一个我常用的起手配置python train.py \ --data data/mask.yaml \ --weights yolov5s.pt \ --epochs 100 \ --batch-size 16 \ --imgsz 640 \ --device 0 \ --workers 4 \ --project runs/train \ --name mask_exp1逻辑说明--weights yolov5s.pt表示从预训练权重开始微调比从头训练收敛快很多尤其数据量不大时。--epochs 100对口罩检测这种二到三分类任务通常够用但如果验证集 mAP 在 80 轮后还在涨可以加到 150。--batch-size 16是 8G 显存下的安全值显存够可以上 32不够就降到 8 并配合--accumulate做梯度累积。--imgsz 640是默认值但如果你的数据集里小目标多前面统计平均框尺寸小于 0.1可以提到 800 或 960代价是显存和训练时间增加。--workers在 Windows 上建议设 0 或 2设大了容易卡在 dataloader。训练过程中重点看三个指标box_loss是否稳定下降、mAP0.5是否在涨、val/val_loss有没有过早反弹。如果box_loss震荡厉害先把学习率降一半试试如果mAP卡在某个值不动检查标注里有没有大量漏标或错标。3.3 用训练好的模型做推理单张图片和批量验证训练结束后runs/train/mask_exp1/weights/best.pt就是最优权重。单张推理python detect.py \ --weights runs/train/mask_exp1/weights/best.pt \ --source test_images/ \ --img-size 640 \ --conf-thres 0.4 \ --iou-thres 0.45 \ --save-txt逻辑说明--source可以是单张图、文件夹或视频。--conf-thres 0.4表示置信度低于 0.4 的框不显示口罩检测里这个值可以适当调低到 0.3避免漏检--iou-thres 0.45控制 NMS 合并阈值如果发现同一个人脸出现多个框就调低到 0.4。--save-txt会把检测结果按 YOLO 格式存下来方便你后续做统计或和标注对比。批量验证时用val.py跑一遍测试集看mAP0.5和mAP0.5:0.95两个数前者反映能不能检出后者反映框得准不准。4. 口罩检测训练里最容易翻车的四个地方4.1 现象训练 loss 正常下降但 mAP 一直是 0原因最常见的是data.yaml里names顺序和标注文件里的class_id对不上导致模型学的是错位类别其次是验证集路径写错val.py实际读的是空目录。解决先用 2.1 的统计脚本确认每类样本数再打开一个标注 txt 和data.yaml逐行核对类别索引。如果路径有疑问把val改成绝对路径试一次。4.2 现象推理时框位置整体偏移或框特别大原因标注时归一化用错了分母比如用 640 去归一化一张 1280 宽的图导致所有框缩小一半。解决回到 2.2 的转换脚本确认IMG_W、IMG_H是每张图的实际尺寸。如果原始数据已经是 YOLO 格式用脚本反归一化画到图上肉眼检查几个样本。4.3 现象训练到一半显存爆了报 CUDA out of memory原因batch-size设太大或者imgsz提高后没有同步降 batch。解决先把--batch-size减半如果还爆就把--imgsz从 640 降到 512。另外--workers设太大也会占用额外内存Windows 上尤其明显改成 0 或 2 再试。如果这些都不行用--accumulate 2配合小 batch 模拟大 batch 效果。4.4 现象模型在测试集上表现很好但实际场景里漏检严重原因数据集场景太单一比如全是室内正脸实际场景有侧脸、遮挡、暗光。解决这不是调参能解决的要么补充实际场景的标注数据做微调要么在推理时降低--conf-thres并配合图像预处理比如直方图均衡化。如果只是做毕业设计可以在论文里把「场景泛化能力不足」作为局限性写出来同时给出改进方向这比硬调参更诚实也更有说服力。5. 验证模型是否真的可用三个比 mAP 更实在的检查方法5.1 用混淆矩阵看类别混淆方向YOLOV5 训练结束后会在runs/train/mask_exp1/下生成confusion_matrix.png。重点看mask和no_mask之间的误判比例。如果no_mask被大量判成mask说明模型对「不戴口罩」的特征学得不够可能是这类样本太少或者标注里把「口罩拉到下巴」也标成了mask。这时候要么补数据要么在推理时对no_mask类单独调低置信度阈值。5.2 用 PR 曲线找最佳置信度阈值PR_curve.png里每条曲线对应一个类别曲线上的点表示不同置信度下的精确率和召回率。实际部署时如果你更怕漏检比如安检场景就选召回率高的点对应的阈值如果更怕误报就选精确率高的点。这个阈值不一定等于训练时的默认 0.25我一般会在验证集上跑一遍val.py --conf-thres 0.1然后手动看不同阈值下的 F1 分数选最高的那个。5.3 用真实场景视频做一次端到端测试mAP 再高也要用一段实际场景的视频跑一遍detect.py看帧率、看漏检、看误报。如果帧率低于 15 FPS考虑换yolov5n或做 TensorRT 加速如果漏检集中在某个角度考虑在数据增强里加旋转。这一步没有捷径但能帮你发现所有离线指标看不出来的问题。5.4 一个我常用的习惯先跑通再优化我带过的几个做口罩检测的同学最常见的翻车不是模型不行而是一上来就想改网络结构、加注意力模块结果环境没配好、数据没对齐卡了一周连 baseline 都没跑出来。我的习惯是先用现成权重和默认参数跑通一遍完整流程拿到一个能看的 mAP再在这个基础上做改进。这样你至少有一个对照基准改了什么、涨了多少都能说清楚。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑