ARTICLE DETAIL

资讯详情

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

YOLOv5反光服与安全帽检测工程包:从推理到训练全流程

YOLOv5反光服与安全帽检测工程包:从推理到训练全流程 简介这份资源面向计算机视觉初学者与工地安全监控开发者提供一套围绕YOLOv5构建的安全装备检测项目覆盖反光服、安全帽及施工人员穿戴识别等场景可用于训练模型判断作业人员是否规范佩戴防护装备。压缩包共47个文件约16.25MB包含16个Python脚本、14个YAML配置、6张示例图片以及权重文件best.pt、训练与推理脚本、shell启动脚本和说明文档结构上分为数据配置、模型定义、训练与检测入口等模块便于直接复现和二次开发。目前已有387人学习下载。借助现成的权重与脚本读者可快速跑通训练与推理流程理解数据集标注与配置方式并在此基础上扩展防护鞋、手套等更多安全装备的检测为智能安全监管应用提供可落地的参考方案。1. 反光服与安全帽检测一份能直接跑通的 YOLOv5 工程包工地安全监控这个场景最怕的就是“模型训出来好看落地全是误报”。我手上这份reflective-clothes-detect-yolov5-master压缩包解决的就是这个痛点——它不是单纯丢给你一堆图片的数据集而是一套已经配好best.pt权重、train.py、detect.py、voc_label_Re.py的完整工程。你拿到手解压完就能用detect.py跑推理看result目录里那几张re_pred.jpg、test02.jpg的检测效果。它适合两类人一是想快速验证反光服/安全帽检测可行性的算法工程师二是需要给施工人员佩戴检测项目找基线代码的开发者。核心关键词就三个反光服检测数据集、安全帽检测、YOLOv5 训练自己的数据集。别急着改网络结构先把这份工程跑通比什么都强。2. 拆包看结构从hubconf.py到voc_label_Re.py的工程逻辑2.1 目录里到底放了什么哪些文件先别动解压后你会看到一堆熟悉的名字models、utils、data、weights还有train.py、test.py、detect.py、hubconf.py、requirements.txt、train.sh。这套结构是 YOLOv5 的标准布局但作者做了针对性裁剪。weights目录下的best.pt是已经训练好的反光服安全帽检测权重你不需要重新训练就能直接推理。data目录里藏着数据集配置和voc_label_Re.py这个脚本是把 VOC 格式的 XML 标注转成 YOLO 需要的 txt 格式名字里的Re大概率指 reflective说明作者针对反光服类别做过标签映射调整。我一般会先看README_ZN.md和README_EN.md确认作者有没有写特殊依赖。requirements.txt里通常锁定了torch、torchvision、opencv-python、numpy这些基础库但 YOLOv5 对版本敏感尤其是torch和 CUDA 的匹配。如果你机器上已经装了其他版本的 PyTorch别直接pip install -r先建个虚拟环境。train.sh是训练启动脚本里面一般写好了--data、--cfg、--weights、--batch-size这些参数但作者可能用了绝对路径你得改成自己的路径。tutorial.ipynb是个 Jupyter Notebook适合快速验证推理流程但生产环境还是用detect.py更稳。result目录里的re_pred.jpg、test02.jpg、test05.jpg、ali_guangdong.jpg是作者跑出来的效果图你可以拿这几张图先跑一遍detect.py对比输出是否一致这是验证环境是否配对的快捷方法。2.2 用voc_label_Re.py把标注转成 YOLO 格式YOLOv5 训练需要每张图片对应一个.txt文件每行格式是class_id x_center y_center width height坐标都要归一化到 0~1。如果你拿到的原始数据是 VOC 的 XML就得用voc_label_Re.py转换。这个脚本通常放在data目录下核心逻辑是遍历Annotations文件夹里的 XML解析object节点提取name和bndbox然后按类别映射表转成数字 ID。# voc_label_Re.py 核心转换逻辑示意 import xml.etree.ElementTree as ET import os # 类别映射反光服和安全帽的类别名必须和 data.yaml 里一致 classes [reflective_clothes, helmet, person] def convert_annotation(xml_file, output_dir, img_w, img_h): tree ET.parse(xml_file) root tree.getroot() txt_name os.path.splitext(os.path.basename(xml_file))[0] .txt with open(os.path.join(output_dir, txt_name), w) as f: for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in classes: continue cls_id classes.index(cls_name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) # 归一化并转为中心点宽高 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h f.write(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n)这段代码的关键参数是classes列表顺序必须和data.yaml里的names完全一致否则训练出来的模型会把反光服识别成安全帽。img_w和img_h要从对应的图片文件读取不能硬编码因为数据集里图片尺寸可能不统一。转换完成后你还需要生成train.txt和val.txt里面每行是图片的绝对路径。常见做法是用glob遍历images目录按 8:2 划分训练集和验证集。提示转换前先备份原始 XMLvoc_label_Re.py如果写错了类别映射重新跑一遍会覆盖旧 txt没有后悔药。2.3 用detect.py跑通第一张推理图环境配好后先别急着训练用detect.py验证权重和依赖是否正常。命令很简单python detect.py --weights weights/best.pt --source result/test02.jpg --img-size 640 --conf-thres 0.4--weights指向best.pt--source可以是单张图、文件夹或摄像头编号。--img-size 640是推理分辨率和训练时保持一致效果最好。--conf-thres 0.4是置信度阈值低于这个值的框会被过滤掉。跑完后输出默认在runs/detect/exp下你可以打开图片看框的位置和标签。如果框全错或者一个框都没有先检查data.yaml里的类别数是否和best.pt匹配再看--img-size是否和训练时一致。我见过有人用 1280 的图去跑 640 训练的权重小目标全漏这就是参数没对齐的典型翻车。3. 训练自己的反光服数据集从train.sh到超参调整3.1 改data.yaml和train.sh里的四个关键参数当你有了自己的反光服和安全帽标注数据第一步是复制一份data.yaml改路径。data.yaml里通常有train、val、nc、names四个字段。train和val填你生成的train.txt和val.txt的绝对路径nc是类别数names是类别名列表。注意nc必须等于len(names)多一个少一个都会报错。train.sh里一般长这样python train.py --data data/data.yaml --cfg models/yolov5s.yaml --weights weights/yolov5s.pt --batch-size 16 --epochs 100 --img-size 640--cfg指定网络结构yolov5s是最小的速度快但精度低yolov5m、yolov5l依次变大。如果你数据量只有几千张yolov5s够用如果反光服在远处很小建议上yolov5m并把--img-size提到 1280。--weights这里填的是预训练权重不是best.pt用 COCO 预训练权重做迁移学习收敛更快。--batch-size根据显存调8G 显存跑yolov5s加 640 分辨率16 基本是上限。--epochs100 起步如果 loss 还在降就继续加。注意train.sh里的路径如果是作者机器上的绝对路径直接跑会报File not found全部改成相对路径或你自己的绝对路径。3.2 训练过程中的 loss 曲线怎么看什么时候该停YOLOv5 训练会输出box_loss、obj_loss、cls_loss三个值。box_loss是边界框回归损失obj_loss是目标置信度损失cls_loss是分类损失。正常情况下三个 loss 都应该是下降趋势如果obj_loss先降后升说明过拟合了赶紧停。cls_loss居高不下通常是类别不平衡反光服样本远多于安全帽样本可以在data.yaml里加class_weights或者对安全帽做 oversampling。我一般会看runs/train/exp下的results.png里面画了 loss 和 mAP 曲线。mAP0.5在 0.85 以上且稳定就可以考虑停止。如果mAP0.5震荡厉害把学习率调小YOLOv5 默认用余弦退火初始学习率--lr0 0.01你可以降到0.001试试。另外--patience参数控制早停轮数默认 50意思是 50 轮 mAP 没提升就停小数据集可以设成 20省时间。3.3 用test.py做验证集评估别只看训练 loss训练完必须用test.py在验证集上跑一遍命令python test.py --weights runs/train/exp/weights/best.pt --data data/data.yaml --img-size 640 --batch-size 16输出会给出mAP0.5、mAP0.5:0.95、precision、recall。反光服检测这个场景recall比precision更重要因为漏检一个没穿反光服的人比误检一个穿了的人风险大得多。如果recall低于 0.8把--conf-thres从 0.25 降到 0.1 再测看能不能把漏检捞回来。test.py还会生成PR_curve.png和confusion_matrix.png混淆矩阵能直接告诉你反光服被误判成安全帽的次数如果这个数很大说明两个类别的特征区分度不够得回去检查标注是否准确。4. 避坑与排查五个让工程跑不起来的常见问题4.1 解压后best.pt加载报UnpicklingError现象torch.load时报UnpicklingError或EOFError。原因压缩包在传输过程中损坏或者用了不兼容的解压工具。项目里那个如果解压失败请用ara软件解压.txt就是作者留的提示。解决换用 7-Zip 或 WinRAR 重新解压解压后对比best.pt的文件大小如果只有几 KB 肯定是坏的需要重新获取压缩包。4.2voc_label_Re.py跑完train.txt里路径全是反斜杠现象Windows 下生成的train.txt每行路径带\Linux 训练时找不到文件。原因os.path.join在 Windows 下默认用反斜杠。解决在脚本里把路径统一替换成正斜杠或者用pathlib.Path的as_posix()方法。更稳妥的做法是生成相对路径训练时用--data指定根目录。4.3 训练时CUDA out of memory但显存明明够现象batch-size设成 8 还是 OOMnvidia-smi看显存没满。原因YOLOv5 默认开启多尺度训练--multi-scale每轮图片尺寸随机变化峰值显存比固定尺寸高。解决加--no-multi-scale关掉或者把--img-size降到 512。另外--workers设太大也会占显存设成 4 或 8 就行。4.4 推理结果里反光服框全是重叠的现象detect.py输出一张图上同一个反光服有十几个框。原因--conf-thres太低或者--iou-thres太高。解决--conf-thres提到 0.5--iou-thres从默认 0.45 降到 0.3NMS 会合并重叠框。如果还不行检查best.pt是不是在过拟合的数据集上训的模型对某些纹理过度敏感。4.5test.py报AssertionError: No labels found现象验证集评估时提示找不到标签。原因val.txt里的图片路径对应的.txt标签文件不存在或者标签文件名和图片名不一致。解决检查val.txt每行路径把.jpg换成.txt看文件是否存在。YOLOv5 要求标签文件和图片文件同名同目录只是扩展名不同。如果标签在单独文件夹需要在data.yaml里配labels路径。5. 进阶技巧用hubconf.py做模型集成与阈值调优hubconf.py这个文件很多人直接忽略但它其实是 YOLOv5 的 TorchHub 入口能让你用torch.hub.load一行代码加载模型。对于反光服检测这种需要快速部署到边缘设备的场景这个入口比detect.py更灵活。你可以把best.pt和另一个安全帽专用模型做集成取两个模型输出的并集再统一做 NMS。具体做法是分别推理把结果转成统一的[x1, y1, x2, y2, conf, cls]格式拼在一起后调torchvision.ops.nms。import torch from torchvision.ops import nms # 假设 model1 和 model2 是两个不同权重的 YOLOv5 模型 results1 model1(img) results2 model2(img) # 提取框和分数拼接 boxes torch.cat([results1.xyxy[0][:, :4], results2.xyxy[0][:, :4]], dim0) scores torch.cat([results1.xyxy[0][:, 4], results2.xyxy[0][:, 4]], dim0) # 统一 NMSiou 阈值设 0.5 keep nms(boxes, scores, 0.5) final_boxes boxes[keep]这个技巧在反光服和安全帽同时检测时特别有用因为两个类别的目标尺度差异大单模型容易顾此失彼。集成后mAP通常能涨 2~3 个点代价是推理时间翻倍适合对实时性要求不高的后台分析。另一个进阶点是阈值调优。detect.py的--conf-thres是全局阈值但反光服和安全帽的最优阈值可能不同。你可以在detect.py里改后处理逻辑对cls0反光服用 0.35对cls1安全帽用 0.5。具体是在non_max_suppression函数里加一个per_class_conf参数按类别过滤。这个改动不大但能明显降低安全帽的误报。从那以后我每次拿到新的检测工程都强制先跑一遍detect.py看result目录的对比图再动train.py。这个习惯帮我省了至少三次重训的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表