ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

YOLO自定义数据集训练全流程实战指南:从数据标注到模型部署

YOLO自定义数据集训练全流程实战指南:从数据标注到模型部署 直接把这两年跑自定义YOLO数据集的经验拿出来写个流水账。搞这个事的人有不少从标注、配环境到训练完看指标每一步都有隐藏坑位。我不是什么算法专家就是一个需要拿模型解决实际问题的普通开发者所以下面说的都是自己踩过的泥土路不定时更新想到哪写到哪。1. 动手之前先把版本、任务和数据这三件事定下来很多人一上来就搜“YOLO 训练自己的数据集”然后照着教程敲命令敲到一半发现版本对不上、数据格式不对、显存爆掉才开始回头补课。我建议动手前先花半天把下面几个问题想清楚比直接跑训练省时间。1.1 版本怎么选yolov5、yolov8、yolo11还是yolo26先回答一个被问烂的问题YOLO 到底第几代了严格来说从 YOLOv1 一路数到 YOLOv8后面又冒出 YOLO9、YOLO10、YOLO11还有不少人叫的 YOLOv26、YOLO27这些编号里既有官方系列也有社区系列追起来意义不大。我自己的习惯是选一个生态成熟、文档多、踩坑案例多的版本而不是选最新的。从我实际使用体感来看版本训练自定义数据集难度生态资料适用场景YOLOv5简单非常多入门首选老项目多YOLOv8简单非常多检测、分割、分类全家桶YOLO11中等较多需要更强特征提取能力YOLOv26等新编号不稳定少尝鲜或研究性项目这里不是劝你非用 v8 不可。如果你的项目要长期维护、需要部署到各种设备我反而推荐先看 v8因为它的接口最统一ultralytics库一套代码能跑检测、分割、分类、姿态估计遇到问题随便搜都有同款。v5 适合老设备老项目YOLO11 适合追求更高精度且能接受新库至于那些更新编号的“实验版”等文档更全了再碰也不迟。1.2 任务类型决定数据标注方式检测、分割还是跟踪训练自己的数据集之前要先搞清楚你要模型输出什么。目标检测输出的是边框实例分割输出的是每个目标的轮廓多目标跟踪需要加上跨帧的 ID。这三者的标注方式完全不同。我最近跑的一个项目就是“检测分割”混合地上堆料需要框出位置同时还要知道料堆的大致形状所以同一个数据集里既有检测标签也有分割标签。实际操作时检测标注我用矩形框分割标注用多边形最后统一转成 YOLO 格式。若你已经确定要 MOT 这类多目标跟踪那就不能只做单帧标框了还要处理帧与帧之间的 ID 对应通常先把 MOT16 这类公开数据转成 YOLO 格式再在训练时加入跟踪头工作量和纯检测不是一个量级。结论很简单先定任务再定标注格式再去找工具顺序千万别反。1.3 数据从哪来、量级要多大自定义数据集最常见三个来源自己拍、网上找开源数据集、用合成数据打底。自己拍最贴近真实场景但数量通常不够开源数据集质量高但类别未必匹配合成数据能快速补量但模型在真实场景会有些水土不服。数量方面的建议我自己的经验是单类别最少 200 到 500 张真实图片想稳定一点就往 1500 张以上走。像泥石流滑坡这类目标检测数据集正样本本身难获取那就用数据增强硬凑但增强不能太离谱比如把滑坡区域反转成天空就容易把模型带偏。更重要的是多样性同一个类别要有不同角度、不同光照、不同远近单独靠增大数量堆不出来泛化能力。2. 环境准备和数据标注被卡住最多的地方训练环节本身只要一条命令真正让新手崩溃的是环境装不上、标注标错、格式转不对。这一章节我把自己的标准流程拆开讲。2.1 环境配置conda、CUDA、PyTorch 以及 AMD 显卡环境配置最稳的路径是用 Anaconda 建独立环境避免把系统 Python 搞乱。我是这么一步步来的conda create -n yolo python3.10 -y conda activate yolo pip install ultralytics装ultralytics会自动拉 PyTorch 相关依赖但这里有个坑如果你有 NVIDIA 显卡默认 pip 源装的 torch 不一定和你的 CUDA 版本匹配。先跑一句nvidia-smi看驱动支持的 CUDA 版本然后去 PyTorch 官网镜像安装对应版本比如pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121我自己推荐直接在 PyCharm 里把 conda 解释器指到yolo环境这样写脚本、看变量、跑训练都在一个地方。很多大作业和毕设项目用 PyCharm 和 Anaconda 来识别人脸、识别物体基本都是这个套路。AMD 显卡用户要单独说一句因为现在用 A 卡跑 YOLO 的人越来越多。AMD 卡可以借助 ROCm 或 DirectML 路线跑训练和推理但踩坑概率比 N 卡高不少。下面专门有一个小节讲这个问题这里先给结论如果你是为了省事训练还是建议租一个 N 卡云环境如果一定要本地跑做好算子不支持、速度偏慢的心理准备。2.2 标注工具LabelImg 与 CVAT标注工具我用了不少最常用的还是 LabelImg。它支持 Pascal VOC 和 YOLO 两种格式在软件右上角切到 YOLO 模式后每画一个框就会保存一个同名 txt 文件里面就是标准的 YOLO 标注格式。LabelImg 的基础操作顺序打开图片目录选择保存目录右上角格式选 YOLO按 W 开始画框填类别名称CtrlS 保存D 切下一张这个工具简单到没太多可讲的但一定要定时保存、多备份标签文件。我遇到过软件崩溃导致标签文件没写全后来核查时才发现少了几十张图的数据。如果标注量大、需要多人协作我建议上 CVAT。CVAT 是一个在线标注平台支持矩形框、多边形、关键点等类型导出时直接选 YOLO 1.1 格式压缩包解压后就是images和labels的目录结构正好迎合ultralytics的读取规则。唯一麻烦的是部署 CVAT 需要 Docker本地起一个服务对新手有点门槛但标注体验确实比单机工具好太多。2.3 数据格式转换YOLO、COCO、MOT16 之间怎么转YOLO 格式的 txt 文件每行是五个数字class_id x_center y_center width height其中坐标全部是归一化到 0 到 1 的浮点数分别表示中心点横坐标、中心点纵坐标、框宽、框高。这是 YOLO 训练的标准输入格式。如果你拿到的是 COCO 格式的 JSON 标注或者要转成 COCO 格式给其他模型用就必须写转换脚本。我通常用一段 Python 做 COCO 转 YOLOimport json import os from PIL import Image def coco_to_yolo(json_path, img_dir, out_dir): with open(json_path, r, encodingutf-8) as f: data json.load(f) images {img[id]: img for img in data[images]} categories {cat[id]: idx for idx, cat in enumerate(data[categories])} for img_info in images.values(): img_path os.path.join(img_dir, img_info[file_name]) w, h Image.open(img_path).size txt_path os.path.join(out_dir, img_info[file_name].rsplit(., 1)[0] .txt) with open(txt_path, w) as f: for ann in data[annotations]: if ann[image_id] ! img_info[id]: continue x, y, bw, bh ann[bbox] cx (x bw / 2) / w cy (y bh / 2) / h nw bw / w nh bh / h f.write(f{categories[ann[category_id]]} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}\n)MOT16 转 YOLO 也属于常见需求。MOT16 的标注是frame_id, track_id, x, y, w, h, conf, class, visibility要转换成 YOLO 检测格式其实只要按帧读把x y w h归一化写出即可track_id在纯检测任务里可以直接丢弃。做多目标跟踪的时候再考虑保留track_id否则转换脚本写起来很轻量。标注转完之后强烈建议先可视化检查一遍。把图片和标注框画回原图看有没有坐标偏移、归一化出错、类别错配。这一步能省出后面训练排查的大量时间。3. 训练自己的数据集一条命令背后的细节环境配好、数据标好之后训练本身只要一条命令。但这条命令背后的配置、预训练模型、参数语义很多人没有吃透导致模型跑了十几个小时效果还是稀碎。3.1 编写 data.yaml 并检查路径在ultralytics里数据集配置是一个 YAML 文件内容是path: ./datasets/mydata train: images/train val: images/val nc: 2 names: [cat, dog]这里的path是数据集根目录train和val是相对根目录的子目录nc是类别数量names是类别名列表。最容易犯的错是path写错或者 train/val 路径指到了根目录的images而没区分训练集和验证集。另外目录结构一定要和标签目录对得上。YOLO 系列默认会到labels/train下找和images/train同名的 txt 标签文件如果只整理了图片没整理标签训练会报 no labels found甚至直接跳过所有图片。3.2 预训练模型怎么选、从哪下载预训练模型就是别人在大数据集上训练好的权重我们用它做初始化能极大缩短训练时间、提升收敛效果。ultralytics库会自动下载也可以手动下载后放到当前目录。不同规模的模型对比模型体积精度潜力速度适合场景yolov8n.pt小较低快快速验证、边缘设备yolov8s.pt中等中等较快一般落地项目yolov8m.pt偏大较高一般精度优先项目yolov8l.pt大高慢显卡够强时选择yolov8x.pt最大最高最慢追求极致精度如果电脑显存只有 6G 以下我建议用n或s先把流程跑通别一上来就用x。等判断模型潜力不足了再换大模型训练也不迟。很多教程把这一点省略了结果新手直接 OOM。3.3 训练命令和参数不要只会复制粘贴有标注数据文件后训练命令大概长这样yolo train datadata.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0各参数含义如下epochs训练轮数我一般起步 100看收敛情况再增减imgsz输入图片尺寸640 是默认值batch批大小显存允许的情况下尽量大但小数据集太大 batch 反而容易过拟合device0 表示第一张 NVIDIA 显卡CPU 训练则写cpuworkers数据加载线程数Windows 下有时要设为 0 才不会报错我训练过一个小数据集2000 张图、2 个类别用yolov8sbatch 16100 轮大概 2 小时跑完。如果你只有 4G 显存把imgsz降到 480batch 降到 8也能跑只不过精度会受影响。3.4 训练日志里到底在观察什么损失函数与指标训练时终端会输出一堆字段新手容易看晕。核心要关注三组东西box_loss、cls_loss、dfl_loss以及precision、recall、mAP50、mAP50-95。这几类 loss 分别代表边框回归损失、分类损失和分布焦点损失。前几步数值高是正常的关键是看趋势训练 loss 和验证 loss 都在下降说明模型在学训练 loss 降但验证 loss 升说明过拟合了需要加正则、减小模型或增加数据两边都震荡不降大概率是学习率或数据标注的问题。mAP50是 IoU 阈值 0.5 下的平均精度mAP50-95是 0.5 到 0.95 不同阈值下的平均精度后者更严格。我判断模型可不可用一般先看mAP50有没有到 0.9 附近再看mAP50-95是否和 mAP50 差距不大如果差距特别大说明框的位置还不够准。3.5 训练到一半才想到的调整冻结层与恢复训练如果你只是在自己数据集上做微调不是从零训练其实可以冻结模型浅层让模型重点学新数据的高层特征。ultralytics的写法很简单yolo train datadata.yaml modelyolov8s.pt epochs100 freeze10freeze10的意思是冻结前 10 层参数不更新。这样做的好处是显存占用小、训练更快、不容易破坏预训练特征。缺点是如果数据和预训练任务差异很大冻结反而会限制模型。我个人的经验数据量少就冻结数据量大就少冻结甚至不冻结。另外训练中断不一定要从头跑。ultralytics会自动保存last.pt和best.pt继续训练时把model指向last.pt即可yolo train datadata.yaml modelruns/detect/train/weights/last.pt epochs50这里有个小经验last.pt用于断点续训best.pt是验证集表现最好的权重最后部署用best.pt就对了。4. 训练过程中遇到的问题清单踩坑实录这一节没有标准教程的味道全是自己踩过的、帮别人排查过的真实问题。你要是遇到同款报错可以直接对着试。4.1 显存溢出与 OOM最经典的问题是CUDA out of memory。解决办法从简单到复杂排列降低 batch 大小、降低 imgsz、关闭一些数据增强、使用更小模型。多数情况下 batch 减半就行。还有一个隐藏技巧ultralytics支持batch-1它会自动尝试找到当前显存能承载的最大 batch这个功能对新手很友好。如果你训练到一半才 OOM可以先把工作目录下runs里的临时文件清理一下有时是磁盘或缓存占满导致不一定真是显存不够。4.2 损失不下降、指标纹丝不动遇到这种问题我的排查顺序是先确认标注文件没乱随机打开几个 txt和原图可视化对照再看类别数量nc是否匹配然后调学习率学习率太高会导致 loss 乱跳太低会像没训练一样最后看数据集是否存在严重类别不平衡对类别不平衡我自己的处理是不急着加损失函数权重先看每个类别图片数少的类别做复制、旋转、亮度调整这些增强把数量拉平。权重调整是更精细的手段等基础流程稳定后再考虑。4.3 小目标检测效果差小目标始终是 YOLO 系列的痛点。我的数据集里经常有几十像素大小的目标直接 640 输入根本看不清。有效方法有三个调大imgsz到 960 或 1280但显存和训练时间都会上升把原图切成多个 tile 分别训练和推理或者用 SAHI 这类切片推理库。速度和精度怎么平衡取决于你部署端的算力。4.4 AMD 显卡跑 YOLO能装但要有心理准备AMD 显卡用户不是跑不了 YOLO只是比 NVIDIA 麻烦。方案上有两条路一是用 ROCm 版 PyTorch二是走 DirectML 路线。ROCm 对 PyTorch 的支持现在还行但只支持部分 AMD 显卡型号装驱动时还要注意系统版本。DirectML 方案适合推理训练时算子兼容性容易出问题。我自己的建议是AMD 显卡适合做验证和推理展示真正需要长时间训练时租云 GPU 或买 N 卡更省心。这句话可能会被骂但这就是真实的使用体验。如果你非要在 AMD 上硬跑遇到算子报错就先换yolov8n这种小模型能降低一些兼容性问题。4.5 标注错漏和脏数据训练效果差有相当一部分原因是标注团队或者自己打标签时的误操作。比如类别名拼错、框没贴近目标边缘、某些类别漏标。排查这类问题最好的办法是训练结束后的 badcase 分析把预测错误的图全部打印出来人眼看一遍。我发现过一个特别隐蔽的问题某张图的标签坐标超出图片边界YOLO 格式没有报错但那个框的位置离谱训练时把模型带歪了。后来我写了一个清洗脚本把坐标小于 0 或大于 1 的标注全部筛出来删除这个步骤现在是我每次训练前的固定动作。5. 训练完之后的那些事评估、转换和部署模型训练完不代表项目结束后面还有评估、导出、部署三件事。尤其是“YOLO 部署”相关的热词常年居高不下说明很多人卡在这一环节。5.1 用指标判断这个模型能不能用训练结束时看最好的验证指标但那个分数只是一个参考。我的习惯是再跑一遍验证集把best.pt的 precision、recall、mAP 三种指标打出来同时看混淆矩阵。准确率再高如果混淆矩阵里两个相似类别被经常搞混也不能上生产。ultralytics提供了简单命令yolo val modelbest.pt datadata.yaml跑完会生成results.png、confusion_matrix.png、F1_curve.png等结果文件全部在runs/detect/val目录下。新手不用全看懂先看混淆矩阵和 mAP 就够。5.2 导出模型ONNX、TensorRT 与 CPU 部署部署的第一步是导出。PyTorch 权重文件.pt不能直接在绝大多数生产环境跑一般要转成 ONNX 或 TensorRT 格式yolo export modelbest.pt formatonnx imgsz640 yolo export modelbest.pt formatengine device0ONNX 适合跨平台通用部署TensorRT 引擎适合 NVIDIA 显卡上的高性能推理。CPU 设备上则可以考虑formatonnx配合 OpenVINO 加速或者直接用自带 CPU 推理接口速度慢一些但胜在配置简单。部署方式跟业务强相关如果做 Web 服务用 FastAPI 包一个推理接口如果做边缘设备考虑 TensorRT 或者 ONNX Runtime如果是 FPGA 场景那需要把模型量化并导出为 FPGA 工具链支持的格式这一步通常会牺牲一些精度。我建议先跑通 ONNX 再考虑具体硬件适配别一上来就整太复杂。5.3 从检测到更复杂的任务实例分割、跟踪指标与 FPGA检测跑通之后很多朋友会往两个方向扩展一是实例分割输出每个目标的轮廓可以顺便求圆度、面积等几何信息二是多目标跟踪需要额外获取 MOTA、IDF1 等指标。实例分割在ultralytics里的使用方式和检测类似只是模型前缀不同例如yolov8s-seg.pt标注时要用多边形而不是矩形框。如果你只是想从图像里求圆度光靠检测框不够分割后的掩膜才能计算轮廓和圆度。多目标跟踪的指标更复杂一点MOT17 或 MOT16 数据集会带 ground truth需要用跟踪算法跑出轨迹再和真值计算 MOTA、IDF1、FP、FN 等。这个属于进阶内容我后续可以单独写一篇。6. 接下来这块帖子会更新什么标题说了“不定时更新”所以最后简单列一下后续计划也给自己定个方向。6.1 想在 YOLO 里插入自己的模块怎么办有不少人搜“yolo 插入模块”期望能把自己的注意力机制或者检测头加进模型里。这个方向可以做但前提是先把现有代码结构看明白。比如在ultralytics的模型配置中可以通过修改 yaml 文件把新建模块替换某个C2f或Bottleneck前提是模块的前后维度能对齐。我不建议新手直接在源码里乱加很容易把训练管线搞坏。6.2 类似的检测器DEIM 和 YOLO 怎么选除了 YOLO 系DEIM 这类基于 DETR 的检测器也开始进入视线。DEIM 的样本匹配策略更先进在小目标或遮挡场景中有时比 YOLO 表现好但训练配置和学习曲线比 YOLO 陡不少。我在有空时会专门写一篇 DEIM 训练自定义数据集的对比测试把同一个数据集分别在 YOLO 和 DEIM 上跑一遍用指标说话。6.3 新手速成路线先跑通再优化别上来就改结构最后这条是给新手的一个强烈建议第一遍训练不要追求高精度先让流程完整跑通哪怕模型效果一般。能跑通之后再去调参、换大模型、改结构、做部署。我见过太多人卡在“一开始就想搞一个完美模型”上面结果连数据格式都没搞明白白白消耗热情。我自己最开始训练一个设备识别模型时前四天全在配环境和整理数据真正训练只跑了一个多小时。但恰恰是那四天的积累把后面微调花的时间省了下来。这些坑和经验我会不定期更新在这篇帖子下面希望后来者少走一点弯路。
返回列表