告别YOLOv8!全面拥抱YOLOv11:最贴心的YOLO"保姆级"教程

Author:Ming

一. 前言
相信点开这篇文章的你,大概率正面临一个实际的机器视觉项目,需要快速掌握一个高效实用的目标检测工具YOLO。因此,本文也不会讲解详细深度学习原理,只教会你如何使用好这个YOLO,如何快速上手、跑通代码、做出一些成果;当然,这其中不可避免的会涉及到深度学习方面的术语,但不用担心,我会用最清晰易懂的方式,为你解释那些基础而关键的概念。
在学习任何工具之前,我们首先得明白它究竟是什么。俗话说:"学必先知其本"。那么,YOLO 到底是什么呢?它是一个软件吗?还是一个算法?
简单来说,YOLO是一个开源的工具库,你可以将其想象成一个工具箱,里面有很多别人已经做好的现成的工具(算法),想要什么视觉的工具,就打开工具箱从里面拿出来用就行了。用什么拿呢?当然是用Python啦。在这篇文章里,我们就用基于 Python 库形式的 YOLOv11,来用Python教大家如何使用YOLOv11。注意,这需要你至少有一些python基础,但不必担心,这里并不会涉及过于复杂的编程技巧。
YOLO 自诞生以来,已经经历了多个版本的迭代。目前主流项目中仍常见 YOLOv5 和 YOLOv8 的身影,它们成熟稳定,社区资源丰富。但随着技术的快速演进,更先进优秀的算法已经出现------YOLOv11 正是当前官方主推的版本,它在精度、速度与易用性之间取得了更好的平衡。
你可能会问:现在不是已经有比 v11 更加先进的版本了吗?没错,YOLO 的迭代确实非常迅速,但 YOLOv11 是目前被官方推荐、文档最全、最适合投入生产的稳定版本 。更重要的是,YOLO 各版本之间的接口设计非常接近,只要你熟练掌握其中任何一个,其他版本也能触类旁通。
事实上,如果你已有深度学习基础,并且能熟练使用 PyTorch,那 YOLO 对你而言更像是一个封装好的视觉工具箱------你可以直接查阅官方文档,快速上手,无需此篇教程。
首先来简要介绍一下YOLO都能做些什么,相信在你读完这篇文章后,你也能亲手训练一个模型来达到下面的效果,并且将其应用到自己的实际项目中。
YOLO最出名的就是它的目标检测(Object Detection)了,你可以训练一个模型,让它识别出图像中你感兴趣的所有物体,并且告诉你每个物体的位置坐标和大小。这在很多任务中非常有用,比如监控安防、自动驾驶,日常的图像分析。

更进一步的是实例分割(Instance Segmentation),它不仅能把图像中不同的对象识别出来,还能精确地把它们从背景中"抠"出来。当你不仅需要知道物体在哪,还想了解它们的具体形状和轮廓时,实例分割就能派上大用场------比如医疗影像分析、机器人视觉等场景。

至于图像分类(Image Classification),可以说是最基础也最经典的任务了。你输入一张图片,模型就会输出一个类别标签和对应的置信度,告诉我们"这张图是什么"。虽然听起来简单,但它却是许多视觉系统的基石。

而姿态估计 (Pose Estimation)则有点特别。它的任务是识别出图像中人体或物体的关键点位置,比如关节、五官等。模型会输出一组带置信度的坐标点,帮助我们理解对象的姿态结构。无论是体育动作分析、互动游戏,还是人机交互,姿态估计都能提供非常有价值的信息。

在本文中,我们将重点手把手教你如何用 YOLO 完成目标检测 和图像分类。掌握这两项核心任务之后,像姿态估计、实例分割,甚至是 OBB(Oriented Bounding Box)等进阶功能,对你来说都将触类旁通,只需要查阅官方文档稍作了解,就能轻松上手。
为了顺利完成本教程的学习和实践,你需要准备一台搭载现代英伟达显卡的 Windows 电脑(苹果电脑也完全可以,不过本教程将以 Windows 系统为例进行演示)。此外,还需要你具备一定的 Python 基础,以及熟悉一些基本的Windows 操作。
二. 环境搭建
2.1 Python版本号查看
相信你的电脑里已经安装好了 Python 吧?这里就不再赘述 Python 的安装过程了,但有一点必须强调:请确保你的 Python 版本 ≥ 3.8(这是官方明确要求的最低版本)。
如何查看Python版本号?很简单,按下 Win + R 组合键打开"运行"对话框,输入 cmd 并回车,进入命令行窗口 。在黑色的命令行窗口中输入 python 后回车,屏幕上就会显示你的 Python 版本信息。

如果你输入 python 后没有看到版本信息,而是提示"找不到'python'命令",那要么是你还没装Python,要么就是你在安装Python的时候没有勾选"Add Python to PATH"选项。

2.2 Pytorch的安装
如果你已经安装好了 PyTorch,并且确认能够正常使用,可以跳过本节内容。
🤔什么是 PyTorch?为什么需要安装它? 简单来说,只要你涉足深度学习,PyTorch 几乎是绕不开的核心组件。它是一个基于 Python 的深度学习框架,你可以非常灵活地使用它来构建、训练和部署各类深度学习模型。正因为其底层设计强大且通用,绝大多数现代 AI 模型(包括 YOLO 系列)都是基于 PyTorch 开发的。因此,想在本地顺利运行 YOLOv11,安装 PyTorch 是必不可少的一步。(Pytorch是一个Python库,在python中它的名称为torch)
很多刚入门机器学习的同学会问我:"有没有必要系统学习 PyTorch?"我的回答通常是:"现阶段没有必要,先把机器学习和深度学习的基础理论打扎实。PyTorch 本质上是一个工具,当你理解了模型和算法之后,再来学习使用 PyTorch 就会水到渠成。"
举个例子吧,想象一下,你交给一位数学博士生一个卡西欧计算器,让他计算如下积分:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> ∫ 0 2 l n ( 1 + x 3 ) s i n ( x ) x d x \int_{0}^{2} ln(1+x^{3})\frac{sin(x)}{x}dx </math>∫02ln(1+x3)xsin(x)dx
他只需要按部就班地输入表达式,计算器自然会返回答案;但如果你把这个同样的计算器交给一个小学生,让他算出这个式子的结果,他可能无从下手,为什么?因为他都看不懂这些符号,甚至觉得这是英语题,更别说要去按哪个键了!这里的"计算器",就相当于 PyTorch。它只是一个工具,会不会用,用的好不好,取决于使用者的理论基础。
当然了,想要用好 YOLO,你并不需要精通 PyTorch,不过如果你会Pytroch的话就更好了。
本文提供安装方式是全局安装,就是最普通的安装方式,默认会将 PyTorch 安装到 C 盘。如果你有能力,可以在虚拟环境中安装,这样以后不用的时候也方便卸载和项目管理。
当然了,如果你不想折腾,尤其是 Python 新手,我强烈推荐全局安装的方式,这能帮你避开很多环境配置的"坑",免去很多麻烦。
⚠️ 需要注意的是,PyTorch 及其相关组件体积较大,总共约 3GB 左右。如果你选择全局安装,请务必确保 C 盘有足够的剩余空间。放心,即便未来你不再使用 YOLO,本文也会教你如何彻底移除这些文件。
首先,你需要确定自己的电脑显卡型号,因为这将决定你要安装哪个版本的Pytorch。
在命令行窗口(cmd) 输入nvidia-smi并且回车来查看本机显卡信息

