YOLOv5实战指南:从环境搭建到自定义训练与部署
简介:这份文档面向具备一定Python与计算机视觉基础的入门级研究人员和工程技术人员,系统讲解YOLOv5目标检测框架的本地环境搭建与基本使用流程。内容从系统要求入手,明确Windows、macOS或Linux平台及Python 3.6以上版本的前提,并针对GPU加速场景说明CUDA 10.2与cuDNN 7.6以上的版本匹配要求,随后依次覆盖依赖库安装、官方源码获取、预训练模型下载与示例检测运行,最后简要引介基于自定义数据集的模型训练与参数调整等进阶方向。资源包共1个docx文件,约19KB,以图文步骤形式组织,便于按章节对照操作。已有238人学习,适合初次接触YOLOv5、希望快速跑通检测实例并了解定制训练思路的读者,既可作为理论教学材料,也能为实际工程项目提供环境部署与排错参考。
1. 从一张工地照片说起:YOLOv5 到底能帮你干什么
上周有个做安防的朋友甩给我一张工地监控截图,问我能不能把画面里没戴安全帽的人框出来。我第一反应不是去翻论文,而是打开终端敲了条python detect.py——这就是 YOLOv5 这类实时目标检测框架最实在的价值:你不需要从卷积核开始推导,装好环境、喂进图片或视频,它就能把「哪里有什么」用框和标签告诉你。YOLOv5 基于 PyTorch 实现,主打推理速度和精度之间的平衡,yolov5s这种小模型在普通显卡甚至 CPU 上都能跑出可用的帧率,适合做原型验证、课程设计、产线质检的初筛,也适合想入门计算机视觉、把「目标检测」四个字从概念变成能跑起来的工程的开发者。这份教程式的项目资源,核心就是带你从零把环境搭起来、跑通第一次检测,再往自定义数据集训练的方向走一步。如果你手里有 Python 基础、想快速看到检测结果而不是先啃三个月理论,这篇拆解就是给你准备的。
2. 环境搭建:Python、PyTorch 与 CUDA 三件套怎么配不翻车
2.1 先想清楚用 CPU 还是 GPU,这决定了后面所有命令
很多人一上来就照着教程装 CUDA,结果发现自己机器根本没有独立显卡,或者驱动版本对不上,卡在torch.cuda.is_available()返回False上半天。我的建议是先把硬件摸清楚:打开终端跑nvidia-smi,能正常输出显卡型号和驱动版本,才考虑 GPU 路线;报「command not found」或者驱动版本太老,就先老老实实走 CPU 版本,把流程跑通再说。YOLOv5 的推理在 CPU 上跑单张图片完全可接受,只是训练会慢到让人怀疑人生。
项目正文给的最低要求是 Python 3.6+、CUDA 10.2+、cuDNN 7.6+,这是底线不是推荐值。实际动手时我一般会把 Python 锁在 3.8,原因是这个版本对 PyTorch 各版本的兼容面最宽,很多预编译 wheel 都覆盖到了。用 conda 建独立环境是血泪经验——目标检测的依赖链又长又杂,直接装在系统 Python 里,哪天另一个项目要旧版 numpy 就会打架。
# 创建并激活独立环境,Python 版本锁 3.8 conda create --name yolov5_env python=3.8 -y conda activate yolov5_env # 验证当前解释器路径,确认没串到系统环境 which python # Windows 下用 where python这段命令的关键在最后一步验证:which python输出的路径里应该带yolov5_env,如果还是系统路径,说明激活没生效,后面装的包全白装。-y是跳过确认提示,批量脚本里常用。
2.2 装 PyTorch:版本对齐比装最新版重要
PyTorch 和 CUDA 的版本是一对一绑定的,装错组合的典型症状是import torch直接报undefined symbol或者 CUDA 相关的一长串错误。项目正文里给的pip install torch torchvision是最简写法,实际我更推荐去 PyTorch 官方给的版本选择器里按你的 CUDA 版本生成命令,因为纯pip install拉到的可能是 CPU 版或者和驱动不匹配的版本。
# GPU 路线示例:CUDA 11.3 对应的 PyTorch 组合 pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cu113 # CPU 路线:明确装 cpuonly 版本,避免误拉 GPU 包 pip install torch torchvision cpuonly -f https://download.pytorch.org/whl/torch_stable.html装完必须做一次自检,这一步别省:
import torch print(torch.__version__) # 看版本号是否符合预期 print(torch.cuda.is_available()) # GPU 路线应为 True print(torch.cuda.get_device_name(0)) # 打印显卡型号,确认识别到了torch.cuda.is_available()返回False而你有显卡,八成是驱动太旧或者装成了 CPU 版,先pip uninstall torch torchvision再按对应 CUDA 版本重装,别在环境里反复叠包,越叠越乱。
2.3 拉源码、装依赖:requirements.txt 里藏着版本地雷
拿到 YOLOv5 源码后,进目录装依赖是标准动作,但requirements.txt里往往钉死了某些包的版本,和你环境里已有的包冲突是常事。
git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt如果安装过程中出现某个包版本冲突的红色报错,不要无脑--force-reinstall,先看清楚是哪个包、被谁依赖。常见做法是单独pip install 包名==版本号把它钉到 requirements 要求的版本,再重跑一次安装命令。装完后跑一句python -c "import torch, cv2, numpy; print('ok')",能打印 ok 说明核心依赖链通了。
提示:整个环境搭建阶段,每装完一层就做一次导入自检,比全部装完再排查要省一半时间。出问题时你至少知道是哪一层引入的。
3. 跑通第一次检测:detect.py 的参数逐个拆开看
3.1 预训练权重从哪来、放哪去
YOLOv5 官方提供yolov5n/s/m/l/x几个规格,字母越大模型越重、精度越高、速度越慢。项目正文用的是yolov5s.pt,这是性价比最均衡的一档,适合第一次跑通。权重文件下载下来放在项目根目录即可,detect.py会按--weights给的路径去找,找不到会尝试自动下载。
# 下载预训练权重(有浏览器的话直接下也行,放到 yolov5 根目录) wget https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.pt权重文件本质是一个序列化的模型状态字典加配置,几十 MB 量级。放错目录是最常见的低级错误——脚本报「找不到权重」,先ls一下确认文件真的在当前工作目录,而不是在下载文件夹里躺着。
3.2 detect.py 的五个核心参数,改哪个影响什么
跑检测的命令本身不长,但每个参数背后都对应一个实际效果,理解它们比背命令有用得多。
python detect.py \ --weights yolov5s.pt \ --source test.jpg \ --img 416 \ --conf 0.4 \ --iou 0.5| 参数 | 作用 | 调大后的效果 | 调小后的效果 |
|---|---|---|---|
--weights | 指定模型权重路径 | 换成更大模型精度升、速度降 | 换成更小模型反之 |
--source | 输入源,图片/视频/目录/摄像头 | — | — |
--img | 推理时输入图像尺寸 | 小目标更容易检出,显存占用升 | 速度快,小目标易漏 |
--conf | 置信度阈值 | 框变少、误检少、漏检多 | 框变多、召回高、误检多 |
--iou | NMS 的 IoU 阈值 | 重叠框保留多,密集场景更友好 | 重叠框合并狠,密集目标易丢 |
--conf和--iou是最值得动手试的两个。同一个场景,conf从 0.4 调到 0.25,你会看到原本没框出来的模糊目标冒出来,同时背景误检也变多;iou在人群、货架这种目标挨得近的画面里影响尤其明显,调太低会把并排的两个目标合并成一个。我的习惯是先固定img=640跑一版看整体效果,再针对漏检或误检单独调conf。
3.3 结果去哪看:runs/detect 目录的结构
检测跑完,结果默认落在runs/detect/exp下,再跑一次会生成exp2、exp3,不会覆盖。目录里通常有带框的可视化图片或视频,以及一个记录检测框坐标、类别、置信度的文本文件。想批量处理一整个文件夹的图片,把--source指向目录即可;想接摄像头实时看效果,--source 0就是默认摄像头。
# 批量检测整个目录,结果按原文件名保存 python detect.py --weights yolov5s.pt --source ./images --img 640 --conf 0.3 # 保存检测框的 txt 结果,方便后续做统计或二次处理 python detect.py --weights yolov5s.pt --source test.jpg --save-txt --save-conf--save-txt输出的每行格式是类别索引 中心x 中心y 宽 高,坐标是归一化到 0~1 的,这个格式和训练时用的标注格式一致,所以你可以直接拿检测结果去做数据回流,这是二次开发里很实用的一环。
4. 训练自己的数据集:从标注格式到 train.py 的完整链路
4.1 数据集目录和 YOLO 标注格式,错一个字段就白标
自定义训练的第一步不是改代码,是把数据整理成 YOLOv5 认的格式。它要求每张图片配一个同名.txt标注文件,每行一个目标,格式是class_id x_center y_center width height,后四个值都是相对图片宽高归一化后的 0~1 小数。用标注工具导出时选 YOLO 格式,别选成 VOC 的 XML,否则要额外写转换脚本。
目录结构一般长这样:
dataset/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 └── labels/ ├── train/ # 与 train 图片同名的 txt └── val/图片和标注必须同名同层级对应,images/train/a.jpg对应labels/train/a.txt。我见过最常见的翻车是标注文件里存了绝对像素坐标而不是归一化值,训练 loss 一直不降,排查半天才发现是格式问题。
4.2 data.yaml 和模型 yaml:两个配置文件各管什么
YOLOv5 训练需要两份配置:一份描述数据集,一份描述模型结构。数据集配置data.yaml大概长这样:
# data.yaml:告诉训练脚本数据在哪、有几类、类名是什么 train: ./dataset/images/train val: ./dataset/images/val nc: 3 # 类别数量,必须和标注里的 class_id 范围一致 names: ['helmet', 'person', 'vehicle'] # 类名顺序对应 class_id 0/1/2nc和names是最容易出错的地方:nc写 3 但标注里出现了class_id 3,训练直接报索引越界;names顺序和标注时的类别顺序不一致,模型学出来的类别会整体错位。模型配置则是在models/yolov5s.yaml里把nc改成你的类别数,其余结构参数一般不动。
# models/yolov5s.yaml 片段:只改 nc,其余保持默认 nc: 3 # 从默认的 80 改成自己的类别数 depth_multiple: 0.33 width_multiple: 0.504.3 train.py 的关键参数与训练过程怎么看
配置齐了就能开训。项目正文给的命令是--img 416 --batch 16 --epochs 300,这套参数在小数据集上够用,但batch要根据显存调,显存不够就往下砍到 8 甚至 4,报CUDA out of memory时优先降batch再降img。
python train.py \ --img 416 \ --batch 16 \ --epochs 300 \ --data data.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --cache--weights yolov5s.pt是迁移学习的关键,从预训练权重起步比从零训练收敛快得多,小数据集上尤其明显。--cache把图片缓存进内存加速读取,数据集不大时开着很香,数据集几个 G 以上就要掂量内存够不够。训练过程中终端会打印每一轮的 box loss、obj loss、cls loss 和 mAP,重点盯 mAP@0.5 有没有在涨、loss 有没有异常震荡。训练完最优权重落在runs/train/exp/weights/best.pt,拿它替换检测命令里的--weights就能验证效果。
注意:训练集和验证集的图片千万别有重叠,否则 mAP 虚高,上线就露馅。划分时按 8:2 左右随机分,别按文件名顺序切,容易把同一场景的图全分到一边。
5. 避坑与排查:那些让新手卡一整晚的典型问题
5.1 现象:torch.cuda.is_available()一直是 False
原因通常是三选一:装成了 CPU 版 PyTorch、显卡驱动版本低于 CUDA 要求、conda 环境里混进了多个 torch。解决顺序是先pip list | grep torch看装的是哪个版本,再nvidia-smi看驱动支持的 CUDA 上限,最后按匹配版本重装。别在原有环境上反复pip install覆盖,先卸载干净再装。
5.2 现象:检测结果框一大堆,全是误检
原因多半是--conf设太低,或者输入图片分辨率远高于--img导致缩放后目标特征丢失。解决是把conf回调到 0.4~0.5 区间,同时把img提到 640 再试。如果只在特定类别上误检多,那是训练数据里该类负样本不足,得补数据而不是调参。
5.3 现象:训练 loss 不降,mAP 一直是 0
原因集中在标注格式:坐标没归一化、class_id从 1 开始而不是 0、标注文件和图片没对上号。解决是抽几张图用脚本把标注框画回原图上看,框位置对不对一眼便知。这个可视化检查我每次开新数据集都做,能省掉大量瞎调参的时间。
5.4 现象:CUDA out of memory训练中断
原因是batch或img超过显存容量。解决是按「先降 batch 到 8,再降 img 到 320」的顺序试,还不行就换更小的模型规格(yolov5n)。另外--cache在数据集大时会吃大量内存,显存报错时也可以先关掉它排除干扰。
5.5 现象:依赖安装报版本冲突,装一半失败
原因是requirements.txt钉的版本和你环境里已有的包打架。解决是看报错里具体是哪个包,单独pip install 包名==指定版本钉住,再重跑安装。实在理不清就重建一个干净 conda 环境,比在脏环境里修修补补快得多。
6. 二次开发:把 detect.py 改成能嵌进业务的服务
跑通检测只是起点,真正落地时你多半不会满足于命令行跑图片。我一般会先把detect.py里的推理逻辑抽出来,做成一个可被调用的函数,再包一层 HTTP 接口,这样业务系统传图进来、拿 JSON 结果出去,链路就通了。核心是复用 YOLOv5 的模型加载和推理接口,而不是重写检测算法。
import torch from PIL import Image # 加载本地权重,只加载一次,别在每次请求里重复加载 model = torch.hub.load('./yolov5', 'custom', path='best.pt', source='local') model.conf = 0.4 # 置信度阈值,等价于命令行的 --conf model.iou = 0.5 # NMS 阈值,等价于 --iou def detect(image_path): img = Image.open(image_path) results = model(img, size=640) # size 等价于 --img # pandas 格式便于筛选和统计,xyxy 是左上右下坐标 df = results.pandas().xyxy[0] return df[['name', 'confidence', 'xmin', 'ymin', 'xmax', 'ymax']].to_dict('records')这段代码的关键点有三个:模型只加载一次并常驻,避免每次请求都读盘;conf和iou挂在模型对象上,和命令行参数一一对应;返回结构用 pandas 转字典,方便直接序列化成 JSON。改造时最容易忽略的是输入图片的尺寸和通道数,业务传来的图可能是 RGBA 或超大分辨率,喂进去前统一转 RGB 并做尺寸约束,能避免一堆莫名其妙的报错。
验证改造是否成功,我的习惯是拿同一张图分别走命令行和接口,比对两边输出的框数量和坐标,误差在可接受范围内才算对齐。从那以后我每次把检测脚本改成服务,都强制走一遍这个「命令行 vs 接口」的对照,因为推理参数在两条链路上不一致导致的偏差,肉眼根本看不出来,只有对数字才现原形。希望这套拆解能帮你少走几个弯路,把 YOLOv5 真正跑进自己的项目里。
本文还有配套的精品资源,点击获取