ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv5口罩佩戴检测项目:从数据集校验到模型训练完整指南

YOLOv5口罩佩戴检测项目:从数据集校验到模型训练完整指南 简介目标检测是计算机视觉中的基础任务而YOLO系列凭借实时性与精度平衡成为工程落地首选。本文围绕口罩佩戴检测场景系统梳理了基于YOLOv5的完整项目实践从YOLO标注格式校验、数据划分到迁移学习参数配置、低显存训练技巧再到常见报错排查与模型评估。内容覆盖数据集检查、环境搭建、train.py核心参数、超参数调优等关键环节适合毕设与课程实战。通过该案例可快速掌握目标检测项目从数据到部署的标准化流程。1. YOLOv5口罩佩戴检测项目到手先看什么一份能直接跑、能交差的完整毕设包做毕设或者课程设计最怕的不是算法难而是东西拿到手发现缺数据、缺权重、缺标注跑不起来还得从头自己补。这个基于YOLOv5的口罩佩戴检测项目打包了数据集、源码、训练好的模型和标注文件不是那种只有代码没有数据的半成品。项目里有带标注的图片数据集、YOLOv5训练脚本、训练好的权重以及一个 tutorial.ipynb 帮你把流程串起来。你拿到手先不急着训练把目录结构和标注格式摸清楚再跑通推理后面训练和调参才有参照。适合正在做计算机相关专业毕设的学生也适合要交课程大作业、想练一遍目标检测完整流程的学习者。下面按我拆这种资源包的顺序一步步说清楚。2. 数据集与标注格式训练前先弄清楚这包数据能不能用很多下载包拿到手第一反应是赶紧跑代码结果训练到一半发现标签全是乱的。花半小时把数据集和标注格式核对一遍比跑通一个错误的结果省一天时间。2.1 资源包里到底有什么先看文件清单这个包里的内容包含这几类setup.cfg Dockerfile tutorial.ipynb logo.jpeg up.jpeg right.jpeg tmp_upload.jpegsetup.cfg 是 Python 项目配置文件Dockerfile 用来构建容器环境tutorial.ipynb 是带你走通全流程的 Jupyter Notebook。几个 jpeg 图片是样例图其中 up.jpeg、right.jpeg 这类命名其实是测试样本你可以直接拿它们验证模型检测效果。整体看下来包的组成是「源码 数据集 标注 训练好的权重 演示脚本」一套齐全。数据集部分一般会按 YOLO 惯例组织成 images 和 labels 两个目录训练集和验证集分开存放。你拿到包后第一件事就是把数据集根目录列出来看一遍dataset/ ├── images/ │ ├── train/ │ │ ├── img_001.jpg │ │ └── ... │ └── val/ │ ├── img_qlobal.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── img_001.txt │ │ └── ... │ └── val/ │ └── ... ├── classes.txt ├── train.txt └── val.txttrain.txt 和 val.txt 是图片路径列表YOLOv5 训练时通过这两个文件定位数据classes.txt 是类别名。如果包里的目录结构和上面有出入以实际解压后的为准但核心逻辑一样每张图片对应一个同名 txt 标注文件标注文件里每行是一个目标。这一步确认清楚了后面训练指令里的 data yaml 才能指对路径。2.2 YOLO txt 标注格式与校验方法YOLOv5 用的是归一化的 txt 格式每行代表一个目标字段顺序固定为类别ID 中心点x 中心点y 宽度 高度。前四个数值都是相对于图片宽高的比例值域在 0 到 1 之间。口罩佩戴检测一般分两类佩戴mask和未佩戴nomask所以类别ID 就是 0 或 1。我习惯拿到标注先写一段脚本快速校验看有没有越界、格式错乱、类别超范围的问题。打开终端跑下面这段import os def check_labels(label_dir, image_dir, class_count2): bad_files [] for f in os.listdir(label_dir): if not f.endswith(.txt): continue path os.path.join(label_dir, f) with open(path, r) as fp: lines fp.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: bad_files.append((f, 字段数不为5)) continue cls_id int(parts[0]) vals list(map(float, parts[1:])) if cls_id class_count or cls_id 0: bad_files.append((f, f类别ID越界:{cls_id})) if any(v 0 or v 1 for v in vals): bad_files.append((f, 坐标不在0-1范围内)) if bad_files: print(发现异常:) for item in bad_files: print(item) else: print(标注格式检查通过) if __name__ __main__: check_labels(dataset/labels/train, dataset/images/train)这段代码按五字段规则逐行解析标注文件先检查字段数量再检查类别 ID 是否超过类别总数口罩检测两类所以传 2最后检查归一化坐标是否落在 0 到 1 之间。注意如果碰到空行不能直接报错空行可能是标注工具生成的残留直接跳过比报错更符合实际场景。我在检查时加了过滤逻辑只对非空行做校验。还有一类常见问题是图片和标注文件对不上号有图片没标注或者有标注没图片。这种问题训练时不会立刻报错但会影响 mAP 计算。校验脚本里可以再加一步对比 image_dir 和 label_dir 的文件名集合找出差集。处理方式就是补标注或者删掉孤儿文件。2.3 类别文件与数据划分YOLOv5 训练时通过 data yaml 文件指定路径和类别名你必须保证 classes.txt 里的类别顺序和标注文件里的 ID 一一对应。mask 在前、nomask 在后那 ID 0 就是 maskID 1 就是 nomask。顺序错了模型也能训练但预测出来的标签永远是反的这种翻车很难排查所以我建议第一时间打开 classes.txt 确认。数据划分建议按训练集:验证集 9:1 或 8:1 来分口罩检测数据集量级通常在几千到一两万张不等。如果你拿到的是完整包里面应该已经分好了 train/val如果只有全部图片你自己划分时用随机分配但要保证同一场景的相似图片不全落在训练集或验证集。我用的是固定随机种子划分避免复现时结果漂移。参数上训练集比例设 0.9 时yaml 文件里 train 路径指到 train 目录val 路径指到 val 目录test 可留空。3. 环境搭建与代码结构YOLOv5环境配置的两条路环境配置是新人最容易卡住的环节卡点通常不是代码本身而是 PyTorch、CUDA、torchvision 三者版本没对齐。这里我给出两条可走通的路线conda 本地安装和 Docker 容器化安装。3.1 conda 环境与依赖安装建议用 conda 建独立环境避免把系统 Python 环境搞乱。Python 版本选 3.8 左右比较稳YOLOv5 官方对 3.7 到 3.10 都兼容但 3.8 踩坑最少。conda create -n yolov5_mask python3.8 -y conda activate yolov5_mask cd yolov5-mask-detection pip install -r requirements.txtrequirements.txt 里核心依赖包括 torch、torchvision、opencv-python、numpy、matplotlib、pyyaml、tqdm 等。重点提醒一句pip 默认安装的 torch 是 CPU 版还是 GPU 版取决于你机器上的 CUDA 环境。如果你有 NVIDIA 显卡建议先用 nvidia-smi 查 CUDA 版本再按对应版本装 GPU 版 torch命令是 pip install torch torchvision --index-url 加对应 CUDA 的下载源。这样能省掉后面训练时遇到的设备不可用问题。安装完成后验证一下环境是否正常python -c import torch; print(torch.__version__, torch.cuda.is_available())输出里 cuda.is_available() 如果是 False说明要么没装 GPU 版 torch要么驱动没对上后面训练只能走 CPU速度会慢到怀疑人生。这一行验证命令值得养成习惯每次换环境都跑一遍。3.2 Dockerfile 方式不想污染本地的备选路线如果你不想在本地装一堆依赖包里自带的 Dockerfile 可以构建一个跑 YOLOv5 的容器。Docker 方式的好处是环境隔离坏了直接删容器重建适合 GPU 服务器上多人共用环境的情况。构建和启动命令如下docker build -t yolov5_mask . docker run --gpus all -it --rm \ -v $(pwd)/dataset:/workspace/dataset \ -v $(pwd)/runs:/workspace/runs \ yolov5_mask bash-v 参数把宿主机的 dataset 和 runs 目录挂载进容器训练产物直接落在宿主机上容器删了也不丢数据。--gpus all 是让容器使用宿主机 GPU前提是宿主机安装了 nvidia-container-toolkit。如果容器里跑 detect 时报 CUDA 不可用先查宿主机上 nvidia-container-toolkit 是否装好再查容器内 nvidia-smi 是否有输出。镜像构建时要注意基础镜像的 PyTorch 版本和宿主机驱动兼容性。常见做法是在 Dockerfile 里固定 torch 版本号而不是用 latest这样后面复现训练结果不会因为依赖升级产生偏差。3.3 tutorial.ipynb 是入口先跑通推理再训练这个包里 tutorial.ipynb 是给你串流程用的建议第一步先跑它。Notebook 里通常包含了加载模型、读取图片、执行推理、绘制检测框这几步。先把推理跑通确认训练好的权重没坏再考虑要不要重新训练。我打开 notebook 后的操作顺序是先看每个 cell 的代码确认它调用的是哪个权重文件、读的是哪张图片然后逐个 cell 执行。如果你在 Jupyter 环境里执行前先确认 kernel 选的是刚才建的 conda 环境否则会出现 torch 没安装这种低级报错。推理跑通后顺带用同一张图跑两次一次是原有权重一次是随机初始化权重对比检测结果。这个对比能直观体现训练好的模型和没训练模型的差别做毕设答辩展示时也很好用能证明你的实验过程真实有效。4. 训练自己的口罩数据集从train.py到超参数调优推理跑通只是热身真正的重头戏是训练。训练这一层决定了你最终模型的 mAP 和检测速度也决定了答辩时能不能拿出漂亮的曲线图。4.1 数据集 yaml 配置YOLOv5 训练入口是 train.py但它不直接读图片路径而是读一个 data yaml 文件。在包的 data 目录下找到或新建 mask.yaml内容如下train: dataset/images/train val: dataset/images/val nc: 2 names: [mask, nomask]train 和 val 字段指向图片目录YOLOv5 会自动去同名 labels 目录找标注文件。你写成 labels 路径是没用的它只认 images 路径这点容易搞错。nc 是类别数names 必须和标注 ID 顺序一致顺序反了模型照样收敛但预测结果的语义标签是错的。路径建议写相对路径这样换机器不用改 yaml。如果你把项目整体放在某个目录下train.py 的工作目录就是这个包的根目录相对路径最稳妥。4.2 train.py 参数详解与低显存设定训练命令我一般这样写python train.py \ --data mask.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0 \ --workers 4 \ --hyp hyp.scratch-low.yaml \ --name mask_exp1参数含义说明--data 指定数据集 yaml--weights 指定初始权重用预训练权重做迁移学习能大幅缩短收敛时间--img 是训练时输入图片尺寸640 是 YOLOv5 默认值--batch 是批大小16 在 8GB 显存的显卡上可以跑--epochs 100 对口罩检测这种少类别任务足够收敛--workers 是数据加载进程数--hyp 是超参数文件后面细说--name 是实验名输出会放在 runs/train/name 目录下。如果你的显卡显存只有 4GB 甚至更低需要做几处调整。常见做法是把 batch 降到 8 或 4把 img 从 640 降到 480把 workers 设为 0。workers 设为 0 是因为 Windows 系统下多进程数据加载偶尔会卡死设 0 最稳缺点是训练时 CPU 加载数据稍慢但总比中断强。参数调整后命令如下python train.py \ --data mask.yaml \ --weights yolov5s.pt \ --img 480 \ --batch 8 \ --epochs 100 \ --device 0 \ --workers 0显存不够时最重要的经验是优先降 batch 而不是降 img。img 降太多会丢失小目标检测精度口罩这种中等尺寸目标影响不大但如果你还想检测人脸的细枝末节就别低于 480。batch 降了之后如果显存还有余量可以考虑开启梯度累积等价于增大 batch 但显存占用不变。4.3 迁移学习与超参数选择YOLOv5 提供了多个预训练模型从 s、m、l、x 依次变大。口罩检测属于少类别简单任务yolov5s.pt 是效率和精度最均衡的选择训练速度快部署也方便。如果追求更高精度且显存充足换 yolov5m.pt但推理速度会慢一些。训练过程中的超参数在一个 yaml 文件里常见的 hyp.scratch-low.yaml 适合初学者里面的核心参数包括参数典型值作用lr00.01初始学习率太大损失震荡太小收敛慢lrf0.01最终学习率与初始学习率的比值momentum0.937SGD 动量加速收敛并稳定方向weight_decay0.0005L2 正则化防过拟合warmup_epochs3.0预热轮数前几轮用低学习率稳定训练box0.05边框损失权重cls0.5分类损失权重新手不推荐一上来就大改超参数。先按默认值训练一轮看 loss 曲线和 mAP 曲线如果 loss 下降不够快再调 lr0。我常用的调法是把 lr0 从 0.01 调到 0.005因为数据集小的时候学习率太大容易在最优解附近震荡。weight_decay 如果要调也只动一个量级上下改大了模型可能欠拟合。迁移学习下有个细节weights 传 yolov5s.pt 时模型会自动冻结部分骨干层训练一段时间后如果精度上不去可以删掉 runs/train/name/weights/last.pt 再从头训或者取消冻结层直接全量微调。YOLOv5 的 train.py 里 freeze 参数默认是 0表示不冻结但如果是加载官方预训练权重前几轮仍会有 warmup 机制帮模型稳定。训练完成后模型保存在 runs/train/exp/weights/best.pt 和 last.pt。best.pt 是验证集上表现最好的权重last.pt 是最后一轮的权重。做毕设演示、写论文、做系统集成都只用 best.pt这是第一个该记住的路径。5. 常见问题排查训练翻车和推理报错的五个血泪坑我拿这个包实际跑了一遍把最容易遇到的坑按现象、原因、解决整理出来。每条都是真踩过的按顺序看能少走弯路。5.1 训练直接崩溃CUDA out of memory现象训练刚开始几十步终端弹出 RuntimeError: CUDA out of memory程序中断。原因显存不够。口罩检测数据集虽然不大但 batch 16 加 img 640 在 6GB 显存卡上就是极限边缘再叠加 workers 多进程开数据显存峰值就会爆掉。还有可能是你同时开着多个 Jupyter notebook 内核占显存。解决先 nvidia-smi 看显存占用把不用的进程结束掉。然后把 batch 降到 8img 降到 480workers 设 0。如果还要继续训练加 --device 0 明确指定显卡避免 YOLOv5 在双显卡机器上默认选到集成显卡或已占用的卡。5.2 训练卡在初始化wandb 报错或长时间无响应现象train.py 启动后一直卡在 Weights Biases 相关日志或者弹出需要登录 wandb 的提示训练进度不动。原因YOLOv5 默认集成了 wandb 日志功能第一次运行时会尝试联网初始化。网络环境不好的时候会一直等甚至报 Connection error。解决训练命令加 --wandb_off 或 --project runs/train 参数禁用 wandb。命令行里直接写python train.py ... --wandb_off这样所有日志只写到本地 runs 目录不影响训练流程。很多人以为卡在数据集加载其实是 wandb 在等网络。5.3 标签文件报错Label class exceeds classes现象训练启动时报错 ValueError: Invalid label class / Label class 2 exceeds classes 2。原因标注文件里的类别ID 最大是 2但 classes.txt 只定义了 2 个类ID 范围只能是 0 和 1。这个情况通常是标注工具导出时类别序号从 1 开始或者整理标注时混入了其他类别的文件。解决用前面第 2.2 节的校验脚本扫一遍 labels 目录找出越界文件。如果那个文件的类别确实是新类别加到 names 里并修改 nc如果是误标直接删掉那一行然后重新生成 train.txt 路径列表。5.4 训练了 100 轮mAP0.5 还是 0.3 以下现象训练过程不报错loss 下降也正常但 val 跑出来的 mAP0.5 始终低于 0.5检测框乱飘。原因最常见的是数据集本身有大量误标注比如口罩区域标得过大把额头也框进去了或者标注框不贴边。另一个常见原因是数据划分时随机种子导致某一类图片全部进了验证集模型没见过自然检不出来。解决打开几张训练图片用 OpenCV 画框核对标注是否贴合目标。检查 train 和 val 里 mask 和 nomask 的类别分布比例两集类别占比应该接近。如果有明显偏差重新划分数据并按固定随机种子生成再训练一次。5.5 Docker 里跑推理GPU 识别不了现象在容器里执行 detect.py提示 Device not available 或 CUDA error但宿主机上 nvidia-smi 正常。原因容器缺少 GPU runtime。docker run 时没加 --gpus all或者宿主机没装 nvidia-container-toolkit容器内根本没有 NVIDIA 驱动映射。解决宿主机装好 nvidia-container-toolkit 后启动容器必须加 --gpus all。已启动的容器退出后重新用正确参数启动。如果你在 Dockerfile 阶段就装好了 CUDA 相关依赖这一步通常不会有问题排查顺序是先宿主后容器别一上来就重装驱动。5.6 补充一个隐蔽问题中文路径导致加载失败现象代码不报错但训练时图片加载总跳过一部分loss 曲线异常验证指标和推理结果对不上。原因Windows 下路径含中文或空格OpenCV 和部分 Python 库对非 ASCII 路径支持不完全导致图片读取失败或标注文件找不到。解决整个项目路径用纯英文不要出现「项目」「毕设」这类中文目录名。这个是所有下载包里最容易忽略但影响最大的一环尤其毕设文件经常放在桌面中文文件夹下。改完路径后重新启动训练你会发现一切正常了。6. 最后一步用 tutorial.ipynb 验证模型把流程固化下来训练完不是结束还得有一套快速验证流程。我通常直接用这个包里的 tutorial.ipynb 完成推理验证和指标评估两步。推理验证命令python detect.py \ --weights runs/train/mask_exp1/weights/best.pt \ --source dataset/images/val/ \ --conf-thres 0.5 \ --iou-thres 0.45 \ --save-txt--conf-thres 是置信度阈值0.5 是常规设置检不出框就往下调--iou-thres 是 NMS 的 IoU 阈值0.45 适合口罩这类重叠较少的场景如果画面里多人密集适当调到 0.5 减少误抑制。--source 可以指向图片目录或单张图片也可以指视频文件或摄像头设备号做完毕设演示时用摄像头实时检测会很加分。--save-txt 可以把检测结果保存成 txt 文件量化分析误检漏检时用。指标评估跑一条命令python val.py \ --data mask.yaml \ --weights runs/train/mask_exp1/weights/best.pt \ --batch 16 \ --conf-thres 0.001 \ --iou-thres 0.6验证集评估会输出 precision、recall、mAP0.5、mAP0.5:0.95 四项核心指标。口罩佩戴检测场景mAP0.5 在 0.9 以上基本算可用0.95 指标在 0.7 左右已不错。答辩或报告里贴这张输出表比任何文字说明都直观。验证通过后如果你想做成一个可交付的小工具导出成 ONNX 格式然后用 ONNXRuntime 推理是常见做法便于部署到 CPU 环境python export.py \ --weights runs/train/mask_exp1/weights/best.pt \ --include onnx \ --opset 12我个人的习惯是每拿到一套这种打包资源先在 tutorial.ipynb 里把推理跑通再训练最后用 val.py 出一份指标存档。这类找到 best.pt 的过程已经成了一套路子项目做完之后把训练日志、评估结果和目录结构整理好交上去基本不用返工。这个流程里我踩过的最大一个坑就是拿到资源直接开训练浪费一晚上才发现数据集标注有问题。从那以后我每次训练前都强制走一遍标注校验再动 train.py这个习惯帮我省了很多返工时间希望帮到你。本文还有配套的精品资源点击获取
返回列表