如果你输入命令出现了上述界面,请确保你的CUDA版本要大于等于11.8,否则就要去更新显卡驱动;
如果你的电脑没有独立英伟达显卡,或显卡太老 ,那么你只能用CPU来进行模型的训练和推理,这会比使用显卡(GPU)的慢很多,但用来学习和测试是完全没问题的。这种情况你就要在命令行窗口(cmd) 输入下述命令并回车来安装CPU版本的Pytorch:
shell
pip install torch torchvision torchaudio
如果你的显卡是RTX 30/40 系列等,你可以使用下面的指令来安装Pytorch
shell
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
如果你的显卡是RTX50系列的显卡,你必须使用下面的指令来安装Pytorch
shell
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu129
如果你的显卡是稍微老一点的显卡,你可以使用下面的指令来安装Pytorch
shell
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
💡 小提示:PyTorch 的安装包体积较大,下载过程可能需要一些时间,请耐心等待。
当安装顺利完成后,命令行最后通常会显示 Successfully installed... 的提示。
最后,为确保一切正常,请你运行下面这段简单的 Python 测试代码,来检查 PyTorch 是否成功安装并能够识别你的硬件设备:
python
import torch
print(f"PyTorch 版本: {torch.__version__}")
print(f"显卡是否可用: {'是' if torch.cuda.is_available() else '否'}")
if torch.cuda.is_available():
print(f"当前 GPU: {torch.cuda.get_device_name(0)}")
如果输出中显示"显卡是否可用: 是",并正确识别出你的显卡型号,那么恭喜你------环境配置成功!
如果上述方法都无法顺利安装,或者在某个步骤(很多时候是下载速度太慢了)卡住了,别担心,推荐使用DeepSeek或者豆包这种大语言模型来进行一对一疑难解决,请耐心、详细地向它描述你遇到的问题(例如,完整复制错误信息),相信AI会给你答案。无论你最后是通过何种方式安装好的Pytorch,请务必要运行一次上面的Python测试代码,来检查Pytorch是否安装成功。
2.3 YOLO的安装
当你已经顺利安装好 PyTorch 之后,安装 YOLO 就变得非常简单了,只需打开你的命令行窗口(cmd),输入下面这行指令并按下回车,系统就会自动帮你完成 YOLO 框架的安装:
shell
pip install ultralytics
安装完成后,请运行一下下面的Python代码。如果运行后没有出现任何报错,并且打印出了"YOLO 安装成功!",那么就代表你已经安装成功了。可以正式进入YOLO的学习了。
python
from ultralytics import YOLO
print("YOLO 安装成功!")
2.4 预训练模型的下载
什么是预训练模型?简单来说,预训练模型就像一位"已经读过万卷书"的学者------它已经在海量的图像数据集(例如 ImageNet、COCO 等)上进行了充分的训练,能够识别出成百上千种常见物体。换句话说,它已经具备了较强的图像识别能力,是一个"半成品"模型。
当我们希望它学习某个特定任务时(比如识别某一种特殊的物体),并不需要让它从零开始学习。相反,我们可以基于它已经掌握的通用视觉知识,用我们自己的小数据集去"微调"(Fine-tuning)它。这样做的好处非常明显:
- 训练效率更高:模型不需要重新学习所有底层特征;
- 数据需求量更少:即使我们只有几百张图像,也能取得不错的效果;
- 收敛速度更快:相比从零训练,训练时间大幅缩短。
这背后的原理,正是迁移学习(Transfer Learning)的思想------将在一个任务中学到的知识,迁移到另一个相关任务中。
举个例子吧,想象一下,你现在要教一位全能型厨师做一道他还没见过的菜,但他已经精通西、日、韩等各类菜系的基本技法(就像预训练模型掌握了通用特征提取能力)。
这时,你想让他专门学会做 「四川麻婆豆腐」 这道菜。
有两种培养路径:
- 方法 A(从零开始训练): 你让他忘掉所有厨艺基础,只给他一堆豆腐和辣椒,让他自己摸索怎么做麻婆豆腐。他可能需要失败几百次、花上好几个月,才能勉强做出一道像样的菜------这就像我们不用预训练模型,只用自己的小数据集从头训练,效率极低且效果难以保证。
- 方法 B(使用预训练模型 + 微调) : 你直接请出那位全能厨师,递给他一份简洁的 《麻婆豆腐专属食谱》(这就是你的小数据集),里面记录了这道菜的关键要领:比如"豆瓣酱要炒出红油"、"花椒要在起锅前撒入"等等。 这位厨师凭借他原有的烹饪功底,很快就能心领神会,做出一道正宗的麻婆豆腐------这正是"预训练 + 微调"的巧妙之处。
你可以在这个【下载链接】中获取到YOLO官方提供的小体积预训练模型,其中yolo11s-cls.pt是图像分类任务的预训练模型,yolo11s.pt是目标检测任务的预训练模型(平衡了精度与体积)。下载后你可以将其放到电脑中任何一个你喜欢的位置。只要不要忘了放在哪就行。

你可以看到,YOLO官方网站上在同一个任务下提供了不同体积的预训练模型,体积越大(模型参数越多,占用空间越大)的预训练模型,识别图像的效果肯定是越好,但是也好不到哪里去,有时候体积提升80%,但识别效果就提升3%,性价比不高;而且大体积的模型还不好训练,对硬件要求较高。具体根据你的任务要求来选择模型。这就好比买车,不是发动机排量越大越好,我们需要考虑性价比 和使用场景。
2.5 YOLO及其组件的彻底卸载
如果你未来不打算使用YOLO了,可以参考下方教程卸载YOLO及其组件
🟢 情况一:使用虚拟环境安装
如果你是在 Conda 或 Venv 等虚拟环境中安装的 YOLO,卸载会非常简单直接------直接删除整个虚拟环境文件夹即可,环境内所有安装的包都会一并清除,不会对系统其他部分造成任何影响。
🟡 情况二:全局安装的普通卸载
如果你是默认全局安装到了系统中(比如 C 盘),你需要在**命令行窗口(cmd)**中输入以下命令,卸载 PyTorch和YOLO 及其相关核心组件。
shell
pip uninstall torch torchvision torchaudio torchtriton pytorch-triton ultralytics
接着,清理 pip 的缓存文件,释放磁盘空间:
shell
pip cache purge
完成这两步后,PyTorch 和 YOLO主体部分就已经被移除了,缓存也清理干净。不过,系统中可能还会残留一些附属组件和配置文件,它们通常散落在不同位置,手动清理比较困难。其实,保留这些残留组件通常不会影响电脑日常使用,最多只是占用少量 C 盘空间。如果你不打算继续使用 YOLO 或 PyTorch,但又不想大动干戈,到这里其实已经足够了。
🔴 情况三:追求完美的"彻底卸载"
如果你打算未来一段时间内都不再使用 Python 进行 AI 开发,或者你有"洁癖",希望系统回归最干净的状态,可以在**命令行窗口(cmd)**输入下述指令并回车↩︎,这条指令的意思是卸载当前 Python 环境中所有通过 pip 安装的包。
shell
for /F "delims==" %i in ('pip freeze') do pip uninstall -y %i
执行完毕后,系统中就只剩下 Python 解释器本身了。此时,你可以卸载 Python。完成之后,你的系统就基本回到了安装前的状态。如果你之后还需要使用 Python,重新下载安装一个全新版本即可,这样就是一个"从零开始"的纯净环境。
三. 分类任务
本篇教程的做风在实践中学习,在项目中成长";在这一章节中,我们将一起完成一个完整的图像分类项目------从数据准备到模型训练,让你真正掌握YOLOv11在分类任务中的应用。
什么是分类任务? 想象一下,当你看到一张花的照片时,能够立刻认出它是玫瑰还是向日葵------这就是图像分类要解决的问题。在AI世界中,分类任务就是让计算机学会这种"识别"能力:你预先定义好若干类别(比如不同品种的花),然后给模型输入一张图片,它就能告诉你这张图片最可能属于哪个类别。

