YOLOv5自定义数据集训练全流程:从环境配置到模型部署实战指南
1. 从零开始为什么选择YOLOv5训练自己的数据集如果你正在读这篇文章大概率是遇到了一个具体的问题你想让计算机识别某个特定的东西比如工厂流水线上的瑕疵零件、农田里的害虫、或者监控画面中的特定车辆。你听说YOLOv5很厉害速度快、精度高而且社区活跃但面对“训练自己的数据集”这个任务网上的教程要么太零散要么跳过了关键细节让你在环境配置、数据准备、训练调参的迷宫里反复碰壁。别担心这正是我写这篇超详细指南的原因——我将以一个过来人的身份带你走完从环境搭建到模型部署的完整闭环避开我踩过的所有坑。YOLOv5之所以成为工业界和学术界的热门选择不是没有道理的。相比它的前辈YOLOv4v5在PyTorch框架下实现了更简洁的工程结构训练和推理速度都更快对新手也友好得多。更重要的是它的“自己训练”门槛被大大降低了。你不需要是深度学习专家只要按照清晰的步骤准备数据、修改配置、运行脚本就能得到一个专属于你业务场景的检测模型。无论是用最新的RTX 4090还是在Jetson Nano这样的边缘设备上YOLOv5都能找到用武之地。接下来我会假设你是一个有一定Python和命令行基础但初次接触目标检测的开发者用最直白的语言把每个环节掰开揉碎讲清楚。2. 环境准备不只是pip install那么简单很多人觉得环境配置就是照着README运行几条命令但恰恰是这里埋了最多的雷。一个纯净、版本匹配的环境是成功的一半。2.1 基础环境搭建与版本锁定首先我强烈建议使用Conda或虚拟环境来管理你的Python环境避免与系统或其他项目的包冲突。以下是经过大量项目验证的稳定版本组合能最大程度避免兼容性问题# 创建并激活一个名为yolov5的虚拟环境 conda create -n yolov5 python3.8 conda activate yolov5接下来是核心依赖的安装。直接pip install -r requirements.txt可能会因为网络或版本问题失败。我的经验是先安装PyTorch因为它对CUDA版本有严格要求。去 PyTorch官网 根据你的CUDA版本用nvidia-smi命令查看生成安装命令。例如对于CUDA 11.8pip install torch1.13.1cu117 torchvision0.14.1cu117 torchaudio0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117注意这里版本号后的cu117必须与你本机的CUDA版本匹配。安装错误的版本会导致训练时无法调用GPU错误信息可能很隐晦比如“CUDA error: no kernel image is available for execution”。安装好PyTorch后再克隆YOLOv5的官方仓库并安装剩余依赖git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt这里有个关键细节requirements.txt里的opencv-python在某些系统上可能安装失败。如果遇到问题可以尝试安装headless版本pip install opencv-python-headless。安装完成后务必运行一个快速验证脚本import torch print(fPyTorch版本: {torch.__version__}) print(fCUDA是否可用: {torch.cuda.is_available()}) print(fCUDA版本: {torch.version.cuda}) print(fGPU设备: {torch.cuda.get_device_name(0)})如果CUDA可用你会看到你的GPU型号。如果显示False请回头检查PyTorch与CUDA的版本对应关系。2.2 数据标注工具选型与实战数据是模型的“粮食”。YOLOv5要求的数据格式是特定的TXT文件每张图片对应一个TXT内容为class_id x_center y_center width height坐标是归一化后的值。手动写这些文件几乎不可能我们必须借助标注工具。LabelImg是经典选择开源免费支持Pascal VOC和YOLO格式。安装简单pip install labelImg然后命令行运行labelImg即可。但它的界面稍显老旧且对于大量数据标注效率不高。Label Studio是更现代、功能更强的选择。它是一个Web应用支持图像、文本、音频等多种数据的标注并且可以团队协作。部署起来稍麻烦但一旦设置好流水线作业非常高效。标注完成后Label Studio可以导出为COCO或YOLO格式。对于“label studio数据标注后的json数据”你需要一个转换脚本将其转为YOLOv5格式。网上有很多现成脚本核心是解析JSON中的shapes字段提取类别和边界框坐标然后进行归一化计算。我个人的工作流是对于小项目几百张图用LabelImg快速启动对于中大型项目用Label Studio搭建一个标注平台让实习生或标注团队在线协作最后统一转换格式。标注过程中的黄金法则边界框要紧贴目标框得太松会引入过多背景噪声太紧则会丢失目标边缘特征。统一标注标准对于同一个类别比如“狗”无论大小、姿态如何都应该使用相同的标注定义。最好先制作一个标注规范文档。处理遮挡对于部分遮挡的目标尽量标注其可见部分。对于严重遮挡超过50%通常选择不标或根据项目需求决定。负样本如果某些图片中完全没有你的目标类别这些图片也需要放入数据集文件夹但对应的TXT文件为空文件。这有助于降低误检率。3. 数据集构建与YOLO格式深度解析准备好原始图片和标注后我们需要将其组织成YOLOv5能够识别的结构。这是新手最容易出错的一步。3.1 目录结构标准化YOLOv5期望的目录结构如下所示。我建议你完全按照这个来创建可以避免后续90%的路径错误your_dataset/ ├── images/ │ ├── train/ │ │ ├── image1.jpg │ │ └── image2.jpg │ └── val/ │ ├── image3.jpg │ └── image4.jpg └── labels/ ├── train/ │ ├── image1.txt │ └── image2.txt └── val/ ├── image3.txt └── image4.txt关键点images和labels目录同级。train和val子目录名称必须严格一致。图片和标签文件除后缀外主文件名必须完全相同如image1.jpg对应image1.txt。3.2 标签文件格式的数学原理每个TXT文件的内容可能像这样0 0.5 0.5 0.2 0.3 1 0.3 0.7 0.1 0.1这每一行代表一个目标物体。我们拆解一下0或1类别索引class_id。这个数字对应着你数据集中类别的顺序从0开始计数。它定义在后续的data.yaml配置文件中。0.5 0.5边界框中心点的归一化坐标x_center, y_center。计算公式是x_center (框左上角x坐标 框宽度/2) / 图片宽度。y_center同理。所以这两个值一定在0到1之间。0.2 0.3边界框的归一化宽度和高度width, height。计算公式是width 框的宽度 / 图片宽度height 框的高度 / 图片高度。为什么用归一化值这是为了消除图片原始尺寸的影响。无论你输入416x416还是640x640的图片模型处理的都是相对坐标这使得模型具有尺度不变性也是YOLO系列高效的原因之一。3.3 创建数据集配置文件data.yaml这个文件是连接你的数据和模型的桥梁。在数据集根目录your_dataset/下创建一个data.yaml文件内容如下# 数据集根目录路径建议使用绝对路径避免相对路径的歧义 path: /home/user/datasets/your_dataset # 训练集和验证集的图片目录相对路径相对于上面的path train: images/train val: images/val # 类别数量 nc: 2 # 类别名称列表顺序必须与标签文件中的class_id严格对应 names: [cat, dog]致命陷阱names列表的顺序就是类别ID。如果data.yaml里names: [dog, cat]但你的标签文件里把狗标成了0猫标成了1那么训练时模型会认为0是狗1是猫与你的标注意图完全相反导致训练完全失败。务必反复检查4. 模型选择与训练参数调优实战YOLOv5提供了从轻量到高精度的多个预训练模型文件名为yolov5s.ptyolov5m.ptyolov5l.ptyolov5x.pt。这里的s/m/l/x代表模型大小和复杂度递增。4.1 如何选择你的起点模型选择哪个模型作为预训练起点是一个权衡艺术模型参数量计算量 (GFLOPs)适用场景个人建议YOLOv5s约7.2M16移动/嵌入式设备Jetson Nano, RK3588实时性要求极高目标较简单。新手首选。训练快调试成本低在大多数业务场景下精度已足够。YOLOv5m约21.2M49通用服务器GPU精度和速度的平衡点。如果s版精度不达标升级到m版通常能显著提升且速度仍在可接受范围。YOLOv5l约46.5M109对精度要求高的任务如工业质检、医学影像。数据量充足上万张、类别多、小目标多时考虑。需要更强的GPU。YOLOv5x约86.7M205学术研究、竞赛刷分或不计成本的超高精度需求。除非有特别需求否则商业项目不推荐性价比低。我的经验是永远从YOLOv5s开始。先用小模型快速迭代验证数据 pipeline 和训练流程是否正确。如果mAP平均精度达不到要求再考虑换更大的模型或进行数据增强。记住好的数据比大的模型更重要。4.2 启动训练与核心参数解读基础训练命令看起来很简单python train.py --img 640 --batch 16 --epochs 100 --data ./your_dataset/data.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt让我们拆解每一个参数背后的意义和调优策略--img 640输入图片的尺寸。YOLOv5训练时会自动将图片缩放到这个尺寸保持长宽比并用灰色填充不足部分。为什么是640这是速度和精度的折衷。增大尺寸如1280可以提升小目标检测能力但会显著增加显存消耗和训练时间。减小尺寸如320则相反。对于大多数场景640是一个安全的起点。如果你的目标都非常小比如航拍图像中的车辆可以尝试增大到960甚至1280但要同步调整batch-size。--batch 16批次大小。这是单次输入到模型中的图片数量。更大的batch size可以使梯度下降更稳定可能有助于收敛。但最大能设多少完全取决于你的GPU显存。一个实用的命令是nvidia-smi先运行一个小的batch观察显存占用然后估算最大batch。例如8GB显存的卡如RTX 3070跑img640的YOLOv5sbatch16通常是安全的。如果出现“CUDA out of memory”错误就减小batch或img。--epochs 100训练轮数。一个epoch代表模型看完了整个训练集一遍。100个epoch对于中等数据集通常足够。如何判断是否训练够了观察训练日志中的metrics/mAP_0.5和val/loss曲线。当验证集损失val/loss不再下降甚至开始上升而mAP也趋于平缓时就说明模型已经收敛或开始过拟合了应该提前停止。YOLOv5支持--patience参数比如--patience 50表示如果连续50个epoch验证指标没有提升就自动停止训练。--data指向你刚才创建的data.yaml文件。--cfg模型结构配置文件。通常我们直接用官方的yolov5s.yaml等除非你需要修改网络结构如增加检测层。--weights预训练权重路径。使用yolov5s.pt就是迁移学习能极大加快收敛速度这是训练自己数据集成功的关键。即使你的类别和COCO数据集完全不同比如检测零件缺陷预训练模型提取通用特征边缘、纹理的能力也是非常有价值的。4.3 高级训练技巧与参数调优当你跑通基础训练后这些进阶选项能帮你把模型性能榨干--hyp超参数配置文件路径。YOLOv5有一个data/hyps/hyp.scratch-low.yaml文件里面定义了学习率、数据增强强度等超参数。对于迁移学习我们通常使用更保守的数据增强。可以复制一份进行修改例如降低颜色抖动(hsv_h,hsv_s,hsv_v)的强度避免过强的增强扭曲了你的专业领域图像特征。--multi-scale多尺度训练。开启后每10个batch会随机选择一个新的输入尺寸在--img尺寸的±50%范围内。这能提升模型对不同尺度目标的鲁棒性但会显著增加训练时间。--cache缓存图像到内存或磁盘ram或disk。如果你的数据集能完全放入内存使用--cache ram可以消除磁盘IO瓶颈让训练速度飞起。这是提升训练效率最有效的手段之一。--resume断点续训。如果训练意外中断比如掉电可以使用--resume从上次保存的最后一个权重last.pt继续训练无需从头开始。一个我常用的、针对中等数据集的优化训练命令示例python train.py \ --img 640 \ --batch 32 \ --epochs 200 \ --data ./data.yaml \ --weights yolov5s.pt \ --hyp data/hyps/hyp.finetune.yaml \ # 使用针对微调的超参 --cache ram \ # 缓存到内存 --patience 70 \ # 早停 --project runs/train \ # 输出目录 --name my_exp \ # 实验名称 --seed 42 # 固定随机种子确保实验可复现5. 训练过程监控与问题诊断训练启动后你会在终端看到滚动的日志同时在runs/train/exp目录下会生成一系列重要的可视化文件。学会解读这些信息是调参和排错的关键。5.1 核心日志指标解读训练时控制台会输出类似下面的信息Epoch gpu_mem box obj cls labels img_size 1/100 5.9G 0.1 0.05 0.02 100 640: 100%|██████████| 100/100 [01:2300:00, 1.20it/s] Class Images Labels P R mAP.5 mAP.5:.95: 100%|██████████| 20/20 [00:0500:00, 3.52it/s] all 100 500 0.95 0.90 0.92 0.70gpu_memGPU显存占用。用来监控是否爆显存。boxobjcls三个损失函数值。box边界框回归损失预测框与真实框的差异如CIoU Loss。这个值应该稳步下降。obj目标置信度损失判断网格内是否有物体。也应下降。cls分类损失判断物体属于哪个类别。同样应下降。P(Precision)R(Recall)mAP.5这是验证集上的关键性能指标。P(精确率)模型预测为正的样本中真正为正的比例。P低意味着误检多把背景当成了目标。R(召回率)所有真实的正样本中被模型找出来的比例。R低意味着漏检多目标没检测出来。mAP.5在IoU交并比阈值为0.5时的平均精度均值。这是最常用的综合指标通常我们最关心这个值的上升趋势。一个健康的训练过程mAP.5会随着epoch增加而稳步上升最终趋于平稳。5.2 TensorBoard可视化分析YOLOv5会自动将训练日志记录到TensorBoard。在训练目录下运行tensorboard --logdir runs/train然后在浏览器打开localhost:6006。这里有几个必须看的图表metrics/mAP_0.5和metrics/mAP_0.5:0.95这是你模型性能的“心电图”。健康的曲线应该是单调上升后趋于平稳。如果曲线剧烈抖动可能是学习率lr0设置过高。如果一直不上升可能是数据或配置有问题。loss/train和loss/val训练损失和验证损失。理想情况下两者都应该下降并且最终val_loss不会显著高于train_loss。如果val_loss在某个点后开始上升而train_loss继续下降这就是典型的过拟合——模型只记住了训练集而无法泛化到新数据。labels.jpg展示了你数据集中所有标签的分布。你可以看到目标中心点的位置分布是否集中在图像中心、目标尺寸的分布是小目标多还是大目标多。如果小目标图中右下角的小点很少那你的模型很可能不擅长检测小目标需要考虑增加--img尺寸或使用专门针对小目标的检测层。5.3 常见训练问题与解决方案问题一Loss特别是obj_loss居高不下或者mAP始终为0或极低。检查数据这是最常见的原因。用以下脚本快速验证你的数据格式是否正确from PIL import Image import os img_path ‘path/to/your/image.jpg’ label_path ‘path/to/your/label.txt’ img Image.open(img_path) img_w, img_h img.size with open(label_path, ‘r’) as f: for line in f: cls_id, x_c, y_c, w, h map(float, line.strip().split()) # 将归一化坐标还原为像素坐标 x1 int((x_c - w/2) * img_w) y1 int((y_c - h/2) * img_h) x2 int((x_c w/2) * img_w) y2 int((y_c h/2) * img_h) print(f“Class {cls_id}: Box ({x1}, {y1}, {x2}, {y2})“)在图片上画出这个框看看是否和目标吻合。经常发现的问题有坐标没有归一化、类别ID超出范围、图片和标签文件不匹配。检查data.yaml确认pathtrainval路径是否正确names列表是否和标签ID对应。降低学习率尝试在命令中加入--lr0 0.01默认是0.01或者更小的值如0.001。过高的学习率可能导致优化过程在最优解附近震荡无法收敛。问题二训练早期mAP有提升但后期val_loss上升train_loss继续下降过拟合。增加数据增强在hyp.yaml文件中适当调高flipudfliplr翻转mosaic马赛克增强等参数的概率。数据增强是缓解过拟合最有效的方法之一。使用更小的模型如果你在用yolov5l或x换回yolov5s或m试试。模型容量过大而数据量不足极易过拟合。收集更多数据这是根本解决之道。如果数据实在有限可以尝试迁移学习中的冻结训练先冻结主干网络backbone只训练检测头head然后再解冻全部微调。YOLOv5官方提供了相关脚本和思路。问题三训练速度非常慢。启用--cache如前所述使用--cache ram或--cache disk。检查数据加载是否图片尺寸过大尝试将--img设为640或更小。是否在机械硬盘上考虑将数据集移到SSD。调整--workers数据加载的线程数。通常设置为CPU核心数。设为0可能会成为瓶颈。6. 模型评估、测试与部署训练完成后在runs/train/exp/weights目录下你会得到两个最重要的文件best.pt验证集上表现最好的权重和last.pt最后一个epoch的权重。我们通常使用best.pt进行后续操作。6.1 模型性能评估使用val.py脚本在测试集上评估模型性能python val.py --weights runs/train/exp/weights/best.pt --data ./your_dataset/data.yaml --img 640 --batch 32 --task test这会生成详细的评估报告包括每个类别的精确率、召回率、mAP并保存混淆矩阵、PR曲线等图表。重点关注mAP0.5和mAP0.5:0.95。前者是宽松指标后者是更严格的指标IoU阈值从0.5到0.95步长0.05的平均值。对于严谨的项目mAP0.5:0.95更有参考价值。6.2 模型推理测试用训练好的模型对单张图片、视频或整个文件夹进行推理# 检测单张图片 python detect.py --weights runs/train/exp/weights/best.pt --source path/to/your/image.jpg --conf 0.25 # 检测视频 python detect.py --weights best.pt --source path/to/video.mp4 # 检测摄像头0为默认摄像头 python detect.py --weights best.pt --source 0 # 检测一个目录下的所有图片 python detect.py --weights best.pt --source path/to/image/folder/关键参数--conf置信度阈值。高于此阈值的检测框才会被显示。默认0.25。如果你的场景要求高精确率宁可漏检不可误检可以调高到0.5或更高。反之要求高召回率宁可误检不可漏检可以调低到0.1。--iou非极大值抑制NMS的IoU阈值。默认0.45。当同一个目标被多个框检测到时NMS会保留置信度最高的并抑制掉与其重叠度IoU高于此阈值的其他框。如果目标非常密集可以适当调低如0.3以避免误抑制。--save-txt保存检测结果为YOLO格式的TXT文件便于后续分析。6.3 模型导出与部署YOLOv5训练出来的是PyTorch模型.pt要部署到生产环境如C服务、移动端、边缘设备需要转换成其他格式。导出为ONNXpython export.py --weights runs/train/exp/weights/best.pt --include onnxONNX是一种开放的模型交换格式可以被TensorRT OpenVINO ONNX Runtime等多种推理引擎支持。导出时注意指定输入尺寸--img 640与你训练时一致。导出为TensorRT用于NVIDIA GPU加速python export.py --weights best.pt --include engine --device 0这需要你的环境已安装TensorRT。TensorRT引擎.engine能获得极致的推理速度是部署到Jetson系列Nano Xavier NX或Tesla服务器的标准操作。关于“rknn量化 校准数据集”和“k230部署yolov5”这是指向国产芯片如瑞芯微RKNN 嘉楠K230的部署。流程通常是PyTorch - ONNX - 芯片厂商提供的转换工具如RKNN-Toolkit - 芯片专用格式。这个过程中“校准数据集”用于量化将FP32模型转换为INT8等低精度模型以减少计算量和内存占用同时尽量保持精度。你需要准备一个代表性的图片集通常是训练集或验证集的一个子集100-500张在转换时提供给工具用于计算激活值的动态范围是量化步骤的关键。部署是一个深水区涉及性能优化、内存对齐、前后处理加速等诸多细节。但第一步永远是先得到一个在Python环境下推理正确的best.pt模型。后面的转换无非是格式的变换和效率的优化。走到这里你已经完成了YOLOv5训练自己数据集的完整旅程。从环境搭建、数据准备、模型训练、调优诊断到最终测试部署每一步都充满了细节和抉择。我最深刻的体会是数据质量决定模型上限代码和调参只是逼近这个上限的过程。花在数据清洗和标注上的时间永远比盲目调参更有价值。当你遇到瓶颈时不妨回到数据本身看看是不是标注不一致、样本不均衡、或者缺少某些难例。希望这篇超详细的指南能成为你解决实际问题的可靠路线图。