ARTICLE DETAIL

资讯详情

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

YOLOv5目标检测实战:从环境搭建到边缘部署的完整指南

YOLOv5目标检测实战:从环境搭建到边缘部署的完整指南 简介这份文档面向具备一定Python与计算机视觉基础的入门级研究人员和工程技术人员系统讲解YOLOv5目标检测框架的本地环境搭建与基本检测流程。内容从系统要求入手涵盖Windows、macOS、Linux三类操作系统支持、Python 3.6以上版本以及GPU加速所需的CUDA 10.2与cuDNN 7.6以上版本匹配并逐步介绍依赖库安装、官方源码获取、预训练模型下载与示例检测运行最后延伸至自定义数据集训练等进阶方向。资源包为单个docx文档约19KB结构紧凑便于按步骤对照操作。目前已有238人学习下载适合初次接触YOLOv5、希望快速跑通目标检测实例并理解环境部署整体思路的读者既可作为理论教学材料也可供实际工程项目参考建议参照每步指南并尝试自行调整实验条件以加深理解。1. YOLOv5 搭建与目标检测详解从环境到推理一条能跑通的路很多人第一次接触目标检测是从一段能框出图片里物体的演示代码开始的。YOLOv5 就是这类演示里出现频率最高的名字之一——它把训练、验证、推理、导出打包成一套脚本让一个没写过检测框架的人也能在半天内跑出第一张带框的图。但跑通 demo和训练自己的数据集之间隔着一堆细节环境版本、数据标注格式、超参数、显存、量化部署。这篇笔记按一线落地的顺序把 YOLOv5 搭建与目标检测的完整链路拆开讲先讲清它为什么这么设计再给能直接抄的命令和配置最后把踩过的坑摊开。适合刚入门想训自己数据集的人也适合已经会推理、准备往树莓派或 RK3568 这类边缘设备上搬的工程师。2. YOLOv5 的网络结构与选型为什么是它而不是别的检测器2.1 从网络结构图看懂 YOLOv5 的三段式设计YOLOv5 的网络结构图基本可以拆成三段Backbone、Neck、Head。Backbone 负责从原图里抽特征用的是 CSPDarknet 结构核心是 C3 模块和 SPPF 模块Neck 用 PANet 做多尺度特征融合把浅层的高分辨率特征和深层的强语义特征拼起来Head 是检测头在三个不同尺度的特征图上分别预测框。三个尺度的设计是理解 YOLOv5 的关键。输入 640×640 的图经过 8 倍、16 倍、32 倍下采样得到 80×80、40×40、20×20 三个特征图。80×80 负责小目标20×20 负责大目标。这就是为什么移动小目标检测、遥感目标检测这类任务里小目标召回率往往取决于 80×80 那一支的质量。C3 模块的作用是加深网络同时控制参数量它把输入分成两路一路经过若干 Bottleneck另一路直接短路最后 concat。SPPF 用不同尺寸的最大池化串联扩大感受野比 SPP 更快。这些模块名字在改网络结构时会反复出现建议对着结构图把每一层的输入输出通道数标一遍改起来才不慌。2.2 版本选型YOLOv5 的 n/s/m/l/x 怎么挑YOLOv5 官方给了五个尺寸n、s、m、l、x参数量和精度依次上升。选型不是越大越好要看你的部署目标和数据量。模型参数量级适用场景显存参考batch16, 640yolov5n最小树莓派、RK3568 等边缘设备约 2Gyolov5s小通用入门、快速验证约 4Gyolov5m中精度与速度平衡约 8Gyolov5l大服务器端、精度优先约 12Gyolov5x最大离线高精度场景约 16G我一般建议第一次训自己的数据集从 yolov5s 起步。原因是 s 收敛快、显存友好能让你在几小时内看到 loss 曲线和验证结果确认数据没问题之后再换 m 或 l。直接上 x 的常见后果是显存爆掉、训练一轮要几小时调参周期被拉长反而拖慢进度。如果目标是量化后部署到 RK3568 或树莓派 4B那从一开始就该选 n 或 s因为大模型量化后的精度损失和推理延迟都更难接受。边缘部署这条线模型尺寸的选择比训练技巧更影响最终能不能用。2.3 和 YOLOv11、Transformer 检测器的取舍现在目标检测领域还有 YOLOv11Ultralytics 系和基于 Transformer 的检测器。YOLOv11 在工程封装上更统一API 更简洁Transformer 检测器在长距离依赖和复杂场景上有优势但训练成本高、部署链路长。YOLOv5 的优势在于生态成熟网上能搜到的教程、预训练权重、部署案例最多遇到问题容易找到答案。对于适合 0 基础纯小白的入门需求或者需要快速把模型搬到 ROS 无人小车、锥桶检测这类具体场景YOLOv5 仍然是性价比最高的起点。选它不是因为最新而是因为踩坑时有人踩过。3. 环境搭建与最小推理把第一张带框的图跑出来3.1 环境配置Python、PyTorch、CUDA 的版本对齐环境是新手翻车最多的地方核心矛盾是 PyTorch 版本和 CUDA 版本必须匹配。常见做法是用 conda 建独立环境避免污染系统 Python。# 创建独立环境Python 版本建议 3.8 到 3.10 conda create -n yolov5 python3.9 -y conda activate yolov5 # 安装 PyTorch注意 CUDA 版本要和驱动匹配 # 下面这行对应 CUDA 11.8其他版本去 PyTorch 官网查对应命令 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 验证 GPU 是否可用 python -c import torch; print(torch.cuda.is_available())这段代码的逻辑是先隔离环境再装和显卡驱动匹配的 PyTorch最后验证。torch.cuda.is_available()返回 True 才说明 GPU 能被调用。如果返回 False先别急着改代码去查驱动版本和 CUDA 版本是否对得上这是最常见的黑匣子问题。参数说明Python 选 3.9 是因为它在 3.8 到 3.10 这个区间里兼容性最好太新或太旧都可能遇到某个依赖装不上。CUDA 版本不是越高越好要看你显卡驱动支持到哪个版本用nvidia-smi看右上角的 CUDA Version。3.2 拉取代码与安装依赖# 克隆仓库用你实际能访问的地址 git clone yolov5-repo-url cd yolov5 # 安装依赖-r 指定依赖文件 pip install -r requirements.txt依赖装完后如果遇到某个包版本冲突优先看 requirements.txt 里锁定的版本不要盲目升级。YOLOv5 对 numpy、opencv-python 这些包的版本比较敏感升级到最新反而可能报错。3.3 用预训练权重跑通最小推理# 下载预训练权重后对示例图片做推理 python detect.py --weights yolov5s.pt --source data/images/ --img-size 640 --conf-thres 0.25这条命令的含义--weights指定模型权重--source指定输入可以是图片、文件夹、视频、摄像头--img-size是推理分辨率--conf-thres是置信度阈值低于这个值的框会被过滤掉。参数怎么调--conf-thres默认 0.25检测框太多就调高漏检多就调低。--img-size越大精度越高但速度越慢边缘设备上通常降到 320 或 416。--source传0可以调摄像头实时检测这是验证推理速度最直接的方式。跑通之后结果默认存在runs/detect/exp目录下。看到带框的图说明环境、权重、推理链路全通了可以进入下一步。4. 训练自己的数据集标注、配置、启动与监控4.1 数据标注与 YOLO 格式转换YOLOv5 用的是 YOLO 格式标注每张图对应一个 txt 文件每行是一个目标格式为类别索引 中心x 中心y 宽 高后四个值都是相对图片宽高的归一化值0 到 1 之间。常见做法是用 labelImg 或 X-AnyLabeling 标注导出时选 YOLO 格式。如果手里是 VOC 的 xml 标注需要转换import xml.etree.ElementTree as ET import os # 把 VOC 的 xml 转成 YOLO 的 txt def convert_voc_to_yolo(xml_path, txt_path, classes): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) with open(txt_path, w) as f: for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) bbox obj.find(bndbox) # 计算归一化中心点和宽高 x_center (float(bbox.find(xmin).text) float(bbox.find(xmax).text)) / 2.0 / w y_center (float(bbox.find(ymin).text) float(bbox.find(ymax).text)) / 2.0 / h bw (float(bbox.find(xmax).text) - float(bbox.find(xmin).text)) / w bh (float(bbox.find(ymax).text) - float(bbox.find(ymin).text)) / h f.write(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}\n)逻辑说明先读图片宽高再把绝对坐标转成归一化的中心点和宽高。classes是类别名列表顺序必须和训练时的 data.yaml 一致否则类别会错位。参数上坐标保留 6 位小数足够归一化值超过 1 说明标注框超出图片边界需要检查。4.2 数据集目录结构与 data.yaml 配置YOLOv5 要求固定的目录结构dataset/ images/ train/ val/ labels/ train/ val/images 和 labels 下的文件名要一一对应只是扩展名不同。然后写 data.yaml# data.yaml path: ./dataset train: images/train val: images/val nc: 3 names: [person, car, cone]nc是类别数names是类别名列表顺序必须和标注时的索引一致。这里最容易翻车的是路径path是数据集根目录train和val是相对 path 的路径。如果训练时报找不到图片先检查这三个字段拼出来的绝对路径对不对。4.3 启动训练与关键超参数python train.py \ --data data.yaml \ --weights yolov5s.pt \ --img-size 640 \ --batch-size 16 \ --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml参数说明--weights用预训练权重做迁移学习比从零训收敛快得多这是新手最该用的一条。--batch-size受显存限制爆显存就往下调16 不行就 8、4。--epochs一般 100 到 300看 loss 曲线是否还在下降。--hyp指定超参数文件yolov5 超参数都在这个 yaml 里学习率、动量、权重衰减、数据增强强度都能改。训练过程中重点看几个指标box_loss、obj_loss、cls_loss 是否稳定下降mAP0.5 是否上升。如果 loss 震荡剧烈通常是学习率太大或 batch 太小如果 mAP 一直不涨可能是数据量不够或标注质量有问题。4.4 用 TensorBoard 监控训练过程tensorboard --logdir runs/train浏览器打开对应端口能看到 loss 曲线、mAP 曲线、学习率变化以及每个 epoch 的验证结果图。这个可视化是判断训练是否正常的后悔药——很多问题在曲线上比在日志里更容易看出来。比如验证 loss 开始上升而训练 loss 还在降就是过拟合该早停或加数据增强了。5. 避坑与排查训练和部署里最容易翻车的几件事5.1 显存爆掉CUDA out of memory现象训练启动几秒后报 CUDA out of memory或者跑到某个 batch 突然崩。原因batch-size 太大、img-size 太高、模型选得太大三者叠加超过显存上限。也可能是 dataloader 的 workers 太多导致内存占用叠加。解决先把 batch-size 减半还不行就把 img-size 从 640 降到 416 或 320。如果用的是 yolov5l/x换成 s。另外把--workers调小到 2 或 4减少数据加载进程的内存开销。显存碎片问题可以加--rect用矩形训练减少 padding。5.2 类别索引错位导致检测结果全错现象训练 loss 正常下降但推理时框的位置对、类别全错或者某些类别永远检测不到。原因data.yaml 里的 names 顺序和标注文件里的类别索引不一致。比如标注时 person 是 0、car 是 1但 yaml 里写反了。解决把 data.yaml 的 names 和标注生成时的 classes 列表逐行对齐检查。转换脚本里的 classes 顺序就是最终索引顺序改完要重新生成一遍标注。这个坑很隐蔽因为 loss 不会报错只有看推理结果才发现。5.3 小目标漏检严重现象大目标框得很准小目标远处行人、锥桶、遥感图像里的小车几乎检测不到。原因小目标在 80×80 特征图上只占几个像素经过多次下采样后特征几乎消失。默认的 anchor 尺寸也是按通用数据集设计的不一定匹配你的目标尺度。解决提高输入分辨率img-size 从 640 提到 1280让小目标占据更多像素用 k-means 重新聚类 anchor 尺寸让 anchor 匹配你的目标分布数据增强里开启 mosaic 和 copy-paste增加小目标的出现频率。如果还不行考虑加一个更高分辨率的检测头P2 层但这会显著增加计算量。5.4 训练 loss 不降或 mAP 卡住现象训练几十个 epochloss 几乎不动mAP 在很低的值徘徊。原因学习率设置不当、数据标注质量差、类别极度不平衡、预训练权重没加载成功。解决先确认预训练权重真的加载了启动日志里会打印加载的层数。然后检查标注用可视化脚本把标注框画到图上看有没有框错、漏标、类别标错。学习率方面用 hyp.scratch-low.yaml 起步如果 loss 完全不降可以适当调大 lr0。类别不平衡的话在 loss 里给稀有类别加权或者对稀有类别做过采样。5.5 部署到边缘设备后速度不达标现象在服务器上推理很快搬到树莓派 4B 或 RK3568 后帧率掉到个位数。原因边缘设备算力有限PyTorch 原生模型没有针对硬件优化FP32 精度计算量大。解决先导出成 ONNX再用目标平台的工具链量化成 INT8。RK3568 有 RKNN 工具链树莓派可以用 NCNN 或 ONNX Runtime。量化时要用一批代表性图片做校准否则精度掉得厉害。模型本身也要选 n 或 s别指望 l 能在边缘设备上实时跑。量化后精度如果掉太多试试混合量化对敏感层保留 FP16。6. 进阶技巧把训练好的模型真正用起来训练完拿到 best.pt 只是中间产物真正落地还要过导出和验证两关。我一般会先做一件事用验证集跑一遍完整评估拿到每个类别的 mAP 和混淆矩阵确认没有某个类别拖后腿。# 在验证集上评估输出每类精度 python val.py --weights runs/train/exp/weights/best.pt --data data.yaml --img-size 640 --task val这条命令会输出 mAP0.5、mAP0.5:0.95 以及每个类别的 AP。重点看混淆矩阵如果两个类别互相混淆严重说明特征区分度不够要么加数据要么在标注上把边界划清楚。导出 ONNX 是部署前的标准动作# 导出 ONNX指定 opset 和输入尺寸 python export.py --weights best.pt --include onnx --img-size 640 --opset 12--opset选 12 是因为它在各推理引擎里兼容性最好太新或太旧都可能遇到算子不支持。导出后一定要用 onnxruntime 跑一遍和 PyTorch 的输出对比确认数值误差在可接受范围内。这一步是很多人的盲区——导出了不等于能用验证过才算。如果目标是 RK3568导出 ONNX 之后还要过 RKNN 工具链转成 rknn 模型转换时注意输入 layout 和量化校准集的选择。树莓派 4B 上我一般用 NCNN它对 ARM 的优化比较成熟配合 INT8 量化能在 640 分辨率下跑到可用的帧率。最后说一个我自己的习惯每次训完模型不管指标多好看都拿一批真实场景的图不是验证集里的跑一遍人工看漏检和误检。验证集指标高但实际场景翻车的例子太多了尤其是光照变化、遮挡、小目标密集的场景。模型能不能用最终是场景说了算不是 mAP 说了算。希望帮到你。本文还有配套的精品资源点击获取
返回列表