3.1 准备数据集
俗话说"巧妇难为无米之炊",没有高质量的数据集,再先进的算法也无用武之地。这里以"花卉种类识别"为例,详细讲解如何准备一个规范的分类数据集。
假设我们要训练一个能够识别4种花卉的模型:向日葵(sunflower)、玫瑰(rose)、郁金香(tulip)和兰花(orchid)。你需要按照以下目录结构组织你的数据:
bash
flowersdataset/
│
├── train/ # 训练集 - 用于模型学习
│ ├── sunflower/ # 向日葵类别,存放所有向日葵的训练图片
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ ├── rose/ # 玫瑰类别,存放所有玫瑰的训练图片
│ ├── tulip/ # 郁金香类别,存放所有郁金香的训练图片
│ └── orchid/ # 兰花类别,存放所有兰花的训练图片
│
└── test/ # 测试集 - 用于评估模型
├── sunflower/
├── rose/
├── tulip/
└── orchid/
你需要创建一个名为"flowersdataset"的主文件夹(名称可以任意取,最好是英文),然后在主文件夹下再创建train和test两个文件夹(这两个文件夹名称不能改,必须是这个!);最后,在每个文件夹内,为每个类别创建对应的子文件夹(建议使用英文类别名),然后在各自类别下的文件夹中放置各自类别的图片。
这里你可能会问,为什么有"train"和"test"两个文件夹?全部放到一个文件夹中不就好了吗?这里的train是指训练集,就是AI实际上会用这个文件夹中的图像来进行训练。如果此时没有测试集(test),那就会出现一个问题,我怎么知道我训练的AI效果好不好,是不是在训练集上过拟合?
- 训练集 就像是学生的"教科书"和"练习册"。AI通过反复学习这里的图片,来掌握"向日葵"、"玫瑰"长什么样。
- 测试集 则是从未见过的"期末考试试卷"。它不参与学习过程,专门用于评估AI是否真正理解了知识,而不是仅仅记住了练习册上的答案。
如果没有测试集,我们可能会训练出一个在"练习册"上得满分,但一遇到新题目就抓瞎的"书呆子模型",这种现象就是过拟合。测试集让我们能在训练过程中随时"抽考"模型,客观地衡量它的真实水平。
一个经典且稳妥的做法是按照 8:2 或 9:1 的比例来划分。例如,如果你有1000张向日葵的图片,那么放800张到 train/sunflower 文件夹,剩下的200张放入 test/sunflower。这能确保模型有足够的数据学习,同时也有充足的数据进行测试。
关于图片的大小和格式,也是有要求的,具体要求如下:
- 格式统一 :虽然YOLO支持多种格式,但强烈建议将所有图片统一为
.jpg格式。这不仅减少了潜在的兼容性问题,而且通常拥有更小的体积和更快的处理速度。 - 尺寸统一 :YOLO模型期望输入的是正方形图片 。最常用的尺寸是 640x640 像素。**通常你不需要手动裁剪每一张图,YOLO会自动帮你完成缩放和填充。**当然,如果你能提前用工具批量处理好,训练效率会更高。
- 命名自由 :图片的文件名可以任意取,
123.jpg或a_beautiful_flower.jpg都可以,YOLO不关心这个。只要保证文件名不重复,你自己能管理即可。
图片预处理(如批量格式转换、重命名、智能裁剪)是一个重要的步骤,但为了不冲淡本教程的主题,不在此处细讲,大家可以自行搜索图片预处理的工具,另外我已将一些高效的批量处理工具和详细使用说明 整理打包,放在了上文提供的网盘链接中了,名称为常用Python预处理脚本.zip,大家可以自行下载使用。
本篇教程将会以一个插画/现实(real/illustration)二分类任务为例,带大家手把手走一遍用YOLOv11进行分类任务的全流程,我们要训练一个能自动区分"真实照片"与"动漫插画"的智能分类模型 。(题外话:如果你有超级多人类画师的画和AI绘画的画,你也可以训练一个二分类模型来分辨一张图是不是AI画的)
数据集可以在上文提供的网盘链接中下载,名为classify_dataset.zip,下载并解压后,你会发现其文件夹结构与上述规范完全一致。这就像一个标准的"分类项目模板",请你在未来组织自己的数据时,也务必遵循同样的规范------清晰的结构是高效训练的前提,它能帮你避免大量不必要的麻烦。

3.2 模型训练
相比数据集的收集和预处理,模型训练的过程则显得非常简单,得益于YOLO框架优秀的封装,让AI"学有所成"的核心步骤,仅仅只需几行代码!
请在你的Python环境中新建一个py文件,并输入以下代码:
python
from ultralytics import YOLO # 导入YOLO库
# 确保在主程序中运行
if __name__ == "__main__":
# 1. 载入预训练模型,请务必替换为你自己的文件路径
model = YOLO(r"D:/WorkSpace/yolo11s-cls.pt")
# 2. 启动训练!
results = model.train(
data=r"D:/WorkSpace/classify_dataset", # 数据集的根目录路径
batch=0.75, # 批次大小,设为显存的75%
project="classification_training_results", # 保存训练结果的文件夹名
deterministic=False, # 允许非确定性以加速训练
epochs=30, # 训练30轮
imgsz=640, # 输入图像缩放为640x640
degrees=60, # 随机旋转增强:±60度
flipud=0.3, # 30%概率上下翻转
fliplr=0.3, # 30%概率左右翻转
)
接下来,我们逐一拆解这些参数,让你彻底明白每行代码的意思。
part1. 模型初始化
model = YOLO(r"D:/WorkSpace/yolo11s-cls.pt")就是加载预训练模型,将其中的地址更换为你自己的yolo11s-cls.pt文件存放地址。results = model.train()就是开始执行训练,其中可以在train中详细配置此次训练的各种参数。
part2. train中可配置的重要参数:
这些参数决定了模型如何学习,直接影响最终效果:
data:告诉模型你的数据集放在哪里。batch:控制"学习强度"与"硬件占用",范围在0~1,设置的越大,训练速度越快。但不能太大,如果训练时出现显存不足(OOM)错误,适当调低这个值(如0.5);这里设置为0.75,意味着程序会动态计算,使用你GPU约75%的显存来进行训练。project:就是训练好的结果要存放的文件夹,这里输入的是文件夹名称,可以任意命名。epochs:定义模型将完整数据集学习多少轮,你可以理解为循环几轮,设置的越大,训练时间越久,效果越好。轮数太少,模型学不透;轮数太多,不仅耗时,还可能"学傻"(过拟合),一般推荐10~30就足够可以收敛,总之根据验证集效果调整。imgsz:统一输入图像的尺寸。若设置为640,所有图像在训练前都会被智能缩放或填充为640x640的正方形。**这个值必须与你预处理图片时的尺寸一致。**如果你的训练集图片是480x480的正方形图片,那么这个参数就要设为480。
除此之外,还有很多参数可以配置,我罗列一些比较重要的参数,你需要的时候可以自行查看:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
time |
float |
None |
最长训练时间(以小时为单位)。如果设置此参数,它将覆盖 epochs 参数,允许训练在指定时长后自动停止。适用于时间受限的训练场景。 |
patience |
int |
100 |
在验证指标没有改善的情况下,等待多少个epoch后提前停止训练。通过在性能停滞时停止训练,有助于防止过拟合。 |
save_period |
int |
-1 |
保存模型检查点的频率,以 epoch 为单位指定。值为 -1 时禁用此功能。适用于在长时间训练期间保存临时模型。 |
cache |
bool |
False |
启用在内存中缓存数据集图像(True/ram),在磁盘上缓存(disk),或禁用缓存(False)。通过减少磁盘 I/O 来提高训练速度,但会增加内存使用量。 |
device |
int 或 str 或 list |
None |
指定用于训练的计算设备:单个 GPU(device=0),多个 GPU(device=[0,1]),CPU(device=cpu),适用于 Apple 芯片的 MPS(device=mps),或自动选择最空闲的 GPU(device=-1)或多个空闲 GPU (device=[-1,-1]) |
workers |
int |
8 |
用于数据加载的工作线程数(每个 RANK ,如果是多 GPU 训练)。影响数据预处理和输入模型的速度,在多 GPU 设置中尤其有用。 |
project |
str |
None |
项目目录的名称,训练输出保存在此目录中。允许有组织地存储不同的实验。 |
name |
str |
None |
训练运行的名称。用于在项目文件夹中创建一个子目录,训练日志和输出存储在该子目录中。 |
optimizer |
str |
'auto' |
训练优化器的选择。选项包括 SGD, Adam, AdamW, NAdam, RAdam, RMSProp 等等,或者 auto 用于基于模型配置自动选择。影响收敛速度和稳定性。 |
deterministic |
bool |
True |
强制使用确定性算法,确保可重复性,但由于限制了非确定性算法,可能会影响性能和速度。 |
single_cls |
bool |
False |
在多类别数据集中,将所有类别视为单个类别进行训练。适用于二元分类任务或侧重于对象是否存在而非分类时。 |
classes |
list[int] |
None |
指定要训练的类 ID 列表。可用于在训练期间过滤掉并仅关注某些类。 |
rect |
bool |
False |
启用最小填充策略------批量中的图像被最小程度地填充以达到一个共同的大小,最长边等于 imgsz。可以提高效率和速度,但可能会影响模型精度。 |
multi_scale |
bool |
False |
通过增加/减少来启用多尺度训练 imgsz 高达 0.5 在训练期间。训练模型,使其在多次迭代中更加准确 imgsz 在推理过程中。 |
cos_lr |
bool |
False |
使用余弦学习率调度器,在 epochs 上按照余弦曲线调整学习率。有助于管理学习率,从而实现更好的收敛。 |
close_mosaic |
int |
10 |
在最后 N 个 epochs 中禁用 mosaic数据增强,以在完成前稳定训练。设置为 0 可禁用此功能。 |
resume |
bool |
False |
从上次保存的检查点恢复训练。自动加载模型权重、优化器状态和 epoch 计数,无缝继续训练。 |
amp |
bool |
True |
启用自动混合精度(AMP)训练,减少内存使用,并可能在对准确性影响最小的情况下加快训练速度。 |
fraction |
float |
1.0 |
指定用于训练的数据集比例。允许在完整数据集的子集上进行训练,这在实验或资源有限时非常有用。 |
freeze |
int 或 list |
None |
冻结模型的前 N 层或按索引指定的层,从而减少可训练参数的数量。适用于微调或迁移学习。 |
lr0 |
float |
0.01 |
初始学习率(即 SGD=1E-2, Adam=1E-3)。调整此值对于优化过程至关重要,它会影响模型权重更新的速度。 |
lrf |
float |
0.01 |
最终学习率作为初始速率的一部分 = (lr0 * lrf),与调度器结合使用以随时间调整学习率。 |
weight_decay |
float |
0.0005 |
L2 正则化项,惩罚大权重以防止过拟合。 |
dropout |
float |
0.0 |
分类任务中用于正则化的 Dropout 率,通过在训练期间随机省略单元来防止过拟合。 |
最后,关掉网络(建议您暂时断开网络连接 。这可以防止因环境自动尝试下载更新或额外模型而可能引发的意外错误,确保训练过程纯净、可控。),将你配置好的代码直接用Python运行,它就开始进行训练了。(注意:请务必在 .py 文件中执行上述训练代码,而非 Jupyter Notebook 等交互式环境。)
在程序运行的过程中,你可以看到控制台输出的这些内容

