YOLOv9自定义数据集:从标注到训练全流程实战
你是不是也遇到过这样的问题:好不容易收集了一堆目标图片,却卡在数据准备环节——标签格式总不对、yaml文件改来改去还是报错、训练启动就提示路径找不到?别急,这篇实战笔记就是为你写的。我们不讲抽象理论,不堆参数配置,只聚焦一件事:用官方YOLOv9镜像,把你的自定义数据集从一张张原始图,变成能跑通的检测模型。整个过程你只需要会复制粘贴命令、会改几行文本,就能完成从零到训完的第一轮迭代。
1. 镜像环境:开箱即用,省掉三天环境踩坑时间
这个镜像不是简单打包了代码,而是把整个YOLOv9训练链路“预装”好了。你不用再为CUDA版本和PyTorch是否匹配发愁,也不用反复重装OpenCV或调试tqdm报错。所有依赖都已对齐验证,直接进环境就能干活。
- 核心框架: pytorch==1.10.0
- CUDA版本: 12.1
- Python版本: 3.8.5
- 主要依赖: torchvision==0.11.0,torchaudio==0.10.0,cudatoolkit=11.3,numpy,opencv-python,pandas,matplotlib,tqdm,seaborn等
- 代码位置:
/root/yolov9
这个环境组合经过实测:在A10/A100/V100显卡上均能稳定运行训练与推理,避免了常见“CUDA out of memory”或“module not found”类问题。如果你之前被环境问题劝退过三次以上,这次真的可以放心往下走。
2. 数据准备:YOLO格式不是玄学,三步搞定
YOLO系列对数据格式要求严格,但其实逻辑非常清晰:每张图配一个txt,每行一个框,坐标归一化。很多新手栽在细节上,比如路径写错、类别ID从1开始、图像尺寸没对齐……我们拆解成最直白的三步:
2.1 标注工具选型与操作要点
推荐使用LabelImg(桌面版)或CVAT(在线协作版)。重点注意三个设置:
- 格式选择YOLO(不是PascalVOC或COCO)
- 保存路径必须和图片路径同级
- 类别名称按顺序写入
data.yaml,ID从0开始(猫=0,狗=1,车=2)
举个例子:你有100张街景图,要标“行人”和“自行车”,那么标注后会生成100个.txt文件,每个文件里可能有类似这样的两行:
0 0.423 0.615 0.124 0.287 1 0.782 0.331 0.189 0.215含义是:第0类(行人)中心x=0.423,y=0.615,宽=0.124,高=0.287(全部除以原图宽高归一化)
2.2 目录结构标准化(关键!)
YOLOv9认的是固定结构。请严格按以下方式组织你的数据(建议直接在镜像里新建):
/root/yolov9/data/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ # 可选,评估用 ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ # 可选 └── data.yamlimages/train/放训练图(如 800 张)labels/train/放对应.txt(文件名必须完全一致,如abc.jpg↔abc.txt)val/同理,建议按 8:2 划分- 所有图片建议统一 resize 到 640×640 或保持原始比例(YOLOv9支持多尺度训练,但初学者建议先固定尺寸)
2.3 data.yaml 文件编写(照抄模板改四行)
在/root/yolov9/data/下新建data.yaml,内容如下(只需改四行):
train: ../data/images/train val: ../data/images/val test: ../data/images/test # 可删 nc: 2 # 类别总数,例如猫+狗=2 names: ['cat', 'dog'] # 类别名,顺序必须和标注ID严格一致注意:train和val路径是相对于 data.yaml 文件的位置,所以写../data/images/train是因为 yaml 在/root/yolov9/data/,而 images 在其子目录下。如果路径写错,训练时会直接报FileNotFoundError: No images found。
3. 训练前检查:三分钟确认,避免两小时白跑
在敲下训练命令前,请花三分钟做这三件事,能避开90%的“训练启动失败”问题:
3.1 检查文件数量是否匹配
进入镜像终端,执行:
cd /root/yolov9 ls data/images/train/ | wc -l ls data/labels/train/ | wc -l两个数字必须完全相等。如果不等,说明有图没标、或标了没存、或文件名大小写不一致(Linux区分大小写!)。
3.2 随机抽样验证标注质量
用OpenCV快速看一张图和它的框是否对得上:
python -c " import cv2 import numpy as np img = cv2.imread('data/images/train/001.jpg') h, w = img.shape[:2] with open('data/labels/train/001.txt') as f: for line in f: cls, cx, cy, bw, bh = map(float, line.strip().split()) x1 = int((cx - bw/2) * w) y1 = int((cy - bh/2) * h) x2 = int((cx + bw/2) * w) y2 = int((cy + bh/2) * h) cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2) cv2.imshow('check', img) cv2.waitKey(0) "如果框明显偏移或出界,说明标注工具导出设置有问题,需重新导出。
3.3 确认环境已激活
镜像启动后默认在base环境,必须手动切换:
conda activate yolov9 python -c "import torch; print(torch.__version__, torch.cuda.is_available())"输出应为1.10.0 True。如果报ModuleNotFoundError或False,说明环境没激活成功。
4. 正式训练:一条命令启动,关键参数解读
确认无误后,执行训练命令(单卡示例):
cd /root/yolov9 python train_dual.py \ --workers 8 \ --device 0 \ --batch 64 \ --data data/data.yaml \ --img 640 \ --cfg models/detect/yolov9-s.yaml \ --weights '' \ --name yolov9-s-custom \ --hyp hyp.scratch-high.yaml \ --min-items 0 \ --epochs 50 \ --close-mosaic 404.1 参数逐项说明(小白友好版)
| 参数 | 含义 | 建议值 | 为什么重要 |
|---|---|---|---|
--data | 指向你的 data.yaml | data/data.yaml | 告诉模型去哪找图和标签,路径错则全盘失败 |
--weights | 初始化权重 | ''(空字符串)表示从头训练 | 如果填yolov9-s.pt就是微调,新手建议从头练一遍感受收敛过程 |
--batch | 一次喂多少张图 | 64(A100)或32(A10) | 太大会OOM,太小收敛慢,根据显存调整 |
--epochs | 总训练轮数 | 50 | 小数据集20~30轮够用,大点的数据50轮较稳妥 |
--close-mosaic | 关闭马赛克增强的轮次 | 40(即最后10轮关闭) | 马赛克增强对小目标友好,但后期关闭更利于精细定位 |
实测提示:YOLOv9-s 在 640×640 输入下,A10 单卡 batch=32 可稳定运行;若显存不足,可降为
--batch 16并加--img 512。
4.2 训练过程观察要点
启动后你会看到类似输出:
Epoch gpu_mem box obj cls labels img_size 1/50 12.4G 0.05214 0.02108 0.01845 128 640 2/50 12.4G 0.04821 0.01987 0.01723 128 640 ...重点关注:
box(定位损失)、obj(置信度损失)、cls(分类损失)是否持续下降(前10轮波动正常,20轮后应明显收敛)labels列数字是否稳定(代表每批有效标注框数,若长期为0说明数据路径或格式错误)- 若某轮突然
box爆涨到 10+,大概率是某张图的标注坐标超出 [0,1] 范围,需回查labels/train/中对应txt
训练完成后,模型保存在:
/root/yolov9/runs/train/yolov9-s-custom/weights/best.pt5. 效果验证:不只是看loss,更要看得见结果
训练完别急着庆祝,先用真实图检验效果。我们跳过复杂评估脚本,用最直观的方式验证:
5.1 快速推理测试(5秒出图)
python detect_dual.py \ --source 'data/images/val/005.jpg' \ --img 640 \ --device 0 \ --weights runs/train/yolov9-s-custom/weights/best.pt \ --name yolov9-custom-test \ --conf 0.25结果图自动保存在:
/root/yolov9/runs/detect/yolov9-custom-test/005.jpg打开这张图,看三点:
- 框有没有漏检(尤其小目标、遮挡目标)?
- 框有没有错检(背景误判为物体)?
- 分类是否正确(猫没被标成狗)?
如果基本合理,说明训练成功;如果大面积漏检,可能是数据量太少或学习率太高,可尝试增加--epochs或降低--lr0(需修改hyp.scratch-high.yaml)。
5.2 量化评估(可选,但推荐)
想看具体指标(mAP@0.5),运行:
python val_dual.py \ --data data/data.yaml \ --weights runs/train/yolov9-s-custom/weights/best.pt \ --batch 32 \ --img 640 \ --task test输出末尾会显示:
Class Images Labels P R mAP50 mAP50-95: 100%|██████████| 25/25 [00:42<00:00, 1.71s/it] all 200 482 0.821 0.763 0.792 0.481重点关注mAP50(IoU=0.5时的平均精度),>0.75 算不错,>0.85 属于优秀。
6. 常见问题直击:那些让你抓狂的报错,这里都有解
我们整理了镜像用户最高频的5个报错及解法,按出现概率排序:
6.1FileNotFoundError: No images found
- 原因:
data.yaml中train:路径写错,或图片/标签文件名不一致(大小写、扩展名.jpg/.JPG) - 解法:用
ls -l data/images/train/ | head和ls -l data/labels/train/ | head对比前10个文件名,确保完全一致
6.2RuntimeError: CUDA out of memory
- 原因:batch size 太大或 img size 太高
- 解法:先降
--batch(32→16→8),再降--img(640→512→416),A10 单卡推荐起始值--batch 16 --img 512
6.3AssertionError: Dataset not found
- 原因:
data.yaml中nc(类别数)和names(类别名列表)长度不一致 - 解法:检查
nc: 2和names: ['a','b']是否都是2个,不能多也不能少
6.4 训练loss不下降,始终在高位震荡
- 原因:学习率过高,或数据标注质量差(大量错标、漏标)
- 解法:在
hyp.scratch-high.yaml中将lr0: 0.01改为lr0: 0.005,或用--weights yolov9-s.pt微调(迁移学习更稳定)
6.5 推理结果全是框,但没标签文字
- 原因:
detect_dual.py默认不显示类别名,需手动添加--hide-labels的反向操作 - 解法:命令中加入
--hide-conf False(显示置信度)和确保data.yaml中names正确,程序会自动读取
7. 进阶提示:让模型更好用的3个实用技巧
训练只是起点,真正落地还要解决实际问题。这些技巧已在多个项目中验证有效:
7.1 小目标检测增强
如果你的数据里有很多小物体(如远距离车辆、小零件),在hyp.scratch-high.yaml中开启:
mosaic: 1.0 # 保持马赛克增强 copy_paste: 0.1 # 添加复制粘贴增强(小目标更鲁棒)并确保--close-mosaic设为0(全程开启)。
7.2 导出ONNX供生产部署
训练完的best.pt可一键转ONNX,方便集成到C++或移动端:
python export.py \ --weights runs/train/yolov9-s-custom/weights/best.pt \ --include onnx \ --img 640 \ --batch 1生成文件:best.onnx,可用OpenCV DNN模块直接加载。
7.3 可视化注意力热力图(调试神器)
想知道模型到底在看哪里?用Grad-CAM:
python gradcam.py \ --weights runs/train/yolov9-s-custom/weights/best.pt \ --source data/images/val/001.jpg \ --img 640输出热力图会叠加在原图上,红色越深表示该区域对预测贡献越大——帮你快速发现标注偏差或背景干扰问题。
8. 总结:你已经掌握了YOLOv9落地的核心闭环
回顾这一路,你完成了:
- 用标准YOLO格式组织自己的数据(不再被格式劝退)
- 写出零错误的
data.yaml(路径、类别、数量三重校验) - 启动一次完整训练并理解每个参数的实际作用(不是盲目复制)
- 用肉眼+数值双验证模型效果(不迷信loss曲线)
- 解决了90%新手会卡住的报错(下次遇到直接翻本节)
YOLOv9不是魔法,它是一套严谨但友好的工程工具。真正的门槛从来不在代码,而在对数据的理解、对错误的耐心排查、对效果的诚实判断。你现在拥有的,已经不是一份教程,而是一个可复用的检测项目骨架——换数据、换类别、换场景,这套流程依然成立。
下一步,试试用你刚训好的模型,处理一批新采集的现场图;或者把best.pt导出成ONNX,嵌入到你的业务系统里。技术的价值,永远在它真正解决问题的那一刻才开始显现。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。