ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

YOLOv7口罩检测实战:从权重解析到训练部署全流程

YOLOv7口罩检测实战:从权重解析到训练部署全流程 简介面向目标检测开发者和计算机视觉学习者YOLOv7口罩检测资源包提供了可直接落地的完整方案。基于数千张标注图片训练而成权重文件mAP达到90%以上配置好YOLOv7环境后即可调用模型完成推理或迁移训练。压缩包共2000个文件约850.2MB核心内容以jpg图像、xml标注、txt标签为主同时包含py训练脚本、yaml配置文件、pt权重文件、ipynb示例文档以及runs目录下的PR曲线等结果图表目录结构清晰方便按需取用。已有1503人学习下载适合需要快速获得高精度口罩检测模型、用于毕设或实际项目的读者。借助该资源可省去从零训练的大量时间直接体验完整训练流程并基于现有权重进行数据扩充与调优。1. 口罩检测数据集和权重拆开来看比整个项目更有价值这套东西的目录并不花哨LICENSE、README、yolov7.pdf、common.py、loss.py、datasets.py、yolo.py、train.py、train_aux.py基本就是标准 YOLOv7 仓库里的训练侧文件。真正值钱的是随包提供的训练权重几千张口罩标注图跑完mAP 到 90% 以上runs 文件夹里还留了 PR 曲线和验证结果。这意味着你不需要从零攒数据、调 loss配置好环境先跑一次推理看到检测框能落在人脸上再决定要不要在自己的业务数据上微调。适合三类人做安全帽、口罩、反光衣等穿戴检测的工程同学刚接触 YOLO 想看懂 mAP 和 PR 曲线从哪来的学生以及想拿一个“能出数”的基线模型做迁移的算法从业者。2. YOLOv7 的工程骨架common.py、loss.py 与 train_aux.py 各管什么2.1 为什么这个项目仍值得用 YOLOv7YOLOv8 出来之后很多人会问为什么还用 YOLOv7。我保留它的原因很直接在小数据集上做穿戴类目标检测时YOLOv7 的 anchor 检测头和train_aux.py辅助训练机制更可控超参数都暴露在命令行里方便按项目去调。口罩检测属于人脸区域的小目标问题低分辨率下容易出现漏检而辅助头在训练阶段会给浅层特征多一重梯度约束等效于让模型更早看到“口罩边缘”这种细节。项目里给出的权重 mAP 到 90% 多说明用这套默认配置在几千张数据上已经能压住误检和漏检拿来做基线完全够用。2.2 common.pySPPCSPC 与 E-ELAN 的乐高盒common.py是模型结构的底层模块集合。口罩目标往往只有几十个像素骨干网络需要在不同感受野下保留上下文所以 SPPCSPC 这类多尺度池化模块会直接影响检测效果。下面是项目里 SPPCSPC 模块的简化样式代码里k(5,9,13)三个核分别覆盖不同范围class SPPCSPC(nn.Module): # 简化自 YOLOv7 的 common.pySPP 与 CSP 的组合模块 def __init__(self, c1, c2, e0.5, k(5, 9, 13)): super(SPPCSPC, self).__init__() c_ int(c2 * e) # 中间通道数e 控制宽度 self.cv1 Conv(c1, c_, 1, 1) self.cv2 Conv(c1, c_, 1, 1) self.cv3 Conv(c_, c_, 3, 1) self.cv4 Conv(c_, c_, 1, 1) self.m nn.ModuleList([ nn.MaxPool2d(kernel_sizex, stride1, paddingx // 2) for x in k ]) def forward(self, x): x1 self.cv1(x) # 主分支输入 x2 self.cv2(x) # 跨阶段分支 x3 self.cv3(x2) pooled [m(x3) for m in self.m] x3 torch.cat([x3] pooled [x2], dim1) return self.cv4(x3)逻辑说明c_控制中间特征宽度e0.5表示压缩一半通道减少后续拼接计算量。三个 MaxPool 的paddingx//2保证池化前后 H、W 不变所以cat时不需要担心尺寸对不上。口罩检测中小尺寸口罩主要靠 5×5 池化补充局部细节大尺寸口罩靠 13×13 池化保留面部上下文这也是 SPPCSPC 比普通 Bottleneck 更稳的原因。2.3 yolo.py 的 Detect 层如何决定 loss 计算yolo.py里实现的是检测头它同时服务训练和推理。训练时forward返回多尺度特征列表给loss.py推理时则输出压缩后的预测张量。下面是 Detect 层的剪影class Detect(nn.Module): def forward(self, x): # x 来自多个 down sample 层通常 80x80、40x40、20x20 ... # 推理时concat 所有 anchor 的输出为一个大张量 return x if self.training else (torch.cat(z, 1), x)说明torch.cat(z, 1)会把三个尺度的 anchor 预测拼成一个[batch, anchor_num * (nc 5), N]形状的张量后续 NMS 再从这个张量里解析坐标和类别。如果你改了nc这里输出的通道数会变所以换类别数后必须重新训练不能直接拿原权重推理。2.4 文件职责速查表文件核心职责什么时候需要改common.py基础卷积、SPPCSPC、E-ELAN 等模块调整骨干网络时yolo.pyDetect 检测头、anchor 编码改类别数、anchor 时loss.py主头损失计算包括 CIoU 与 BCE默认不动datasets.py标签加载、mosaic、增强改输入尺寸、类别映射时train.py主训练入口每轮项目调参train_aux.py带辅助头的训练脚本小数据集提升召回时2.5 train_aux.py 在 loss 上做了什么train_aux.py不是另起一套网络而是在原主干上多接一组浅层辅助头。训练时主头和辅助头共享 backboneloss.py里对辅助头的输出额外做一次加权损失反向传播时让浅层特征也获得清晰的梯度。这样在小数据集、大 batch 不稳时模型不容易在前期振荡。实际部署时辅助头不参与导出所以模型体积不会增加。我一般遇到口罩这类面部小目标会优先尝试train_aux.py如果只是做快速基线train.py就够。3. 配置环境后直接跑通 YOLOv7 口罩检测推理命令与参数调整3.1 先把官方仓库补全下载包里的文件以训练侧代码为主缺少detect.py和test.py。常见做法是先把 WongKinYiu 的官方 YOLOv7 仓库克隆下来再用下载包里的同名文件覆盖最后把训练好的权重放到weights/目录git clone https://github.com/WongKinYiu/yolov7.git cd yolov7 # 将下载包里的 common.py、loss.py、yolo.py、train.py 等覆盖进去 pip install -r requirements.txt这里说明一下为什么不直接单独跑train.py推理依赖detect.py验证依赖test.py这两个文件不在下载包里但和项目属于同一版本仓库覆盖后权重结构不会冲突。环境方面PyTorch 1.8 到 2.1 都能跑CUDA 11.x 以上更稳CPU 也可以推理只是速度会慢很多。3.2 单张图片的检测命令与参数含义检测命令如下python detect.py \ --weights weights/mask_yolov7.pt \ --source data/mask/test_images/01.jpg \ --conf 0.25 \ --iou 0.45 \ --project runs/detect \ --name mask_test \ --exist-ok命令里的几个参数可以根据实际场景调整参数作用使用建议--conf置信度阈值0.15~0.25 适合提高召回0.4 以上适合减少误检--iouNMS 的 IoU 阈值0.45 是通用值遮挡多时可降到 0.3--save-txt保存坐标 txt二次开发时建议打开--save-conf在 txt 里附带置信度配合--save-txt使用--deviceCPU 或 GPU 编号多卡时指定0,13.3 视频和摄像头场景口罩检测最终要落到监控视频里所以摄像头和视频流也是主要输入来源python detect.py \ --weights weights/mask_yolov7.pt \ --source 0 \ --conf 0.25 \ --view-img--source 0表示第一个摄像头--view-img会弹出预览窗口适合本地调试。如果在服务器上跑建议不加--view-img直接用默认结果保存到runs/detect/exp。视频推理时我一般再开--agnostic-nms把人脸框和口罩框做类别无关的 NMS避免同一张脸上出现重叠框。3.4 实时画面抖动怎么办detect.py本身是逐帧检测没有任何跟踪逻辑。如果你想部署到实时监控里常见做法是先把检测框送到 ByteTrack 或 DeepSORT 里做 ID 关联再用滑窗平均修正框位置。不要在推理阶段直接开--augment它虽然会提升一点召回但推理耗时翻几倍实时场景完全没法用。4. 从 runs 目录的 PR 曲线复验 mAP 90% 的真实性4.1 runs 文件夹里到底有哪些可看的东西训练和验证结束后runs 目录下会生成一批可视化文件。这个项目里提到的 PR 曲线我一般先看下面几个文件作用PR_curve.pngPrecision-Recall 曲线横轴 Recall纵轴 PrecisionP_curve.pngPrecision 随置信度变化的曲线R_curve.pngRecall 随置信度变化的曲线labels.jpg标注框中心点与宽高分布判断数据质量train_batch*.jpg训练输入图确认增强效果如果labels.jpg里中心点集中在画面中央说明标注有偏如果宽高分布出现大量接近 1.0 的点说明某张图的分辨率或标注单位可能出了问题。这个文件虽然不直接参与推理但能快速判断模型为何对某些角度的口罩检测不好。4.2 用 test.py 重新计算 mAP模型评估不能只看作者给出的数字最好自己在 val 集上复算一遍。YOLOv7 仓库里评估入口是test.pypython test.py \ --task val \ --data data/mask.yaml \ --weights weights/mask_yolov7.pt \ --batch 16 \ --conf 0.001 \ --iou 0.5 \ --project runs/val这里有两个关键细节--conf要设成 0.001而不是推理时常用的 0.25。因为 mAP 计算的是 PR 曲线下的面积需要积分到低置信度区间如果把置信度卡在 0.25等于人为砍掉曲线左侧部分mAP 会被低估。--iou 0.5表示 IoU 大于 0.5 就算检测正确这是 mAP0.5 的标准口径。输出一般长这样Class Images Instances P R mAP0.5 mAP0.5:0.95 all 500 1210 0.931 0.902 0.921 0.734只看mAP0.5会特别高但mAP0.5:0.95才是更严格的标准。如果后者明显低于前驱说明模型对框的位置不够精准比如口罩露出一半时框会偏。这个时候与其调模型不如先检查标注框是否贴合脸部边缘。4.3 怎么把 PR 曲线读成决策PR 曲线越贴近右上角越好。我在实际项目里会重点看 Recall 在 0.8 附近时 Precision 是否还保持 0.9 左右。如果曲线在低置信度处 Recall 拉高Precision 却掉到 0.5 以下说明模型有大量背景误检部署时应提高--conf。反过来如果曲线末端 Recall 只到 0.7说明数据里有一部分难样本完全没被模型学到要补数据或加强 mosaic 增强。5. 数据集转 YOLO 格式并用 train.py / train_aux.py 复现口罩检测模型5.1 YOLO 标注格式与目录划分YOLOv7 训练时需要 YOLO 格式的 txt 标注每行内容为类别id x_center y_center width height坐标值是归一化到 0~1 的小数。比如0 0.517 0.402 0.183 0.214 1 0.278 0.311 0.161 0.199第一行表示类别 0 的目标中心在图片横向 51.7%、纵向 40.2% 的位置宽高分别占 18.3% 和 21.4%。实际数据集目录结构要保持下面这样的对应关系data/mask/ images/train/ images/val/ labels/train/ labels/val/如果你手头是 VOC 或 COCO 格式的标注常见做法是先转成 YOLO txt再按图片和标签的基名一一对应。转换时注意类别 id 从 0 开始顺序必须和后面data/mask.yaml里names的顺序一致。5.2 mask.yaml 的配置项项目训练前需要准备 YOLOv7 格式的 yaml 文件# data/mask.yaml path: data/mask train: images/train val: images/val nc: 2 names: 0: face_with_mask 1: face_without_masknc表示类别数量names用列表或字典形式都可以。这里的顺序非常重要如果权重里训练时是“没戴口罩”为 id 0你却在 yaml 里把它写成“戴口罩”那么验证时 PR 曲线看起来会乱掉。遇到这种问题先去看labels.jpg里自动生成的类别统计确认标注 id 和 names 是否对齐。5.3 train.py 从头训练与微调命令复现或者重新训练时train.py是最常用的入口# 从头训练 python train.py \ --epochs 100 \ --batch-size 16 \ --img 640 \ --data data/mask.yaml \ --cfg cfg/training/yolov7.yaml \ --weights \ --name mask_yolov7 \ --device 0参数含义如下参数示例值说明--epochs100小数据集 100 足够数据多可到 200--batch-size16显存不够就降到 8会影响 BN 统计--img640训练尺寸推理时最好保持一致--cfgcfg/training/yolov7.yaml网络结构配置--weights空字符串表示从零训练--namemask_yolov7输出目录名实际生成runs/train/mask_yolov7如果要把现有口罩权重迁移到自己的数据集上把--weights改成权重文件路径并在train.py里设置--freeze冻结一部分 backbone 层python train.py \ --weights weights/mask_yolov7.pt \ --data data/mask.yaml \ --freeze 20 \ --epochs 50 \ --batch-size 16--freeze 20表示冻结前 20 层这样前几个 epoch 只更新检测头避免小数据量下 backbone 被带偏。5.4 什么时候换用 train_aux.py当你要处理的是“人脸比例小、口罩占人脸比例大”的场景train_aux.py会比train.py更容易把漏检拉下来python train_aux.py \ --data data/mask.yaml \ --cfg cfg/training/yolov7-e6e.yaml \ --batch-size 8 \ --img 1280 \ --weights weights/mask_yolov7.pt \ --name mask_aux说明train_aux.py在训练时会额外计算辅助头的 loss所以显存开销明显变大batch size 通常要减半。它适合数据集已经基本干净、你追求更高召回率的阶段。我先跑train.py拿一个收敛结果再把weights指向这个结果去跑train_aux.py收敛速度会比直接从零跑 aux 快很多。5.5 loss 不下降时的排查方向训练时如果 loss 长时间不动先看学习率是否太高导致梯度震荡其次是 mosaic 增强导致数据分布变化太大。YOLOv7 默认的 mosiac 在datasets.py里如果数据集只有几千张建议保留但把--cache-images打开把图片提前缓存到内存。另一个我常踩的坑是--workers设置过高容易卡在 dataloader 读取表现为 loss 迟迟不更新。6. 部署阶段容易翻车的四个细节尺寸、类别映射、显存与精度6.1 输入尺寸必须和训练尺寸对齐如果你训练时用--img 640推理时却用--img 1280短期看可能召回更高但口罩框位置会系统性偏移。YOLOv7 的 anchor 是按训练分辨率生成的改成更大输入后小目标确实更清晰但 anchor 分配和 NMS 结果都会轻微变化。所以部署前先固定输入尺寸再在验证集上跑一次test.py确认 mAP 没掉再上线。6.2 names 顺序错位是个隐形炸弹很多排错案例最后都查到同一个问题检测框画出来了但标签全对不上。原因是detect.py推理时不读取 yaml 里的 names而是在代码里写死了类别名而test.py里的 names 来自 data.yaml。如果两个地方不一致会出现训练时 mAP 90%线上结果却把“没戴口罩”标成“戴口罩”。我建议把类别名直接写进data/mask.yaml传给detect.py的--names参数保证推理和验证同一份映射。6.3 显存 OOM 不只是 batch 的问题训练时显存不足最常见的是--batch-size过大推荐从 8 开始用nvidia-smi观察显存余量再往上加。但还有个隐藏因素--img和--batch-size是按平方关系影响显存的640 升到 1280显存占用约增加四倍。另一种情况是train_aux.py的辅助头没有释放中间变量这属于正常开销只能减少 batch。推理时用半精度--half能显著降低显存python detect.py --weights weights/mask_yolov7.pt --source 0 --img 640 --half6.4 半精度提速与验收基准分离推理时开半精度很舒服显存减半、吞吐翻倍但模型输出的 PR 曲线和浮点结果会有 0.01 到 0.02 的波动。做项目验收时先不开--half用 FP32 跑一遍test.py记录基准 mAP再开半精度复测确认幅度可接受后再决定线上是否长期使用半精度。这样既能保住检测指标又能在监控场景里把帧率拉上去。验收时用 FP32 作为基准上线再开半精度是成本最低的稳定路线。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进