以上图为例,逐一解读这些关键指标的意义:
Epoch n/30这表示训练的总轮数(epochs)设置为30,当前正处于第n轮。你可以直观地看到训练进度,预估剩余时间。GPU_mem 7.96G这显示了当前训练任务占用的GPU显存。它是你调整batch参数的重要参考------如果此处接近你的显存上限,下次训练时可适当调低batch值。loss(损失函数值) 这是模型预测与真实标签之间的误差,是评估模型学习效果的核心指标 。- 理想情况:loss 值随训练轮数稳定下降,说明模型正在有效学习。
- 警惕过拟合:如果 loss 降至极低(如 0.01 以下),但测试集准确率不高,则模型可能"死记硬背"了训练集,泛化能力差。
- 警惕欠拟合:如果 loss 在较高数值(如 1.0 左右)徘徊不下,说明模型未能从数据中学到有效规律,需要检查数据质量、模型结构或学习率。
top1_acc 0.929这代表了模型在测试集 上的Top-1准确率 ,即模型认为最可能的那个答案正好是正确答案的概率。0.929 意味着当前模型在测试集上达到了 92.9% 的识别准确率,这说明它已经是一个非常可靠的"次元鉴定师"了。
当控制台出现类似下图的提示,并最终停止运行时,就代表已经训练完了。此时,所有训练成果------包括最终模型权重、训练过程图表、详细配置等------都已自动保存在你指定的 classification_training_results 文件夹中。

3.3 结果数据解读
如果你多次运行训练代码,会在 classification_training_results 目录下看到多个 train、train2、train3......这样的文件夹。每一个都对应着你某一次训练过程的完整记录。
找到你成功的那次训练所对应的train文件夹,点进去,这里面的内容就是你此次训练的结果。接下来,就让我来讲一讲这里面的各个文件都是什么意思。
3.3.1 📈核心图表:results.png
这张图是评估训练过程最直观的工具,它由四个子图表构成,横轴(X轴)均为0到30的训练轮次(Epoch),清晰地展示了模型在整个学习周期中的表现轨迹。
train/loss(训练集损失) 这条曲线反映了模型在"练习题"(训练集)上犯错的减少过程。 理想情况下,它应随着训练轮次的增加而稳步下降,并最终趋于平稳。这证明模型正在从你提供的数据中有效地学习知识。如果曲线剧烈波动或无法下降,则说明模型"学不进去",可能遇到了数据或结构问题。val/loss(验证集损失) 这是模型在"模拟考卷"(验证集)上的犯错情况,是检测"过拟合"的关键指标。 最健康的状态是:验证集损失随着训练集损失一同下降,且二者在训练后期数值较为接近。如果训练集损失持续下降,但验证集损失在中后期反而开始回升,这就是一个典型的过拟合信号------模型对训练数据"死记硬背",丧失了举一反三的能力。metrics/accuracy_top1(Top-1 准确率) 这是我们最关心的指标:模型在验证集上的"考试分数"。 它直接告诉你,模型做出的第一个预测是正确的概率。这个值越高越好,我们训练的终极目标就是让这条曲线稳步攀升至高位(例如95%以上)并保持稳定。图中曲线平稳上升至0.95以上,表明我们的模型已经成长为一位优秀的"次元鉴定师"。metrics/accuracy_top5此指标在多分类任务(类别数≥5)中更有意义,它表示正确答案出现在模型预测的前五个可能中的概率。由于我们的任务是"照片/插画"二分类,Top1准确率已经足够说明问题,因此可以暂不深入关注此指标。
results.csv表格中的数据就是上述图表的具体数据,那个图表就是以这个数据来绘制的。results.csv表格中有一个time列,表明到达每一个epoch所耗费的时间,单位是秒。

3.3.2 📊 数据本源:results.csv
上面所讲的 results.png 图表,就是由此文件中的数据直接绘制而成。如果你需要对模型的表现进行更加精确的分析,你可能会需要这些精确数据。
另外,这个表中有特别实用的一个字段是 time 列 ,它记录了完成每一轮训练所耗费的时间,单位是秒。
3.3.3⚙️ 训练蓝图:args.yaml 文件
这个文件完整记录了你本次训练在 model.train() 中设置的所有超参数。你可以把它理解为这次训练的 "配方"或"技术图纸"。一般情况下它没什么用,除非你要精确复现。
3.3.4 📑 归一化混淆矩阵
在评估模型性能时,confusion_matrix_normalized.png(归一化混淆矩阵)是一份非常直观的"诊断报告"。它清晰地揭示了模型在哪些地方做对了,在哪些地方容易混淆。【可以不用管confusion_matrix.png,这两个本质是一样的】
以本教程的二分类任务为例,你会看到一个 2x2 的网格,其基本结构如下

