简介这份文档面向具备一定Python与计算机视觉基础的入门级研究人员和工程技术人员系统讲解YOLOv5目标检测框架的本地环境搭建与基本使用流程。内容从系统要求切入明确Windows、macOS或Linux平台及Python 3.6以上版本的前提并针对GPU加速场景说明CUDA 10.2与cuDNN 7.6以上的版本匹配要求随后依次覆盖依赖库安装、官方源码获取、预训练模型下载与示例检测运行最后简要引介基于自定义数据集的模型训练与参数调整思路兼顾理论教学与工程实践参考。资源包共1个docx文件约19KB以图文步骤形式组织便于按章节对照操作。目前已有238人学习适合初次接触YOLOv5、希望快速跑通检测流程并理解环境配置要点的读者也可作为课程实验或项目搭建的辅助材料。1. 从一张工地监控截图说起YOLOv5 到底能帮你干什么上周有个做安防的朋友甩给我一张截图画面里安全帽、反光背心、人员、叉车全被框了出来每个框上还带着类别和置信度。他问我这套东西部署要多少钱我说你先别谈钱本地一台带独显的机器就能跑起来代码是开源的模型权重直接下。这就是 YOLOv5 的日常——实时目标检测里落地最广的一档框架PyTorch 生态训练和推理脚本都给你写好了改几行参数就能从“检测 COCO 八十类”切到“检测你自己的几类目标”。这份资源是一套完整的搭建与检测实操教程从环境准备、依赖安装、拉源码、跑通第一张图一直讲到用自定义数据集训练。适合刚接触计算机视觉、手里有 Python 基础、想把目标检测真正跑起来而不是停在论文里的开发者和工程技术人员。下面我按自己拆项目的顺序把每一步的命令、参数和容易翻车的地方讲透。2. 环境与依赖把 PyTorch、CUDA、cuDNN 这条链先理顺2.1 为什么先建虚拟环境而不是直接 pip目标检测项目的依赖又重又杂torch、torchvision、opencv、numpy、matplotlib 版本之间互相咬直接装在系统 Python 里跑崩一次想回退都难。我一般第一步就是隔离环境Anaconda 装不装都行装了省事不装用 venv 也一样。教程里给的是 conda 方案Python 定在 3.8这个版本对 PyTorch 各版本兼容性最好别贪新上 3.11、3.12有些轮子还没跟上。# 创建名为 yolov5_env 的独立环境指定 Python 3.8 conda create --name yolov5_env python3.8 # 激活环境后续所有命令都在这个环境里执行 conda activate yolov5_env--name后面是环境名随便起但建议带上项目标识机器上环境多了不容易混。激活之后命令行前面会出现(yolov5_env)看到这个前缀才说明你进对环境了。这一步看着简单实际最常见的错误是“装完依赖发现装到了 base 环境”原因就是忘了激活或者中途开了新终端。养成习惯每开一个新终端先conda activate yolov5_env再干活。2.2 PyTorch 与 CUDA 的版本对齐这是整个搭建里最容易翻车的一环。PyTorch 的 GPU 版本是跟 CUDA 运行时绑定的你装的 torch 轮子自带一份 CUDA 运行时但驱动得系统里有且驱动支持的 CUDA 版本不能低于轮子要求的版本。教程里给的是 CUDA 11.3 对应的安装命令实际动手前先跑一句nvidia-smi看右上角那个 CUDA Version它代表你驱动能支持到的上限。# GPU 环境安装带 CUDA 11.3 支持的 PyTorch pip install torch torchvision # 纯 CPU 环境装 CPU 版体积小、不依赖显卡 pip install torch torchvision cpuonly这里有个血泪经验pip install torch torchvision默认拉的是哪个版本取决于你的 pip 源和平台不一定带 CUDA。稳妥做法是去 PyTorch 官方给的安装命令生成页按你的系统和 CUDA 版本复制那条完整命令通常长这样pip install torchx.x.xcu113 torchvisionx.x.xcu113 -f https://...。装完立刻验证别等跑检测时才发现是 CPU 版import torch # 打印版本和 CUDA 是否可用False 说明装成了 CPU 版或驱动不匹配 print(torch.__version__, torch.cuda.is_available()) # 可用时再看显卡型号和显存显存决定你能开多大 batch print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else CPU only)torch.cuda.is_available()返回 False 的排查顺序是驱动有没有装、nvidia-smi能不能出画面、装的 torch 是不是 cu 版本、CUDA 运行时版本是否高于驱动支持上限。cuDNN 一般随 torch 轮子一起带不用单独装教程里提的 cuDNN 7.6 是下限要求实际以 torch 自带为准。2.3 拉源码与装项目依赖环境好了把项目代码拿下来。注意别在随便一个目录里 clone后面训练产物、数据集路径都相对项目根目录走路径乱了很麻烦。# 克隆项目仓库并进入目录 git clone https://github.com/ultralytics/yolov5.git cd yolov5 # 安装项目声明的全部依赖 pip install -r requirements.txtrequirements.txt里锁了一批库的版本包括 opencv-python、pillow、pyyaml、tqdm 这些。装的时候如果报某个包编译失败八成是缺系统级编译工具Linux 上补build-essentialWindows 上装 Visual C Build Tools。装完可以用pip list扫一眼确认 torch 版本没被 requirements 里的宽松约束降级覆盖掉——这是另一个隐蔽的坑requirements 里如果写了torch1.7pip 可能觉得你已装的满足条件就不动也可能顺手给你换个版本装完再验一次torch.cuda.is_available()最保险。3. 跑通第一次检测detect.py 的参数逐个拆开看3.1 权重文件与目录约定YOLOv5 提供 s、m、l、x 几个规格字母越大网络越深、精度越高、速度越慢。教程用 yolov5s.pt这是最小的一档几 MB 大小CPU 上也能跑出能看的结果适合第一次验证链路通不通。# 下载最小的预训练权重到项目根目录 wget https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.ptWindows 上没有 wget用浏览器下或者 PowerShell 的Invoke-WebRequest都行关键是文件落在项目根目录因为 detect.py 默认按相对路径找权重。权重文件本质是个字典里面存了模型结构和训练好的参数加载时框架会按结构重建网络再灌参数所以权重和代码版本差太多会报 key 不匹配这也是为什么建议权重和仓库版本尽量对齐。3.2 detect.py 的核心参数与一次完整调用检测脚本的参数不少但真正天天调的就那么几个。先看一次完整调用再逐个说。# 对单张图片做检测权重、输入源、推理尺寸、置信度阈值、NMS 的 IoU 阈值 python detect.py --weights yolov5s.pt --source test.jpg --img 416 --conf 0.4 --iou 0.5--weights指定模型权重路径可以换成自己训练出来的best.pt。--source是最灵活的一个可以是单张图、一个目录、一段视频文件甚至填0调摄像头实时检测。--img是推理时的输入分辨率必须是 32 的倍数416 比默认的 640 快不少代价是小目标容易漏工地那种远景小目标场景我一般还是回到 640。--conf是置信度阈值低于它的框直接丢调高框变少变准、调低召回上来但误检多。--iou是 NMS 的 IoU 阈值同一个物体被预测出多个框时重叠度超过这个值的低分框会被压掉调太低会把挨得近的两个真实目标误合并调太高又压不干净。脚本跑完结果默认落在runs/detect/exp下第二次跑会变成exp2、exp3不会覆盖。输出图里框的颜色按类别区分左上角带类别名和置信度。如果一张图跑完啥框都没有先别怀疑模型把--conf降到 0.1 再看很多时候是阈值卡太死。3.3 从脚本入口看推理链路想改检测行为得知道 detect.py 里发生了什么。核心链路是读图 → letterbox 缩放填充到 32 的倍数 → 归一化转 tensor → 送进模型前向 → 输出一堆候选框 → NMS 过滤 → 按原图比例还原坐标 → 画框存图。其中 letterbox 那步是很多人忽略的细节它保持长宽比缩放再补灰边避免直接拉伸导致目标变形还原坐标时也要按同样的比例反算自己写后处理时这里算错框就会整体偏移。# 伪代码示意 detect.py 的核心推理段帮助理解参数作用位置 img letterbox(im0, new_shapeimg_size)[0] # 保持比例缩放并填充 img img[:, :, ::-1].transpose(2, 0, 1) # BGR 转 RGBHWC 转 CHW img np.ascontiguousarray(img) / 255.0 # 归一化到 0~1 pred model(img_tensor)[0] # 前向得到候选框 pred non_max_suppression(pred, conf_thres, iou_thres) # 按 conf 和 iou 过滤conf_thres和iou_thres就是命令行传进来的--conf和--iou它们作用在 NMS 这一步而不是模型内部。理解这一点很关键模型输出的原始候选框数量是固定的你调阈值只是决定留哪些不会让模型“看得更准”。想让模型本身更准得走训练那条路。4. 训练自己的数据集配置、启动与产物解读4.1 数据集格式与 data.yamlYOLO 系列的数据标注格式是每张图配一个同名 txt每行一个目标格式为类别索引 中心x 中心y 宽 高后四个都是相对图像尺寸归一化到 0~1 的值。目录一般组织成 images/train、images/val 和对应的 labels/train、labels/val。标注工具导出时选 YOLO 格式即可别导成 VOC 的 xml虽然框架有转换脚本但多一道转换多一次出错机会。数据准备好后写一个 data.yaml告诉训练脚本去哪找图、有几类、类名是什么# data.yaml 示例路径、类别数、类名三块是必须的 train: ../dataset/images/train val: ../dataset/images/val nc: 3 names: [helmet, vest, person]train和val写图片目录框架会自动去找同级的 labels 目录。nc是类别数必须和 names 长度一致写错了训练能启动但类别会错位。names的顺序就是标注文件里类别索引对应的名字标错顺序是最隐蔽的错误之一训练 loss 看着正常检测出来类别全乱。4.2 改模型配置与启动训练模型配置文件在models/yolov5s.yaml里面主要是 depth_multiple、width_multiple 和 backbone、head 的结构定义。换类别数只需要改nc这一项别去动网络结构除非你清楚自己在干什么。# 用预训练权重做迁移学习训练自定义数据集 python train.py --img 416 --batch 16 --epochs 300 \ --data data/mydata.yaml --cfg models/yolov5s.yaml \ --weights yolov5s.pt --cache--batch 16是每步喂多少张图显存不够就往下调8 甚至 4 都行batch 太小梯度噪声大会影响收敛可以配合调小学习率。--epochs 300是过数据集的轮数小数据集一两百轮就够看验证集指标不再涨就可以停。--weights yolov5s.pt是迁移学习的关键从预训练权重起步比从零训练收敛快得多小数据集上效果差距非常明显。--cache把图片缓存进内存加速读取数据集大到内存放不下时要去掉否则会吃满内存被系统杀掉。训练产物落在runs/train/exp下重点看两个文件weights/best.pt是验证集指标最好的权重results.png里画了各类 loss 和 mAP 曲线。曲线是判断训练状态的窗口——训练 loss 一直降但验证 mAP 不涨甚至掉就是过拟合该加数据增强或者减轮数两个 loss 都居高不下可能是学习率太大或者标注有问题。4.3 用训练结果做推理与指标验证训练完拿 best.pt 跑一次检测确认端到端没问题# 用自己训练的权重检测输入源换成验证集里的图 python detect.py --weights runs/train/exp/weights/best.pt --source ../dataset/images/val --conf 0.25自定义模型第一次跑--conf建议先给低一点比如 0.25看召回情况再往上调。验证指标除了看 results.png还可以跑val.py得到精确的 mAP# 在验证集上评估输出 mAP0.5 和 mAP0.5:0.95 python val.py --weights runs/train/exp/weights/best.pt --data data/mydata.yaml --img 416mAP0.5 看整体检出能力mAP0.5:0.95 更严格看框的定位精度。两个数差得特别大说明框画得不够准可能是标注框本身松紧不一或者输入分辨率太低。5. 避坑与排查这几处我踩过你别再踩5.1 现象训练一开始就报显存不足原因通常是 batch 或 img 开太大或者--cache把大数据集全塞进了内存。解决是先降 batch 到 8 甚至 4img 从 640 降到 416去掉--cache再用nvidia-smi观察显存占用曲线确认稳定后再逐步往上加。别一上来就拉满训练中途 OOM 比启动就 OOM 更气人。5.2 现象检测结果框位置整体偏移原因多半是输入尺寸不是 32 的倍数或者自己改后处理时 letterbox 的缩放比例没对上。解决是确认--img传的是 32 的倍数320、416、640自己写推理代码时严格复用框架的 letterbox 和 scale_coords 逻辑别手写坐标还原。5.3 现象训练 loss 正常但检测类别全错原因是 data.yaml 里 names 的顺序和标注文件里的类别索引对不上。解决是抽几张图用标注工具重新打开核对类别名再对照 yaml 里的顺序逐类确认。这个错误不会让训练报错只会让结果悄悄错属于典型的黑匣子问题。5.4 现象pip 装完 torch 后 CUDA 不可用原因是装成了 CPU 版轮子或者驱动支持的 CUDA 版本低于轮子要求。解决是先nvidia-smi看驱动上限再去官方安装页复制对应版本的完整命令重装装完用torch.cuda.is_available()验证别靠猜。5.5 现象验证集 mAP 很高实际场景一塌糊涂原因是训练集和实际场景分布差太远比如训练图都是白天、清晰、正对镜头实际是夜间、模糊、斜拍。解决是往训练集里补真实场景的图和对应的困难样本做针对性增强别指望调推理阈值能救回来。6. 二次开发把检测能力接进自己的业务链路跑通只是起点真正落地时没人会让你手动敲 detect.py。我一般的做法是把模型加载和推理封装成一个常驻服务业务侧通过接口传图、拿结构化结果。核心是把 detect.py 里那套 letterbox、前向、NMS、坐标还原抽出来去掉画图存盘的部分直接返回[x1, y1, x2, y2, conf, cls]的列表。import torch, cv2 from models.common import DetectMultiBackend from utils.augmentations import letterbox from utils.general import non_max_suppression, scale_coords # 服务启动时加载一次别每次请求都加载加载权重是重操作 device torch.device(cuda:0 if torch.cuda.is_available() else cpu) model DetectMultiBackend(runs/train/exp/weights/best.pt, devicedevice) model.eval() def infer(image_path, conf0.25, iou0.45, imgsz640): im0 cv2.imread(image_path) # 保持比例缩放到 imgsz返回缩放后的图和原始尺寸比例 img letterbox(im0, imgsz, stride32, autoTrue)[0] img img[:, :, ::-1].transpose(2, 0, 1) # BGR-RGB, HWC-CHW img torch.from_numpy(img).to(device).float() / 255.0 img img.unsqueeze(0) # 补 batch 维度 pred model(img)[0] pred non_max_suppression(pred, conf, iou) results [] for det in pred: if len(det): # 把缩放图上的坐标还原回原图尺寸 det[:, :4] scale_coords(img.shape[2:], det[:, :4], im0.shape).round() for *xyxy, c, cls in det: results.append([int(v) for v in xyxy] [float(c), int(cls)]) return results这段代码里几个点值得说。DetectMultiBackend是框架封装的统一加载入口能自动识别权重格式比手动拼模型结构省事。stride32和autoTrue让 letterbox 自动算填充量保证尺寸对齐。scale_coords那步千万别省省了返回的坐标就是缩放图上的业务侧拿去画框会整体偏小。model.eval()也要记得训练模式下的 BN 层行为不一样推理结果会飘。改造方向上如果业务是视频流把逐帧读图换成cv2.VideoCapture循环推理部分不变注意控制帧率别把 GPU 打满。如果要多路并发模型实例共享、请求排队别每个请求 new 一个模型。想再快可以导出 ONNX 或 TensorRT 引擎用export.py一条命令搞定推理侧换成对应的 runtime速度能提一截代价是后处理逻辑要自己接。验证改造是否正确的办法很土但有效拿同一张图分别走原始 detect.py 和你的封装函数把两边的框坐标和置信度打出来对比数值一致才算接对了。我吃过一次亏封装时把 RGB 和 BGR 搞反了检测框位置对但类别置信度普遍偏低查了大半天才发现是通道顺序问题。从那以后我每次封装推理代码都强制拿原脚本的输出做一次逐框比对对上了再往业务里接。希望帮到你。本文还有配套的精品资源点击获取