YOLOv5实战:从数据集训练到TensorRT部署全流程解析 简介面向YOLOv5学习者的完整实战代码仓库内容按入门、拓展、进阶、部署四篇编排从环境安装、模型推理、数据集构建、模型训练到界面开发、网页演示、云端服务器训练、推理加速部署等均有涉及适合零基础起步、逐步进阶的开发者。压缩包共三百四十个文件大小约二百七十六兆主要包含训练与推理脚本、模型配置、图像样本、可视化笔记、标签与说明文件、预训练权重以及推理引擎另有容器化与自动化脚本便于搭建环境。代码结构清晰内容按篇章组织可对照配套视频按需取用进阶内容还覆盖网络结构修改、注意力机制引入、主干网络替换以及接口化项目部署与模型调用等扩展方向。目前已有约一百三十八人学习无论是入门YOLOv5还是做工程化部署都能从这份资源中获得可直接运行的代码和完整操作链路。1. 这份YOLOv5实战zip包值得花十分钟拆开它把训练到部署的路都铺好了很多做目标检测的同行都下载过YOLOv5源码但真正能把自己的数据集跑通、再把模型部署到服务里的人不多。这份“手把手带你实战YOLOv5.zip”是B站配套课程的完整代码仓库里面不只有YOLOv5源码还包括训练过程生成的results.csv和 TensorBoard 事件文件events.out.tfevents...以及已经转换好的yolov5s.engine系列 TensorRT 引擎文件。也就是说你解压之后既能回看训练日志也能直接用 TensorRT 推理。适合刚接触目标检测、想从环境安装一路走到 Flask 部署的从业者也适合已经跑通训练、但对engine推理和 Web 封装还不熟的人。整个课程分入门、拓展、进阶、部署四个篇章代码仓库把这些篇章对应的文件都收在一起省去到处找源码的时间。2. 环境安装与数据集构建先把YOLOv5跑起来再谈别的2.1 从zip解压到conda环境版本匹配是第一道坎拿到这个zip包第一步不是急着跑训练而是先把压缩包解压干净。这里有个容易被忽视的点zip包内部目录如果带权限或软链在 Windows 上解压可能会丢可执行权限在 Linux 上则要注意解压后文件属主。我一般习惯用命令解压而不是双击这样能避免文件名编码问题。unzip 手把手带你实战YOLOv5.zip -d yolov5_project cd yolov5_project conda create -n yolov5 python3.8 -y conda activate yolov5 pip install -r requirements.txt逻辑说明unzip的-d参数指定解压目标目录避免把一堆文件散落在当前目录conda create创建独立环境防止和系统 Python 互相污染。requirements.txt是 YOLOv5 官方仓库自带的依赖清单里面包含了 torch、opencv-python、pyyaml 等运行所需库。参数说明Python 版本建议 3.8 或 3.9太新的 3.11/3.12 可能遇到部分算子兼容问题。如果你本机 CUDA 版本是 11.xtorch 安装建议用pip install torch1.13.1这类匹配版本具体以你nvidia-smi显示的 CUDA 版本为准不要盲装最新版。这个zip包里的Dockerfile也给出了另一条路如果你不想污染本机环境直接用 Docker 镜像跑更干净。2.2 用自己的数据集训练目录结构决定训练脚本能不能找到图把YOLOv5跑起来之后的第一个正经任务是训练自己的数据集。很多人栽在数据集目录结构上。YOLOv5 默认要求 images 和 labels 分开并且 train/val 子目录放图片标签文件按同名 txt 放在 labels 下。课程里的“YOLOv5 数据集构建”环节就是干这个。# 以你的自定义数据集为例 mkdir -p datasets/mydata/images/train mkdir -p datasets/mydata/images/val mkdir -p datasets/mydata/labels/train mkdir -p datasets/mydata/labels/val # 标签格式class_id x_center y_center width height归一化坐标逻辑说明YOLOv5 的Dataset类会按datasets/mydata路径去找images和labels如果你把自己的图片放在别的别名目录下train.py的 data 参数指向的 YAML 文件里写的path必须精确匹配。这里的labels目录下每个 txt 文件和图片同名里面一行代表一个目标。参数说明坐标是归一化到 0~1 的浮点数不是像素坐标。如果你用 LabelImg 或 labelme 导出的是像素框需要写个转换脚本。常见做法是def convert(x1, y1, x2, y2, img_w, img_h): c_x ((x1 x2) / 2) / img_w c_y ((y1 y2) / 2) / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h return c_x, c_y, w, h这段脚本把 VOC 格式的左上右下坐标转成 YOLO 需要的中心点加宽高转换后要检查w和h是否大于 0部分标注软件导出时可能出现反向坐标那会导致训练 loss 直接 NaN。2.3 检查训练数据标签和图像数量必须对得上每张图片对应一个 txt 文件但允许 txt 为空即没有目标。常见翻车点是图片有而标签文件缺失或者标签文件有而图片缺失。训练脚本会在加载时报错但有时报错信息不直观。# 快速检查统计图片和标签文件数量 find datasets/mydata/images/train -name *.jpg | wc -l find datasets/mydata/labels/train -name *.txt | wc -l逻辑说明两个数字应该一致但如果存在没有目标的图片标签文件仍然会生成空 txt所以数量一致是必要条件不代表全部正确。更严苛的做法是用yolov5/utils/里的脚本逐个解析标注是否在边界内。参数说明find的-name *.jpg只匹配 jpg如果你的图片是 png 或 bmp改成对应后缀。B站课程里老师用的是标准 coco 数据集结构你替换成自己的数据集后必须同步修改.yaml里的nc类别数。3. 模型训练与超参数调整读懂results.csv和TensorBoard日志3.1 训练指令里的关键参数不要全盘照抄默认值YOLOv5 的训练入口是train.py课程“YOLOv5 模型训练”一节会讲到最精简的命令。实际训练时我一般会在默认参数基础上做三处调整batch-size要匹配显存、epochs要够但别过拟合、workers要按 CPU 核心数设。python train.py --data mydata.yaml --weights yolov5s.pt \ --batch-size 16 --epochs 100 --workers 8 --device 0逻辑说明--weights yolov5s.pt是用 COCO 预训练权重做迁移学习这比从零训练收敛快得多。--device 0指定用第一张 GPU如果你只有 CPU把--device cpu但训练速度会慢到让人怀疑人生。--data mydata.yaml指向你自己写的数据集配置文件。参数说明batch-size 16在 8GB 显存上对 yolov5s 是安全的但如果你用 4K 分辨率图片16 可能爆显存改成 8 或 4。epochs 100是经验值我的习惯是先跑 50 轮看看 loss 曲线如果验证集 mAP 还在上升就继续跑如果已经平台期早停。workers是数据加载线程数Windows 上建议设 4 以下Linux 可以设 8 或更高但不要超过 CPU 物理核心数。3.2 从results.csv里读训练健康度别只看loss训练结束后根目录会生成results.csv这个zip包里自带了一份历史训练结果。下面这个表格是results.csv里最常见的列列名含义健康值参考epoch当前轮数单调递增train/box_loss训练集框损失前 30 轮下降快后期平缓val/box_loss验证集框损失和训练损失同步下降不应反弹metrics/precision精确率越高越稳metrics/recall召回率和 precision 平衡metrics/mAP_0.5IoU0.5 的 mAP最终目标metrics/mAP_0.5:0.95严格 mAP一般比上面低 20~30 个点常规操作是每跑 10 轮瞄一眼val/box_loss如果它先降后升而train/box_loss还在降说明过拟合了。这时候你该做的是调--patience早停而不是继续跑。python train.py --data mydata.yaml --weights yolov5s.pt \ --batch-size 16 --epochs 100 --patience 10参数说明--patience 10表示验证集指标连续 10 轮不提升就自动停止训练。这个参数在课程进阶篇里有演示可以省掉你守夜的精力。但要注意如果数据集小且噪声大mAP 可能有波动patience 设太小会导致过早停止我一般设 15~20。3.3 用TensorBoard回放训练历史events.out.tfevents文件的正确理解zip 包里的events.out.tfevents...是 TensorBoard 的事件文件。你不需要重新训练就能看到当时那次训练的过程曲线前提是环境里装了 tensorboard。tensorboard --logdir.然后浏览器打开http://localhost:6006左侧选到对应 run就能看到 loss、mAP、learning rate 曲线。注意如果你的tfevents文件名里带着DESKTOP-XX这样前缀说明原训练是在 Windows 机器上跑的不影响读取。参数说明--logdir.指当前目录它不会自动递归所有子目录如果你把 events 文件放在runs/exp目录要写成--logdirruns。如果在远程服务器上还要加--host 0.0.0.0才能用本地浏览器访问。4. TensorRT部署加速yolov5s.engine系列文件的正确打开方式4.1 为什么要转成engine从PyTorch到TensorRT的变换课程部署篇的核心是 TensorRT。PyTorch 模型在 GPU 上推理虽然是动态图灵活但实际生产环境里我们只关心吞吐和延迟。TensorRT 会把训练好的模型做层融合、精度校准、内核自动调优生成一个engine文件。这个 zip 包里给你的是yolov5s.engine、yolov5s-halfsize.engine、yolov5s-fp16.engine三个版本对应不同精度和输入尺寸。文件精度输入尺寸特点适用场景yolov5s.engineFP32原始 640x640精度要求高容忍延迟yolov5s-fp16.engineFP16原始 640x640精度小降速度提升明显yolov5s-halfsize.engineFP32/FP16可能是 320x320 或自定义小尺寸带宽有限追求极致速度注意engine文件不是跨平台通用的。你在这台机器的 GPU 和驱动环境下生成的 engine换到另一张卡上可能加载失败或报错。所以拿到这个 zip 里的 engine 文件第一时间用加载脚本试跑如果报错再重新转换。4.2 用engine做推理TensorRT的API没那么可怕加载 engine 做推理的标准姿势是先反序列化然后绑定输入输出 buffer。import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np logger trt.Logger(trt.Logger.WARNING) with open(yolov5s.engine, rb) as f, trt.Runtime(logger) as runtime: engine runtime.deserialize_cuda_engine(f.read()) context engine.create_execution_context() # 输入输出 buffer h_input np.empty((1, 3, 640, 640), dtypenp.float32) h_output np.empty((1, 25200, 5 num_classes), dtypenp.float32) d_input cuda.mem_alloc(h_input.nbytes) d_output cuda.mem_alloc(h_output.nbytes)逻辑说明deserialize_cuda_engine把引擎文件读取为可执行的推理计划create_execution_context创建推理上下文。输入张量用numpy初始化然后用cuda.mem_alloc在显卡上分配显存。推理时要先执行cuda.memcpy_htod把图片拷入显存再调用context.execute_v2最后把输出拷回内存。参数说明预处理的归一化方式要和训练时一致。YOLOv5 训练时是除以 255 归一化到 0~1很多人在这一步偷懒直接喂 0~255 的原始像素导致 mAP 低得离谱。num_classes是你的类别数如果你在 zip 自带的分类上测试就是 COCO 的 80 类但一旦用自己数据集重新训练这个数必须改。4.3 后处理engine输出的是裸张量不是检测框从 engine 拿到的25200是 640x640 下三个尺度特征图拼接后的候选框数量。每个候选框有5 num_classes个值前 4 个是坐标第 5 个是置信度后面是类别概率。def postprocess(output, conf_thres0.25, iou_thres0.45): # output shape: (1, 25200, 85) boxes output[0] # 去掉 batch 维 # 按置信度筛选 mask boxes[..., 4] conf_thres boxes boxes[mask] if len(boxes) 0: return [] # 类别置信度 目标置信度 * 类别概率 class_conf boxes[..., 4:5] * boxes[..., 5:] class_id class_conf.argmax(axis-1) conf class_conf.max(axis-1) # NMS keep nms(boxes[:, :4], conf, iou_thres) return boxes[keep], class_id[keep], conf[keep]逻辑说明25200这个数字来自 YOLOv5 的 anchors 设计——3 个尺度乘以 3 个 anchor再乘以特征图网格数。后处理的核心是阈值筛选和非极大值抑制。课程里专门有“YOLOv5 后处理”一集建议动手实现一遍不要直接用utils.general.non_max_suppression因为你要理解 engine 输出和 PyTorch 模型输出的区别。参数说明conf_thres和iou_thres是后处理的两个关键阈值。工程上我一般把conf_thres设 0.3iou_thres设 0.45前者卡目标置信度后者控制重叠框的消除力度。阈值设太低会出大量误检设太高又漏检。5. 实战避坑五个YOLOv5配置与部署的常见问题5.1 现象conda环境装好但 torch.cuda.is_available() 返回 False原因你的 CUDA 驱动版本和 PyTorch 内部编译时的 CUDA 版本不匹配。最常见是nvidia-smi显示 CUDA 12.x但装的是torch1.13配套的 CUDA 11.7。另一个原因是在 base 环境里装了 CPU 版 torch然后又用conda create建了新环境但pip指向了旧环境的 site-packages。解决先彻底退出环境再重新创建环境用 PyTorch 官网的安装命令重新装。conda activate yolov5 python -c import torch; print(torch.__version__, torch.cuda.is_available()) # 如果 False卸载重装 pip uninstall torch torchvision -y pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118注意不要用conda install pytorch那个源可能会给你装 CPU 版。装完再跑检查脚本看到True再继续。5.2 现象训练前 20 轮 loss 就降到接近 0验证集 mAP 却一直在低位原因数据集标注有错误比如类别 id 从 1 开始而不是 0导致标签和模型输出对不上或者图片里有大量空标签模型学会了把所有目标都忽略。典型特征是train/box_loss正常但metrics/recall极低。解决先检查 label 文件。写一段脚本遍历每张图片的 txt看 class_id 是否在[0, nc-1]范围内再看坐标是否超出图片宽高。python -c from pathlib import Path for f in Path(datasets/mydata/labels/train).glob(*.txt): for line in f.read_text().strip().splitlines(): cls int(line.split()[0]) if cls 0 or cls 5: # 假设 5 类 print(f.name, bad class, cls) 5.3 现象加载 yolov5s.engine 报错 TensorRT version mismatch原因zip 里的 engine 是用某个特定 TensorRT 版本转换的你的环境里 TensorRT 版本不兼容。engine是二进制产物包含算子内核选择跨版本几乎不可能通用。解决换成自己的环境重新转换。转换脚本常见是python export.py --weights yolov5s.pt --include engine --device 0 --half参数说明--half表示导出 FP16 engine。如果你想导出 FP32去掉--half。但注意export.py是 YOLOv5 自带的脚本zip 包里没有的话要去官方仓库单独下载。转换时 TensorRT 版本要和推理环境完全一致否则刚才的报错会复现。5.4 现象Gradio页面能打开但上传图片后推理报错 shape mismatch原因Gradio 输入的图片被PIL打开后是 HxWxC 的 uint8 数组而你检测函数期望的是 1x3x640x640 的 float32 张量。很多人直接把 image 传给模型忘记做 letterbox 和 BGR/RGB 转换。解决在送入模型前做标准化预处理。import cv2 img cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # Gradio 给的是 RGB img letterbox(img, new_shape(640, 640), stride32)[0] img img[:, :, ::-1].transpose(2, 0, 1) # BGR - RGB img np.ascontiguousarray(img, dtypenp.float32) / 255.0 img np.expand_dims(img, axis0)5.5 现象Dockerfile 构建时下载依赖卡在 pip install 阶段原因基础镜像源是国外源国内网络访问慢或者被墙。zip 包里带了Dockerfile-cpu和Dockerfile-arm64如果是 arm 设备还要注意基础镜像本身是否支持该架构。解决在 Dockerfile 里换 pip 源和 apt 源。常见做法是在pip install前加一行RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt另外如果你在 arm64 设备上跑建议看Dockerfile-arm64的内容不要用通用的Dockerfile因为很多预编译轮子没有 arm 版本。6. 把训练好的模型变成Web服务Gradio快速验证Flask正式部署6.1 用Gradio搭一个可交互的检测Demo课程“YOLOv5 Gradio搭建Web GUI”给出了快速验证的方法。Gradio 能在几分钟内把检测函数包装成网页适合给团队看效果。import gradio as gr from detect import run_detection # 你自己的推理函数 def detect_and_show(image): result_img run_detection(image) return result_img gr.Interface(fndetect_and_show, inputsimage, outputsimage, titleYOLOv5 Demo).launch()参数说明inputsimage会返回一个numpy.ndarray注意颜色通道顺序是 RGB。如果你的检测函数内部用的是 OpenCV 的 BGR需要在函数入口做一次转换。launch()默认为server_name127.0.0.1如果要局域网访问改成launch(server_name0.0.0.0, server_port7860)。6.2 进阶Flask部署时的后处理与返回结构如果要把模型嵌进现有系统Flask 是更常被要求改造的方向。课程“基于Flask的YOLOv5项目部署”里会把模型加载放入 Flask 应用初始化阶段避免每个请求都重复加载模型。from flask import Flask, request, jsonify import cv2, numpy as np app Flask(__name__) # 全局加载模型只加载一次 model load_tensorrt_engine(yolov5s.engine) app.route(/detect, methods[POST]) def detect(): file request.files[image] img cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR) results model.detect(img) return jsonify({boxes: results[boxes].tolist(), labels: results[labels].tolist(), confs: results[confs].tolist()})逻辑说明模型加载放在 Flask 模块顶部进程启动后会常驻显存不需要每次请求重新读 engine 文件。imdecode从字节流解码图片避免用cv2.imread因为路径问题出 Bug。检测函数内部必须包含 letterbox、推理、后处理这一整套在课程部署篇有专门章节。参数说明request.files[image]是前端以multipart/form-data上传的文件对象。返回的 JSON 里boxes是二维列表每行[x1, y1, x2, y2]是原始图片坐标系下的像素坐标不是归一化坐标。前端拿过去画框时要确认坐标系一致。这里有一个我每次必踩的坑用 TensorRT engine 推理时输入的 letterbox 填充颜色必须是灰色(114, 114, 114)而你训练时预处理脚本可能填的是黑色。这个灰度值影响背景填充区域的响应虽然不至于全错但会让边缘目标检测精度下降一两个点。从那以后我每次在本地跑通推理都会顺手做一次「同一张图、PyTorch 模型 vs TensorRT engine」的输出对比确保坐标和置信度误差在 1e-3 以内再交出去部署。也希望这份 zip 里的笔记和 engine 文件能帮你少走这些弯路希望帮到你。本文还有配套的精品资源点击获取