- 底部横坐标 (True Label): 表示图片实际 的类别(
illustration插画,real真实照片)。 - 左侧纵坐标 (Predicted Label): 表示模型预测的类别。
对角线上的格子(从左上到右下)代表预测正确的部分,颜色越深、数值越高,说明模型表现越好。
来依次看看每个格子代表什么意思:
-
第一行第一列 (0.98),真实标签是插画(illustration),预测的标签也是插画,比率是0.98;这就表明原本是插画标签的图片有98%被预测成了插画。
-
第二行第一列 (0.02),真实标签是插画(illustration),预测的标签是真实图像(real),比率是0.02;这就表明原本是插画标签的图片有2%被预测成了真实照片。
-
其余同理
3.3.5 🍂 模型权重weight
在 weights 文件夹中,保存着本次训练最重要的成果------模型本身,其中best.pt是整个训练过程中性能最优的效果最好的模型权重,它在测试集上综合表现最佳,是后续使用的首选。
last.pt是训练最后一轮(在本教程中就是第30轮)的模型快照 ,它代表了模型最终达到的状态。如果训练因故中断,您也可以加载 last.pt 从断点处继续训练,无需从头开始。
python
# 从断点处继续训练
from ultralytics import YOLO
if __name__ == "__main__":
model = YOLO("xxxx/last.pt") # 加载你的last.pt模型
results = model.train(resume=True) # 恢复训练
3.3.6 📷其它图片
这里剩余的图片就是模型训练好后进行预测的可视化图片,可以实实切切看到模型的效果,可以用来PPT汇报或文章插图展示。
3.4 模型推理
现在模型已经训练完成,我们也仔细分析了结果文件夹中的各类图表,对模型的性能有了全面的了解。那么,如何将训练好的模型实际应用到我们自己的项目中呢?
其实使用起来非常简单!只需要几行代码,下面是一个完整的示例:
python
from ultralytics import YOLO
# 加载训练好的最佳模型
model = YOLO("xxx/your_training_output_path/best.pt") # 请将此路径替换为你实际的模型保存路径
# 设置待分类的图片路径
source = ["./predict_pic/p4.jpg"] # 单张图片预测,这张图片是一张真实的公路照片
# source = ["./predict_pic/p4.jpg", "./predict_pic/p7.jpg"] # 多张图片批量预测
# 进行预测,设置图片尺寸与训练时保持一致
result = model.predict(source, imgsz=640)
你输入的待分类图片不需要预先调整为训练时的大小,YOLO会自动将其规范化为640×640(如果你训练时使用的是其他尺寸,记得相应调整imgsz参数);此外,YOLO不仅支持单张图片预测,也支持多张图片批量预测,只需在source列表中添加更多图片路径即可
如何解读预测结果。result变量接收到的预测信息是一个列表,因为我们可以一次性输入多张图片。我们以第一张图片(索引为0)为例:
python
# 输出每个类别的预测概率
print(result[0].cpu().probs.data)
# 输出模型预测的类别序号
print(result[0].probs.top1)
# 输出类别序号与类别名称的对应关系
print(result[0].names)
# 输出示例==========================
# tensor([0.0265, 0.9735])
# 1
# {0: 'illustration', 1: 'real'}
从输出结果可以看出,模型预测p4.jpg有97.35%的概率是真实照片(real),只有2.65%的概率是插画(illustration)。模型最终将其分类为类别1,也就是'real'类别。
其实,不止这种形式(source = ["./predict_pic/p4.jpg"])的source,YOLO还支持非常多的图像来源,如下表格中所展示的图像数据类型YOLO均可以批处理,并将结果返回到result中
支持的source
| 来源 | 示例 | 类型 | 备注 |
|---|---|---|---|
| 图像 | 'image.jpg' |
str 或 Path |
单个图像文件。 |
| URL | 'https://ultralytics.com/images/bus.jpg' |
str |
图像的URL。 |
| 截图 | 'screen' |
str |
截取屏幕截图。 |
| PIL | Image.open('image.jpg') |
PIL.Image |
具有RGB通道的HWC格式。 |
| OpenCV | cv2.imread('image.jpg') |
np.ndarray |
具有BGR通道的HWC格式 uint8 (0-255). |
| numpy | np.zeros((640,1280,3)) |
np.ndarray |
具有BGR通道的HWC格式 uint8 (0-255). |
| torch | torch.zeros(16,3,320,640) |
torch.Tensor |
具有RGB通道的BCHW格式 float32 (0.0-1.0). |
| CSV | 'sources.csv' |
str 或 Path |
包含图像、视频或目录路径的CSV文件。 |
| 视频 ✅ | 'video.mp4' |
str 或 Path |
MP4、AVI等格式的视频文件。 |
| 目录 ✅ | 'path/' |
str 或 Path |
包含图像或视频的目录的路径。 |
| glob ✅ | 'path/*.jpg' |
str |
用于匹配多个文件的Glob模式。使用 * 字符作为通配符。 |
| 流 ✅ | 'rtsp://example.com/media.mp4' |
str |
用于流媒体协议的URL,例如RTSP、RTMP、TCP或IP地址。 |
| 多流 ✅ | 'list.streams' |
str 或 Path |
*.streams 包含每行一个流 URL 的文本文件,例如,8 个流将以 batch-size 8 运行。 |
| 网络摄像头 ✅ | 0 |
int |
用于运行推理的已连接摄像头设备的索引。 |
另外,model.predict()函数可以配置很多进阶参数,这里把常用的参数列出来,供大家参考
predict的可选参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
source |
str |
'ultralytics/assets' |
指定推理的数据源。可以是图像路径、视频文件、目录、URL 或实时馈送的设备 ID。 支持多种格式和来源 |
conf |
float |
0.25 |
设置检测的最小置信度阈值。 将忽略置信度低于此阈值的检测到的对象。 调整此值有助于减少误报。 |
iou |
float |
0.7 |
用于非极大值抑制 NMS的IoU阈值。较低的值会通过消除重叠的框来减少检测结果,这对于减少重复项很有用。 |
imgsz |
int 或 tuple |
640 |
定义推理的图像大小。可以是一个整数 640 表示正方形调整大小,也可以是 (height, width) 元组。适当的大小调整可以提高检测准确性和处理速度。 |
rect |
bool |
True |
如果启用,则对图像较短的一边进行最小填充,直到可以被步长整除,以提高推理速度。如果禁用,则在推理期间将图像填充为正方形。 |
half |
bool |
False |
启用半精度 (FP16) 推理,这可以加快在支持的 GPU 上的模型推理速度,同时对准确性的影响极小。 |
device |
str |
None |
指定用于推理的设备(例如, cpu, cuda:0 或 0)。允许用户在 CPU、特定 GPU 或其他计算设备之间进行选择,以执行模型。 |
batch |
int |
1 |
指定推理的批处理大小(仅在源为以下情况时有效: 目录、视频文件或 .txt 文件)。更大的批处理大小可以提供更高的吞吐量,从而缩短推理所需的总时间。 |
max_det |
int |
300 |
每张图像允许的最大检测数量。限制模型在单次推理中可以检测到的对象总数,防止在密集场景中产生过多的输出。 |
vid_stride |
int |
1 |
视频输入的帧步长。允许跳过视频中的帧,以加快处理速度,但会降低时间分辨率。值为 1 时处理每一帧,值越高跳过的帧越多。 |
agnostic_nms |
bool |
False |
启用与类别无关的非极大值抑制 (NMS),它会合并不同类别的重叠框。在类别重叠很常见的多类别检测场景中非常有用。 |
retina_masks |
bool |
False |
返回高分辨率分割掩码。返回的掩码(masks.data)如果启用,将与原始图像大小匹配。如果禁用,它们将具有推理期间使用的图像大小。 |
project |
str |
None |
如果 save 已启用,则为保存预测输出的项目目录的名称。 |
name |
str |
None |
预测运行的名称。用于在项目文件夹中创建一个子目录,如果 save 已启用,则为保存预测输出的项目目录的名称。 |
verbose |
bool |
True |
控制是否在终端中显示详细的推理日志,从而提供有关预测过程的实时反馈。 |
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
show |
bool |
False |
可视化参数: True,则在窗口中显示带注释的图像或视频。这对于开发或测试期间的即时视觉反馈非常有用。 |
save |
bool |
False or True |
启用将带注释的图像或视频保存到文件。这对于文档编制、进一步分析或共享结果非常有用。使用 CLI 时默认为 True,在 python 中使用时默认为 False。 |
save_frames |
bool |
False |
处理视频时,将各个帧另存为图像。这对于提取特定帧或进行详细的逐帧分析非常有用。 |
save_txt |
bool |
False |
以文本文件格式保存检测结果,格式如下: [class] [x_center] [y_center] [width] [height] [confidence]。 有助于与其他分析工具集成。 |
save_conf |
bool |
False |
在保存的文本文件中包含置信度分数。 增强了可用于后处理和分析的细节。 |
save_crop |
bool |
False |
保存检测到的裁剪图像。 有助于数据集增强、分析或为特定对象创建重点数据集。 |
show_labels |
bool |
True |
在可视化输出中显示每个检测的标签。 能够立即理解检测到的对象。 |
show_conf |
bool |
True |
在标签旁边显示每个检测的置信度分数。 可以深入了解模型对每次检测的确定性。 |
show_boxes |
bool |
True |
在检测到的对象周围绘制边界框。 这对于在图像或视频帧中以可视方式识别和定位对象至关重要。 |
line_width |
None or int |
None |
指定边界框的线条宽度。 如果 None,则线条宽度会根据图像大小自动调整。 提供视觉自定义以提高清晰度。 |
你可以看到,YOLO 提供了非常丰富的配置选项,这意味着我们可以高度自定义很多流程。但这也带来了一个问题:这么多参数,如果一时不理解某个选项的具体作用,或者不确定调整后会带来什么效果,该怎么办呢?
这时候,你完全可以向你熟悉的AI大模型提问,在掌握了 YOLO 的基本框架,思想和使用方法之后,这些细节问题完全可以交由 AI 帮你快速解决。
但如果你完全不了解 YOLO,就想让 AI 从头帮你完成一个YOLO视觉项目,那几乎是很困难的,因为这时候你能做的,就是完全依靠AI,你对YOLO的宏观微观理解,都需要AI给你从头搭建,你能做到,只是在AI提供的答案中做出选择;没有扎实的技术基础,仅凭 AI 生成的项目无异于空中楼阁,难以稳固、更难以迭代。但当你对一个项目的整体流程有了清晰概念和想法,AI 就能成为你得力的助手,是你在主导AI,而不是AI在领导你。这正是"懂技术"和"不懂技术"的人在使用 AI 时的关键差异,你的技术基础,决定着你的AI生成能力的上界。工具越是强大,人的思维和视野就越显珍贵。
3.5 图像增强
你应该注意到了,在模型训练的那个章节,我有三个参数没有讲到,如下:
python
degrees=60,
flipud=0.3,
fliplr=0.3,
要想理解这三个参数,就需要知道什么是图像增强。
回到我们之前做的"真实图片 vs 插画"的二分类任务。假设你找不到那么多插画或者真实系列的图片怎么办,如果拿来训练的数据集太少,AI训练的效果会大打折扣。在AI模型训练中,有一个非常直观的规律:训练数据越丰富、越多样,模型的识别精度和泛化能力就越好。
以下面这个动漫图片为例,看似是一张图片,但是我们可以人为增加训练数据集 ,将原始的一张输入图片进行旋转,拉伸,镜像,扭曲,对比度增强等操作,并保持输出形状不变,这样就由一个图片(训练集)变成了多个图片(训练集);图像增强的本质,是通过对原始训练图像进行一系列随机但合理的变换,人为地"创造"出更多样的训练样本。

上面的这张图片就可以转化为如下12张"新图片",如果对你数据集中的每一个图片都这么操作,那么你的数据集一下子就扩充了12倍!

