从零开始的YOLO目标检测全流程:数据标注→模型训练→推理验证→结果可视化
很多人入门YOLO,都能很快跑通官方的demo,但一换成自己的数据集就频繁报错:标签格式不对、路径配置出错、训练loss不收敛、推理结果一片空白。本质上,多数教程只讲了训练那一行命令,却没说清数据怎么准备、格式怎么对齐、结果怎么解读。
本文以YOLOv11为例,完整走通从数据标注到可视化落地的全链路,所有步骤均可直接复现,照着操作就能训练出属于自己的目标检测模型。
一、全流程总览
完整的YOLO目标检测项目分为五个核心阶段,每个阶段都有明确的输入输出,前一步的质量直接决定后一步的上限。
动手之前先确认环境已经配置完成:GPU版PyTorch安装正常,ultralytics库可正常导入。如果环境还没搭好,可以先参考环境搭建篇配置完成后再往下走。
二、第一步:数据标注与格式标准化
数据是模型的上限,标注质量直接决定模型能达到的最高精度。这一步也是新手踩坑最多的环节。
2.1 标注工具选型
入门首选LabelImg,轻量易上手,原生支持YOLO格式输出,适合快速上手;如果是团队协作、数据量大,可以用LabelStudio,功能更全面。
LabelImg安装非常简单:
pipinstalllabelImg安装完成后终端输入labelImg即可启动工具。
2.2 标注规范与操作
- 打开工具后,先在左侧「PascalVOC」按钮上点击,切换为「YOLO」格式,确保输出的标签格式正确。
- 用「Create RectBox」框选目标,紧贴目标边缘,不要留过多背景,也不要截断目标主体。
- 选择对应的类别名称,同一场景下类别命名要统一,不要出现大小写、中英文混杂的情况。
- 标注完成后保存,会生成与图片同名的
.txt标签文件。
踩坑提醒:模糊、遮挡严重、无法判断类别的样本,不要强行标注,错误标注的负面影响远大于少几个样本。
2.3 YOLO标签格式详解
每个txt文件对应一张图片,每一行代表一个目标,格式为:
class_id x_center y_center width heightclass_id:类别索引,从0开始,与配置文件中的类别顺序一一对应x_center y_center:边界框中心点坐标,相对于整张图片的归一化值,范围0~1width height:边界框的宽和高,同样是归一化值
归一化的计算方式:
- x_center = 目标中心点x坐标 / 图片宽度
- y_center = 目标中心点y坐标 / 图片高度
- width = 目标宽度 / 图片宽度
- height = 目标高度 / 图片高度
LabelImg切换到YOLO模式后会自动计算并生成这个格式,不需要手动计算。
2.4 标准数据集目录结构
YOLO对目录结构有严格要求,图片和标签必须分目录存放,且文件名一一对应。标准结构如下:
my_dataset/ ├── images/ # 存放所有图片 │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 │ └── test/ # 测试集图片(可选) └── labels/ # 存放所有标签 ├── train/ # 训练集标签,与图片同名 ├── val/ # 验证集标签,与图片同名 └── test/ # 测试集标签(可选)2.5 数据集自动划分脚本
不需要手动拆分文件,用下面的Python脚本可以自动按比例划分训练集和验证集,默认比例8:2,直接复制运行即可。
importosimportrandomimportshutil# 配置路径img_dir="all_images"# 所有图片存放的文件夹label_dir="all_labels"# 所有标签存放的文件夹output_dir="my_dataset"# 输出数据集目录train_ratio=0.8# 训练集比例# 创建目录forsplitin["train","val"]:os.makedirs(os.path.join(output_dir,"images",split),exist_ok=True)os.makedirs(os.path.join(output_dir,"labels",split),exist_ok=True)# 获取所有图片并打乱img_list=[fforfinos.listdir(img_dir)iff.endswith((".jpg",".png",".jpeg"))]random.shuffle(img_list)split_idx=int(len(img_list)*train_ratio)train_imgs=img_list[:split_idx]val_imgs=img_list[split_idx:]# 复制文件forimg_nameintrain_imgs:label_name=os.path.splitext(img_name)[0]+".txt"shutil.copy(os.path.join(img_dir,img_name),os.path.join(output_dir,"images","train",img_name))ifos.path.exists(os.path.join(label_dir,label_name)):shutil.copy(os.path.join(label_dir,label_name),os.path.join(output_dir,"labels","train",label_name))forimg_nameinval_imgs:label_name=os.path.splitext(img_name)[0]+".txt"shutil.copy(os.path.join(img_dir,img_name),os.path.join(output_dir,"images","val",img_name))ifos.path.exists(os.path.join(label_dir,label_name)):shutil.copy(os.path.join(label_dir,label_name),os.path.join(output_dir,"labels","val",label_name))print(f"划分完成,训练集{len(train_imgs)}张,验证集{len(val_imgs)}张")三、第二步:编写数据集配置文件
数据集整理好后,需要一个.yaml配置文件告诉YOLO数据在哪里、有哪些类别。这是新手报错的重灾区,绝大多数「找不到标签」「类别不对应」的问题都源于配置文件写错。
在数据集根目录下新建data.yaml,内容如下:
# 数据集根目录路径,可以写绝对路径,也可以写相对路径path:./my_dataset# 训练集和验证集图片目录,相对于path的路径train:images/trainval:images/valtest:images/test# 没有测试集可以注释掉# 类别数量nc:3# 类别名称,索引从0开始,顺序必须和标注时的顺序完全一致names:0:cat1:dog2:bird避坑指南:
- 类别索引和名称必须和标注时完全对应,标注时的第0类就是names里的0号类别
- 路径不要有中文、空格和特殊字符,Windows下注意路径分隔符用正斜杠
/或者双反斜杠\\- 标注文件里没有目标的图片,可以不用放对应的txt文件,YOLO会自动处理
四、第三步:模型训练
数据准备就绪后,训练本身非常简单,ultralytics已经封装好了完整的训练逻辑,一行命令即可启动。
4.1 模型选型
根据硬件和精度需求选择对应大小的模型,常用的五个版本:
yolo11n.pt:纳米版,速度最快,精度最低,适合边缘部署yolo11s.pt:小型版,性价比最高,多数场景首选yolo11m.pt:中型版,精度更高,速度稍慢yolo11l.pt:大型版,精度高,对显存要求高yolo11x.pt:超大版,精度最高,速度最慢,适合离线高精度场景
新手建议从n或s版本开始,先跑通流程,再换大模型。
4.2 两种训练方式
方式一:命令行训练(推荐,简单直接)
打开终端,激活虚拟环境,执行命令:
yolo trainmodel=yolo11s.ptdata=./my_dataset/data.yamlepochs=100imgsz=640batch=16device=0方式二:Python代码训练(适合二次开发)
新建train.py文件,写入以下代码:
fromultralyticsimportYOLO# 加载预训练模型model=YOLO("yolo11s.pt")# 开始训练results=model.train(data="./my_dataset/data.yaml",epochs=100,# 训练轮次imgsz=640,# 输入图片尺寸batch=16,# 批次大小device=0,# 使用的GPU编号,CPU就写cpuproject="runs/train",# 结果保存目录name="exp1",# 本次实验名称patience=20,# 20轮精度不提升自动早停save=True,)运行脚本即可开始训练。
4.3 核心参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
| epochs | 100 | 训练总轮次,小数据集可以适当减少,大数据集可以增加 |
| batch | 16 | 每批次图片数量,显存不够就调小,如8、4 |
| imgsz | 640 | 输入图片分辨率,小目标多可以调大到800 |
| device | 0 | 计算设备,单GPU写0,多GPU写[0,1],CPU写cpu |
| patience | 50 | 早停轮次,连续多少轮精度不提升就终止训练 |
| lr0 | 0.01 | 初始学习率,数据集小可以适当调小 |
显存不足处理:如果报错「CUDA out of memory」,优先调小batch,其次减小imgsz,Windows下可以把workers设为0。
4.4 训练过程输出
训练启动后,控制台会输出每一轮的训练损失、验证损失、各类精度指标。正常情况下,损失会持续下降,mAP逐步上升后趋于平稳。
训练完成后,所有结果会保存在runs/train/exp1目录下,核心文件:
weights/best.pt:验证集上精度最高的权重,推理首选weights/last.pt:最后一轮训练的权重results.png:所有指标的变化曲线图confusion_matrix.png:混淆矩阵
五、第四步:验证评估与指标解读
训练完成后,需要在验证集上做完整评估,查看模型的真实效果,而不是只看训练loss。
5.1 执行验证
yolo valmodel=runs/train/exp1/weights/best.ptdata=./my_dataset/data.yamldevice=05.2 核心指标解读
验证完成后会输出四个核心指标,分别从不同维度衡量模型性能:
- Precision(精确率):检测出来的目标中,真正是目标的比例。精确率低意味着误检多。
- Recall(召回率):所有真实目标中,被模型检测出来的比例。召回率低意味着漏检多。
- mAP@0.5:IoU阈值设为0.5时的平均精度,是最常用的精度指标,数值越高越好。
- mAP@0.5:0.95:IoU从0.5到0.95每隔0.05取一次平均,更严格地衡量定位精度。
工业落地场景中,优先关注召回率,尤其是缺陷检测这类场景,漏检的代价远大于误检。
5.3 单类别指标
验证结果中会输出每个类别的单独指标,可以清晰看到哪类效果好、哪类效果差。如果某一类精度明显偏低,优先检查该类的标注质量和样本数量,通常是样本太少或者标注不一致导致的。
六、第五步:推理与结果可视化
训练好模型后,就可以用它来做实际检测了,支持单张图片、视频、文件夹批量推理等多种模式。
6.1 命令行快速推理
# 单张图片推理yolo predictmodel=runs/train/exp1/weights/best.ptsource=test.jpgconf=0.25# 视频推理yolo predictmodel=runs/train/exp1/weights/best.ptsource=test.mp4# 整个文件夹批量推理yolo predictmodel=runs/train/exp1/weights/best.ptsource=./test_images/推理结果会自动保存在runs/detect/exp目录下,图片上会自动画好检测框、类别和置信度。
6.2 Python代码推理(灵活可控)
如果需要获取检测坐标、做后续业务逻辑处理,用Python代码调用更灵活:
importcv2fromultralyticsimportYOLO# 加载模型model=YOLO("runs/train/exp1/weights/best.pt")# 读取图片img=cv2.imread("test.jpg")# 执行推理results=model(img,conf=0.25,iou=0.45)# 解析结果forresultinresults:boxes=result.boxesforboxinboxes:# 获取坐标、置信度、类别x1,y1,x2,y2=map(int,box.xyxy[0])conf=float(box.conf[0])cls_id=int(box.cls[0])cls_name=result.names[cls_id]# 画框cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),2)cv2.putText(img,f"{cls_name}{conf:.2f}",(x1,y1-10),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,255,0),2)# 显示或保存cv2.imwrite("result.jpg",img)6.3 训练结果可视化解读
训练目录下的results.png包含了所有指标的变化曲线,是判断训练效果的核心依据:
- 损失曲线(box_loss、cls_loss):持续下降后趋于平稳,说明模型收敛正常。如果验证损失先降后升,说明出现过拟合。
- mAP曲线:持续上升后平稳,最高点对应best.pt权重。
- P、R曲线:精确率和召回率通常是此消彼长的关系,需要根据业务需求调整置信度阈值。
七、新手避坑指南
- 先小批量验证,再全量训练。先用十几张图片跑通整个流程,确认没有报错、数据能正常读取,再上全量数据集,能节省大量时间。
- 标注质量 > 标注数量。100张高质量标注的效果,远好于500张标注混乱的数据。优先保证标注规范,再扩充数据量。
- 不要盲目堆轮次。多数数据集100~200轮就足够收敛,跑太多轮只会过拟合,不会提升泛化能力。配合早停机制即可。
- 报错先看路径。90%的入门报错都是路径问题:yaml里的路径写错、图片和标签文件名不对应、目录结构不对,先排查这几项。
最后
YOLO目标检测的入门门槛其实很低,核心是把数据准备的环节做扎实,剩下的训练、推理框架都已经封装好了。跑通第一个自己的数据集只是开始,后续针对具体场景的优化、改进、部署,才是落地的关键。
如果训练出来的效果不理想,可以优先从数据增强、网络改进、损失调优几个方向入手,后续我们也会逐步拆解各类优化手段。