图片增强的核心思想在于,我们希望模型学到的不是简单地"记住"训练集中的图片,而是捕捉到物体最本质、最稳定的特征。无论一个瓶子怎么放,它瓶身的特点、标签的纹理这些关键信息是不变的。图像增强正是通过引入各种"干扰项",强迫模型去关注这些深层、不变的特征,从而成为一个"见过世面"的智能模型。
你不需要手动实现这些复杂的增强操作。YOLO在训练时已经内置了丰富的图像增强功能,只需要在model.train()中配置相应参数即可。如下是YOLO官方给出的可配置参数:
| 参数 | 类型 | 默认值 | 支持的任务 | 范围 | 描述 |
|---|---|---|---|---|---|
hsv_h |
float |
0.015 |
detect, segment, pose, obb, classify |
0.0 - 1.0 |
通过色轮的一小部分调整图像的色调,从而引入颜色变化。帮助模型在不同的光照条件下进行泛化。 |
hsv_s |
float |
0.7 |
detect, segment, pose, obb, classify |
0.0 - 1.0 |
通过一小部分改变图像的饱和度,从而影响颜色的强度。可用于模拟不同的环境条件。 |
hsv_v |
float |
0.4 |
detect, segment, pose, obb, classify |
0.0 - 1.0 |
通过一小部分修改图像的明度(亮度),帮助模型在各种光照条件下表现良好。 |
degrees |
float |
0.0 |
detect, segment, pose, obb |
0.0 - 180 |
在指定的角度范围内随机旋转图像,提高模型识别各种方向物体的能力。 |
translate |
float |
0.1 |
detect, segment, pose, obb |
0.0 - 1.0 |
通过图像尺寸的一小部分在水平和垂直方向上平移图像,帮助学习检测部分可见的物体。 |
scale |
float |
0.5 |
detect, segment, pose, obb, classify |
>=0.0 |
通过增益因子缩放图像,模拟物体与相机的不同距离。 |
shear |
float |
0.0 |
detect, segment, pose, obb |
-180 - +180 |
按指定的角度错切图像,模仿从不同角度观察物体的效果。 |
perspective |
float |
0.0 |
detect, segment, pose, obb |
0.0 - 0.001 |
对图像应用随机透视变换,增强模型理解 3D 空间中物体的能力。 |
flipud |
float |
0.0 |
detect, segment, pose, obb, classify |
0.0 - 1.0 |
以指定的概率将图像上下翻转,增加数据变化,而不影响物体的特征。 |
fliplr |
float |
0.5 |
detect, segment, pose, obb, classify |
0.0 - 1.0 |
以指定的概率将图像左右翻转,有助于学习对称物体并增加数据集的多样性。 |
bgr |
float |
0.0 |
detect, segment, pose, obb |
0.0 - 1.0 |
以指定的概率将图像通道从 RGB 翻转到 BGR,有助于提高对不正确通道排序的鲁棒性。 |
mosaic |
float |
1.0 |
detect, segment, pose, obb |
0.0 - 1.0 |
将四个训练图像组合成一个,模拟不同的场景组成和物体交互。对于复杂的场景理解非常有效。 |
mixup |
float |
0.0 |
detect, segment, pose, obb |
0.0 - 1.0 |
混合两个图像及其标签,创建一个合成图像。通过引入标签噪声和视觉变化,增强模型的泛化能力。 |
cutmix |
float |
0.0 |
detect, segment, pose, obb |
0.0 - 1.0 |
组合两张图像的部分区域,创建局部混合,同时保持清晰的区域。通过创建遮挡场景来增强模型的鲁棒性。 |
copy_paste |
float |
0.0 |
segment |
0.0 - 1.0 |
在图像中复制和粘贴对象,以增加对象实例。 |
copy_paste_mode |
str |
flip |
segment |
- | 指定 copy-paste 要使用的策略。选项包括 'flip' 和 'mixup'. |
auto_augment |
str |
randaugment |
classify |
- | 应用预定义的增强策略 ('randaugment', 'autoaugment'或 'augmix')通过视觉多样性来增强模型性能。 |
erasing |
float |
0.4 |
classify |
0.0 - 0.9 |
在训练过程中随机擦除图像区域,以鼓励模型专注于不太明显的特征。 |
其实不止在图像识别领域可以这么做,在其他领域也可以,比如对于声音作为输入同理,往原始的声音中加入噪音,不同背景的噪音甚至是水下或者电话的声音特效作为新训练集。如果你的训练集是文字识别的话,那么不同的字体显示又可以得到非常多的训练集。
补充知识点:YOLO是如何"智能裁剪",将任意图片变为标准正方形的?
上面我们提到,只要你定义了 imgsz 参数,无论你输入的图片(不论是训练用的图片还是推理用的图片)是横屏的风景照、竖屏的人像,还是各种奇奇怪怪的尺寸,YOLO都能在背后默默地将它们处理成统一大小的正方形张量。其核心方法就是:等比例缩放 + 智能填充。
整个过程可以清晰地分解为以下三步,我们结合下图来理解:

- 等比例缩放长边 :YOLO会首先找到图片原始的长和宽,并识别出最长边 。然后,它会将这条最长边直接缩放到你设定的
imgsz目标尺寸(如640像素)。同时,另一条短边也会按照完全相同的比例进行缩放,以确保图片内容不变形。 - 计算并填充灰边 :上一步缩放后,图片的短边显然还达不到
imgsz的要求。于是,YOLO会在短边的两侧(通常是上下或左右)填充灰色的像素条,我们称之为 "灰边" ,从而将图片"撑"成一个标准的imgsz x imgsz正方形。这个填充过程是自动且精准的,确保目标始终位于画面的正中央。 - 坐标同步调整:对于训练图片而言,填充后图片的几何中心没有改变,所以标注框(Bounding Box)的位置也需要进行相应的同步调整。YOLO在预处理阶段会自动完成这个坐标映射,确保标注信息与处理后的图像严格对齐,为模型的精准学习保驾护航。
为什么要这样设计?
这种方式最大限度地保留原始图像的完整信息和比例,避免因暴力拉伸导致的图像失真和目标变形。无论是训练还是推理,模型接收到的都是尺寸统一、比例协调的数据,这极大地简化了网络的计算过程,提升了模型的泛化能力和预测的稳定性。
四. 目标检测任务
4.1 数据集
如果说分类任务教会模型"图片里是什么",那么目标检测任务就更进一步------不仅要识别出物体,还要精准定位它们的位置,即"在哪里"和"是什么"。这种更复杂的任务,自然需要更丰富的数据组织形式。

与分类任务直接读取主文件夹不同,目标检测任务依赖于一个以 yaml 结尾的数据集配置文件 。这个文件就像整个数据集的"导航地图",训练时程序会读取它来找到所有需要的数据。我们可以自由命名这个文件,这里我们将其命名为 data.yaml。
data.yaml 本质上是一个文本文件,其标准内容结构如下:
shell
path: C:/Users/Ming/Desktop/dataset # 数据集的根目录路径
train: images/train # 训练集图片路径 [相对于根目录]
val: images/val # 验证集图片路径 [相对于根目录]
test: images/test # 测试集图片路径 [相对于根目录] (可选)
# 类别名称与索引的映射关系
names:
0: person
1: bicycle
2: car
3: motorcycle
4: airplane
创建它非常简单:新建一个文本文件(txt),将上述内容复制进去,根据你的实际情况修改路径和类别,最后将文件后缀名改为 .yaml 即可。编辑时,用任何文本编辑器或代码编辑器打开都行。
接下来,你需要按照以下结构来组织你的数据集文件夹:
bash
data.yaml
dataset/
│
├── images/
│ ├── train/ # 存放所有训练图片
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ ├── val/ # 存放所有验证图片
│ └── test/ # 存放所有测试图片 (可选)
│
└── labels/
├── train/ # 存放所有训练图片对应的标签文件
│ ├── img_001.txt
│ ├── img_002.txt
│ └── ...
├── val/ # 存放所有验证图片对应的标签文件
└── test/ # 存放所有测试图片对应的标签文件 (可选)
看到这里,你会发现两个与分类任务显著不同的新元素:一个是多出来的 val (验证集),另一个就是神秘的 labels 文件夹及其中的 .txt 文件。接下来一一说明。
验证集就是模型的"模拟考场" ,在分类章节,我们认识了 训练集(教科书) 和 测试集(期末考试) 。验证集则扮演着 "模拟考试" 的角色。它不直接用于更新模型的权重参数,但会参与训练过程------模型在每个训练阶段后,都会在验证集上"考一次",我们根据它的表现来调整一些训练策略(如学习率)和选择最佳模型,简单来说就是为了在训练过程中,提供一个不参与"学习"的客观评价标准,帮助我们监控模型在未见数据上的泛化能力,防止它变成只会死记硬背"训练集答案"的书呆子,从而挑选出真正"学懂了"的模型。 那么应该放多少图片到验证集呢?一个常用的经验法则是,让验证集的大小与测试集相近即可。
标签文件(txt)就是告诉模型"目标在哪" ,每个图片(如 img_001.jpg)都会有一个同名且同目录结构的 .txt 标签文件(如 labels/train/img_001.txt)。这个文件精确记录了图片中每个需要检测目标的位置和类别。
以img_001.jpg图片为例,如下

其对应的 img_001.txt 文件内容如下:
shell
0 0.48 0.63 0.69 0.71
0 0.74 0.52 0.31 0.93
我们来解读第一行 0 0.48 0.63 0.69 0.71:
- 第一个数字
0:表示目标的类别索引,对应data.yaml中names下的0: person,即"人类"。 - 后续四个数字
0.48 0.63 0.69 0.71:它们共同描述了目标的位置和大小,格式为(x_center, y_center, width, height)。- 所有这些坐标都是归一化的,即它们是相对于图片总宽度和总高度的比例值,范围在0到1之间。
(x_center, y_center)=(0.48, 0.63):这是目标边界框中心点的坐标。(width, height)=(0.69, 0.71):这是目标边界框的宽度 和高度。- 模型会以
(0.48, 0.63)为中心,画一个宽为图片宽度0.69倍、高为图片高度0.71倍的矩形框,这个框住的内容就是我们要检测的"人"。
第二行数据含义同理,它标注了图片中的另一个人。
当然,我们不可能手动去计算这些归一化坐标。幸运的是,有许多强大的图形化工具可以帮我们轻松完成标注,它们能自动生成符合YOLO格式的数据集结构。
本章节将会带大家完成一个有趣的目标检测实战项目:训练一个能够精准识别热门游戏《反恐精英2》(CS2)画面中的"警察"与"匪徒"的智能模型。
(小知识:CS2是一款极具影响力的团队竞技第一人称射击游戏,玩家主要分为"反恐精英"(Counter-Terrorists, 即警察)与"恐怖分子"(Terrorists, 即匪徒)两大阵营,我们的AI就要学会在复杂的游戏画面中将它们分辨出来。)
我已经把训练用的数据集放在了上面提供的网盘链接中,名为 cs2_dataset.zip 。下载并解压后,你会发现其文件夹结构与上述规范完全一致。这就像一个标准的"目标检测项目模板",请你在未来组织自己的数据时,也务必遵循同样的规范。

4.2 常用标注工具
这里,我向大家推荐一个经典、轻量且广泛使用的标注工具------LabelImg。
可以在上方我分享的网盘链接中下载,名为 label_img.zip。你可以直接下载并解压到任意方便的目录。
解压后,你会看到文件夹内非常简单,主要包含 labelImg.exe 可执行文件和一个 data 文件夹。请先不要急于双击启动程序 ,我们的第一步是预先告诉它我们要标注哪些东西。进入 data 文件夹,找到名为 predefined_classes.txt 的文本文件。这个文件就是用来记录类别的,比如你的任务是分类猫,狗,人,那么就把这三个类别提前写入这个txt文件中,一行写一个类别,如下图所示:

txt
dog
cat
human
为了让标注过程清晰高效,建议你在开始前创建两个专门的文件夹:
images文件夹:用于存放你准备好的等待标注的数据集图片。labels文件夹 :作为一个空文件夹,准备用来承接LabelImg自动生成的YOLO格式标注文件(每个图片会对应一个同名的.txt文件)。
接着,你就可以打开labelImg.exe程序了。然后按照如下图片进行初始设置

设置好后,按照下图所示操作


标注好这一张图片后,你可以按一下w继续标注其它内容,或者按下D键跳转到下一张并自动保存,继续标注下一张图片。
小提示:如果不小心跳过了,或者需要回看修改,可以按A键可以回到上一张
等你按部就班的完成了所有图片的标注,你就得到了一个与 images 文件夹对应的 labels 文件夹,里面存放着每一张图片的精确坐标与标签------这是你辛勤劳动的宝贵成果。不过细心观察你会发现,目前的文件结构(一个图片夹和一个标签夹)还不是YOLO所要求的标准形式。我们还需要将数据集科学地划分为训练集、验证集和测试集,才能投入训练。
你可能会想:"是不是需要手动剪切粘贴,把文件一个个分到不同文件夹里?"------这确实是一种方法,但当面对成百上千张图片时,手动操作不仅效率低下,还极易出错。
这里给大家准备好了一个能够自动完成数据集划分的Python脚本,并附上了详细的使用说明。你可以在上文提供的网盘链接中的 "常用Python预处理脚本" 文件夹里找到它。
4.3 模型训练
模型训练就非常简单了,下面的代码便是启动训练的全部核心,你会发现它与分类任务的代码几乎一模一样:
python
from ultralytics import YOLO
if __name__ == "__main__":
model = YOLO("./yolo11s.pt") # 加载预训练模型
# 启动训练流程
results = model.train(
data="./data.yaml", # 【关键】这里是数据集配置文件的路径,而非文件夹路径
epochs=30,
imgsz=720, # 输入图像的尺寸,此处统一缩放为720x720像素
batch=0.6,
project="detection_results",
deterministic=False,
)
唯一要注意的是,data参数不再直接指向你的数据集文件夹,而是一个描述了数据集所有信息的.yaml配置文件。
剩余的内容,包括参数设置什么的都和分类任务一样,你可以参考分类任务的"模型训练"章节来设置你的参数,了解它们的作用。
在程序运行的过程中,你可以在终端或命令行中看到类似下图的输出:

与分类任务主要关注准确率不同,目标检测的评估更为精细。在每个训练周期,你都会看到一整套丰富的评估指标,它们从不同角度反映了模型的效果:有box_loss,cls_loss,df1_loss,instances,P,R,mAP50,mAP50-95等参数
训练结束后,程序还会贴心地生成一份总结性的评估报告表,其中把每个类别的指标都列出来了,这里是police和robber两个类别

这些模型的指标将在下一节详细介绍。
4.4 结果数据解读
下面的这些是评估一个模型好坏的关键指标,一旦你懂了下面这几个核心指标,你就能对模型的性能了如指掌,并精准地指出它的强项和短板。
-
box_loss: 边界框回归损失。它衡量模型预测的物体边界框(Bounding Box)与真实标注框之间的差距,包括中心点坐标、宽度和高度的误差。它的下降意味着模型正在学习如何更精准地定位物体,框的位置和大小越来越准。
-
cls_loss: 分类损失。它衡量模型对框内物体分类的正确性(比如,把"警察"误判为"匪徒"就会产生很高的分类损失)。它的下降意味着模型正在学习更准确地识别物体的类别,不再"指鹿为马"。
接下来我们以如下例子带大家了解剩余的参数意思:
背景设定
- 任务:你训练了一个"警察"(YOLO模型),在图像上抓"小偷"(缺陷目标)。
- 验证集 :一个已知有1561个场景(Images ),里面确实藏着2420个"小偷"(Instances)的测试场地。
4.4.1 IoU(交并比) - "抓对的证据标准"
通俗理解:警察画了一个圈说"小偷在这里",这个圈和真实小偷所在的位置的重合程度。
- 计算 :
交集面积 / 并集面积 - 比喻 :
- IoU = 1.0:警察画的圈和小偷的真实位置完美重合,100%抓对。
- IoU = 0.5 :警察画的圈和小偷的位置大概有一半重合。
(这是一个常用的"及格线") - IoU = 0:警察画的圈和小偷的真实位置完全没有重合,抓错人了。
IoU是一个衡量"定位是否准确"的尺子。
4.4.2 精确率 (Precision)
通俗理解 :警察抓来的人里面,有多少是真正的小偷。 它关心的是"抓人的准确性"。
- 公式 :
精确率 = 抓对的小偷数量 / 总共抓的人数 - 比喻 :
- 警察A一天内抓了10个人,经过核实,其中9个是真正的小偷。
- 精确率 = 9 / 10 = 90% (很靠谱,他说谁是小偷,谁大概率就是)
- 警察B一天内抓了100个人,其中只有10个是真正的小偷。
- 精确率 = 10 / 100 = 10% (胡乱抓人,冤假错案很多)
- 警察A一天内抓了10个人,经过核实,其中9个是真正的小偷。
scss
Box(P): 0.907
- 这意味着你的模型每标记出100个目标,其中大约有91个是真实存在的目标,另外9个是误报
- 高精确率的好处:减少虚惊,节省复检人力。
4.4.3 召回率 (Recall) - "天网恢恢,疏而不漏"
通俗理解 :所有真实的小偷中,警察抓住了多少。 它关心的是"抓人的全面性"。
- 公式 :
召回率 = 抓对的小偷数量 / 街上真实存在的小偷总数 - 比喻 :
- 街上总共有100个小偷。警察A抓住了其中的85个。
- 召回率 = 85 / 100 = 85% (法网恢恢,大部分小偷落网)
- 警察B只抓住了其中的5个。
- 召回率 = 5 / 100 = 5% (大部分小偷逍遥法外)
- 街上总共有100个小偷。警察A抓住了其中的85个。
scss
Box(R): 0.831
- 这意味着在所有2420个真实目标中,你的模型成功检测出了大约83%。剩下的17%是漏检(模型没发现,但实际存在的目标对象)。
- 高召回率的好处:减少漏网之鱼,降低风险。
4.4.4 mAP50- "综合考评(宽松版)"
通俗理解 :在"IoU门槛设为50%"这个宽松标准 下,对模型性能的一个综合打分。
- mean(平均):对所有类别的性能取平均。
- Average Precision(平均精度):综合了不同置信度阈值下的精确率和召回率,计算出的一个单一、稳健的指标。
- 50:只要警察画的圈和小偷位置有超过50%的重合(IoU > 0.5),就算他抓对了。
makefile
mAP50: 0.913
- 意思是:在"定位只要大致准确就行"的标准下,你的模型综合性能得分是91.3分(百分制)。说明它既能准确地找到目标,又能很好地识别出目标的类别。
4.4.5 mAP50-95- "综合考评(严格版)"
通俗理解 :在"IoU门槛从50%逐步提升到95%"的一系列严格标准 下,对模型性能的综合打分。
- 它不再是单一标准,而是从"大致框对"(IoU=0.5)到"几乎完美框对"(IoU=0.95)共10个不同门槛下,分别计算mAP,然后取平均值。
- 这个指标同时考验模型的"分类能力"和"定位精准度"。
makefile
mAP50-95: 0.619
- 这个分数比mAP50低是完全正常且预期之内的,因为标准严苛得多。
- 61.9%的分数表明:当要求模型必须用非常精确的框来包围目标时,它的性能会下降。但它依然是一个可以接受的成绩,说明模型的定位能力还算不错。
4.4.6 关键图表解读
懂了上面的这些内容,相信你再来看下面的这些训练结果图表就是轻而易举了。

接下来介绍下面的图表,这四个图表是帮你在模型推理时调参的重要工具!它们能帮你深入洞察模型在不同"自信度"下的表现,从而找到那个最佳的置信度阈值。

要想看懂上面的图表,就要知道什么是置信度?想象一下,当模型在图片中框出一个目标时,每个边框上方显示的数字(例如"0.86")就是它的置信度。这个分数代表了模型对这个预测结果的"自信程度"------比如0.86就意味着模型有86%的把握认为它框中的确实是你指定的目标(如"行人"或"汽车")。
在实际推理时,你可以通过设置 conf 参数来灵活调整这个"自信门槛"。例如,设定 conf=0.5,就等于告诉模型:"只有当你觉得自己有50%以上的把握时,才把目标框出来;低于这个信心的,就直接忽略掉。" 这个阈值是你平衡检测"漏报"与"误报"的重要杠杆。
- F1-Confidence Curve (F1-置信度曲线) F1分数是精确率和召回率的调和平均数 ,是衡量模型综合性能的"单科总分"。这条曲线展示了在不同置信度阈值下,F1分数的变化情况。你的目标就是找到这条曲线的最高点,这个点对应的置信度阈值,通常就是精确率和召回率达到最佳平衡的"甜蜜点"。
- Precision-Confidence Curve (精确率-置信度曲线) 精确率衡量的是"模型说对了吗"。它回答的是:在所有被模型框出来的目标中,到底有多少是真正的目标?当置信度阈值提高时,模型会变得越来越"保守",只输出它最确信的结果,因此精确率通常会随之升高(因为误报减少了)。如果这条曲线整体偏低,说明模型存在较多的误检。
- Recall-Confidence Curve (召回率-置信度曲线) 召回率衡量的是"模型找全了吗"。它回答的是:所有真实存在的目标中,模型成功找出了多少?当置信度阈值提高时,模型可能会因为"过于保守"而漏掉一些不太确定但真实的目标,因此召回率通常会随之下降。如果这条曲线下降得过快,说明模型太容易"放弃"真实目标了。
- Precision-Recall Curve (精确率-召回率曲线) 这个图表展示了准 和全的权衡关系,曲线越往右上角靠(表明既准又全),那么表示模型整体性能越好。
简单来说,你可以这样综合运用它们: 首先在 F1曲线 上找到最高点,确定一个备选的置信度阈值。然后,观察在此阈值下,精确率曲线 和召回率曲线 的数值是否都处于你能接受的范围内。通过这样的分析,你就能科学地设置 conf 参数,让模型在"不错怪一个好人"和"不放过一个坏人"之间取得最佳平衡。
4.5 模型推理
如何使用你训练好的模型呢,YOLOv11的推理过程设计得非常人性化,与分类任务的流程基本一致。如果你还记得分类章节中的参数配置表格,很多参数在这里都能通用。
下面这段简洁的代码就能让你加载训练好的模型并进行预测:
python
from ultralytics import YOLO
model = YOLO("../detection_results/train/weights/best.pt") #加载一个本地训练好的模型
source = "./324.jpg" # 测试一张图片
results = model.predict(
source,
imgsz=720,
conf = 0.5, # 置信度设置,只显示把握大于50%的检测结果
)
python
# 提取并分析第一个检测结果(因为可能有多张图片,这里取第一张)
result = results[0].cpu()
print("检测到的目标类别:", result.boxes.cls) # 类别ID,数组长度就是目标个数
print("各目标的置信度:", result.boxes.conf) # 模型对每个检测结果的把握程度
print("归一化位置信息:", result.boxes.xywhn) # 格式:[x中心, y中心, 宽度, 高度](归一化到0-1)
print("原始位置信息:", result.boxes.xywh) # 格式:[x中心, y中心, 宽度, 高度](原始像素坐标)
# 实际输出示例:
# 检测到的目标类别: tensor([1., 1.]) → 检测到2个目标,都是类别1
# 各目标的置信度: tensor([0.8580, 0.8501]) → 第一个目标置信度85.8%,第二个85.0%
# 归一化位置信息: tensor([[0.6452, 0.5798, 0.1171, 0.3129], → 第一个目标在图像中的相对位置
# [0.2688, 0.5362, 0.0881, 0.3594]]) → 第二个目标在图像中的相对位置
# 原始位置信息: tensor([[709.7494, 406.4641, 128.8472, 219.3187], → 第一个目标的像素坐标
# [295.6964, 375.8881, 96.9277, 251.9450]]) → 第二个目标的像素坐标
除了直接查看数据,YOLOv11还提供了便捷的可视化功能:
python
# 方法一:直接显示带检测框的图片
results[0].show()
# 方法二:保存可视化结果
results[0].save(save_dir="./detection_results/")
# 方法三:获取绘制好的图像数组,用于后续处理
plotted_image = results[0].plot()
...
五. 结语
读到此处,相信你已经跟随本教程一步步完成了从环境配置到模型训练、结果解读的全过程。在结束这篇YOLO"保姆级"教程之前,我想与你分享一些超越代码工具本身的学习感悟------这些或许比某个具体参数如何设置更为重要。
回顾我的学习历程,曾几何时,我也曾纠结于是否要"精通"某门语言,或担心错过某个热门框架。但代码写得越多,越清晰地意识到:程序员的真正核心竞争力,并非体现在对某门语言或框架的熟悉程度上,而在于运用技术解决实际问题的能力 。计算机世界日新月异,今天流行的框架可能明年就会过时,新的语言亦会层出不穷。唯有保持持续学习的状态,才能在技术的浪潮中始终拥有立身之本。当你遇到新的场景,需要新的工具时,自然就能学会新的语言------你缺的从来不是学习能力,而是那个驱动你学习的真实问题。
其次,在学习这些强大的工具库(如 SciPy、scikit-learn、Pytorch乃至我们本文的 YOLO)时,一个高效的策略是 "按需所学,而非系统通读" 。试图一开始就系统性地掌握一个庞大库的所有内容,很容易陷入大量专业术语的泥潭。更好的方式是,在具体项目中遇到什么需求,再去深入学习该库对应的模块。这能让你始终保持目标清晰,理解也更为深刻。
当然,这并非否定打好基础的重要性。像 Python、NumPy 这类构成生态基石的库,就必须系统地学习------它们是你能快速"按需所学"其他工具的前提。
最后,也是最重要的一点:在用中学。编程如同游泳,看再多的教程也无法替代你亲自跳入水中。只看不练,如同纸上谈兵,知识永远无法内化为你解决问题的能力。不要担心自己懂的不够多,真正的掌握,始于你动手让第一行代码运行起来,并在解决一个又一个bug和需求的过程中,将知识彻底消化。
语言只是工具,不是目的;代码只是手段,而非终点。 真正有价值的,永远是你运用工具去解决真实问题的思维、视野与创造力------而这,是任何技术更新都无法取代的。