告别YOLOv8!全面拥抱YOLOv11:最贴心的YOLO“保姆级”教程
告别YOLOv8!全面拥抱YOLOv11:最贴心的YOLO“保姆级”教程
一. 前言
点开这篇文章的各位,大概率正面临一个实际的机器视觉项目,急需掌握一个高效实用的目标检测工具——YOLO。所以本文不打算深究深度学习原理,只聚焦于如何用好这个工具:如何快速上手、跑通代码、做出成果。当然,过程中难免涉及一些专业术语,但会用最直观的方式解释那些基础而关键的概念。
学习任何工具前,先搞清楚它到底是什么。YOLO不是一个软件,而是一个开源的算法工具箱——就像一整套预制好的视觉工具,想用什么直接拿。以YOLOv11为例,它可以通过Python库的形式调用。需要说明的是,你至少得有点Python基础,但别担心,不会涉及过于复杂的编程技巧。
YOLO从诞生到现在迭代了很多版,目前主流项目中YOLOv5和YOLOv8仍很常见,成熟稳定且社区资源丰富。但技术演进很快,YOLOv11是官方主推的生产级版本,在精度、速度、易用性之间取得了更好的平衡。也许你会问:不是有比v11更新的版本吗?确实,但YOLOv11是目前文档最全、最推荐用于实际部署的稳定版本。更关键的是,各版本接口设计高度一致,掌握一个就能触类旁通。
如果你已有深度学习基础且熟悉PyTorch,那YOLO对你来说更像一个封装好的工具包——直接翻官方文档就能上手,完全不需要这篇教程。不过对于多数想快速落地项目的朋友,咱们还是从头走一遍。
先看看YOLO都能做什么。读完这篇文章,你也能亲手训练一个模型达到以下效果,并用在自己的项目里。
YOLO最知名的能力是目标检测(Object Detection)——训练一个模型,让它识别出图像中你感兴趣的物体,并给出每个物体的位置坐标和大小。这在监控安防、自动驾驶、日常图像分析等场景中非常实用。
更进一步是实例分割(Instance Segmentation),它不仅能识别出不同物体,还能精确地把它们从背景中“抠”出来。当你不光要知道物体在哪,还想了解其具体形状和轮廓时,这个能力很有用——比如医疗影像分析、机器人视觉等场景。
图像分类(Image Classification)是最基础也最经典的任务:输入一张图片,模型输出一个类别标签和置信度,告诉我们“这是什么”。听起来简单,却是很多视觉系统的基石。
姿态估计(Pose Estimation)则更特别——它识别图像中人体或物体的关键点位置,比如关节、五官等。模型输出一组带置信度的坐标点,帮助我们理解对象的姿态结构。体育动作分析、互动游戏、人机交互等场景都会用到。
本文会重点带大家完成目标检测和图像分类两个核心任务。掌握它们之后,像姿态估计、实例分割、甚至OBB(定向边界框)这些进阶功能,只需要查阅官方文档稍作了解就能举一反三。
为了顺利实践,你需要一台搭载现代NVIDIA显卡的Windows电脑(苹果电脑也行,但本教程以Windows为例),有一定的Python基础,并熟悉基本的Windows操作。
二. 环境搭建
2.1 Python版本号查看
假定你的电脑已经装好了Python,这里就不重复安装步骤了。关键一点:请确保Python版本≥3.8,这是官方明确的最低要求。
查看Python版本很简单:按Win + R打开“运行”,输入cmd回车,在命令行窗口中输入python后回车,屏幕上就会显示版本信息。
如果输入python后提示“找不到命令”,要么是没装Python,要么是安装时没勾选“Add Python to PATH”。
2.2 Pytorch的安装
什么是PyTorch?简单说,只要你进入深度学习,PyTorch几乎绕不开。它是一个基于Python的深度学习框架,可以灵活地构建、训练和部署各类模型。现代AI模型(包括YOLO系列)大多基于PyTorch开发,所以想本地跑YOLOv11,安装PyTorch是必须的。(在Python中它的库名叫torch)
很多初学者会问:“有没有必要系统学PyTorch?”答案通常是:现阶段没必要,先把机器学习和深度学习的基础理论打扎实。PyTorch本质上是个工具,懂了模型和算法后再学它,水到渠成。打个比方:你给一位数学博士生一个计算器,让他算一个复杂积分,他按流程就能得到答案;但如果把这个计算器给一个小学生,他连符号都认不全,更别说按键了。这里的“计算器”就是PyTorch。会不会用,取决于使用者的理论基础。
当然,用好YOLO并不需要精通PyTorch,但会一点会更好。
本文采用全局安装方式,默认将PyTorch装到C盘。如果你有经验,可以在虚拟环境里安装,方便卸载和项目管理。但Python新手强烈建议全局安装,能避开很多环境配置的坑。
⚠️ 注意:PyTorch及其组件总大小约3GB,全局安装请确保C盘有足够空间。未来不用了,本文也会教你怎么彻底移除。
首先确定显卡型号,这决定你要安装哪个PyTorch版本。在命令行窗口(cmd)输入
nvidia-smi
并回车查看显卡信息。
如果看到上述界面,请确保CUDA版本≥11.8,否则需要更新显卡驱动。如果电脑没有独立NVIDIA显卡或显卡太老,只能用CPU训练和推理,速度会慢很多,但学习测试没问题。这种情况在cmd中输入以下命令安装CPU版PyTorch:
pip install torch torchvision torchaudio
如果显卡是RTX 30/40系列等,可以用以下命令:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
如果显卡是RTX 50系列,必须用:
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu129
如果显卡稍老,可以用:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
PyTorch安装包较大,下载需要耐心。完成后命令行的结尾会显示Successfully installed...。
最后运行测试代码检查安装和硬件识别:
import torch
print(f"PyTorch 版本: {torch.__version__}")
print(f"显卡是否可用: {'是' if torch.cuda.is_a vailable() else '否'}")
if torch.cuda.is_a vailable():
print(f"当前 GPU: {torch.cuda.get_device_name(0)}")
如果输出显示“显卡是否可用: 是”并正确识别显卡型号,恭喜——环境配置成功!
如果上述方法都无法顺利安装(比如下载太慢),可以用AI大模型(如DeepSeek、豆包)一对一解决问题,把错误信息完整描述给它。无论最终用哪种方式装好,务必运行上面的测试代码确认。
2.3 YOLO的安装
装好PyTorch后,YOLO的安装就很简单了。在cmd中输入:
pip install ultralytics
安装完成后运行:
from ultralytics import YOLO
print("YOLO 安装成功!")
如果没有报错,就说明安装成功,可以开始学习了。
2.4 预训练模型的下载
什么是预训练模型?简单说,它就像一位已经读过万卷书的学者——在海量图像数据集(如ImageNet、COCO等)上充分训练过,能识别成百上千种常见物体。换句话说,它是一个“半成品”模型,已经具备通用视觉能力。
当我们希望它学习某个特定任务时(比如识别某一种特殊物体),不需要让它从零开始,可以基于已有知识用我们的小数据集去微调(Fine-tuning)。这样做收益明显:训练效率更高、数据需求量更少、收敛更快。这背后的原理是迁移学习。
举个例子:教一位全能型厨师做一道他没见过的新菜,但他已经精通各种菜系的基本技法(预训练模型的特征提取能力)。现在你想让他专门学会做“四川麻婆豆腐”:
- 方法A(从零训练):让他忘掉所有基础,只给豆腐和辣椒自己摸索,可能失败几百次、花几个月,这就是不用预训练模型从头训练的效果。
- 方法B(预训练+微调):请出这位厨师,递给他一份简明的“麻婆豆腐专属食谱”(你的小数据集),他凭借原有功底很快就能做出来。这正是“预训练+微调”的精髓。
YOLO官方提供了多种体积的预训练模型。以分类任务为例,yolo11s-cls.pt是图像分类的预训练模型,yolo11s.pt是目标检测的(平衡了精度与体积)。可以从官方仓库下载,放到你喜欢的任何位置,只要记得路径就行。
注意,同一任务下不同体积的模型,体积越大(参数越多、占用越大)识别效果越好,但往往收益递减——可能体积提升80%,识别效果只提升3%。大模型对硬件要求也高。根据任务需求选择就好,好比买车,不是排量越大越好,要考虑性价比。
2.5 YOLO及其组件的彻底卸载
情况一:虚拟环境安装。如果是用Conda或Venv装的,直接删除虚拟环境文件夹,所有包都会清除,干净利落。
情况二:全局安装的普通卸载。在cmd中输入以下命令卸载PyTorch、YOLO及相关组件:
pip uninstall torch torchvision torchaudio torchtriton pytorch-triton ultralytics
接着清理pip缓存释放磁盘空间:
pip cache purge
完成这两步后,主体就被移除了。系统中可能残留一些附属组件和配置文件,通常不影响使用,只占少量C盘空间。如果不打算继续用YOLO/PyTorch,到这里就够了。
情况三:追求完美彻底卸载。如果以后都不再使用Python做AI开发,或者有洁癖希望系统回归纯净,可以在cmd中输入:
for /F "delims==" %i in ('pip freeze') do pip uninstall -y %i
这会卸载当前Python环境中所有通过pip安装的包,只剩解释器本身。此时可以再卸载Python。完成后再回到安装前的状态。之后需要的话,重新下载个全新版本即可。
三. 分类任务
什么是分类任务?看到一张花的照片,认出它是玫瑰还是向日葵——这就是图像分类要解决的问题。在AI世界,分类任务就是让计算机学会这种“识别”能力:预先定义若干类别(比如不同品种的花),输入图片后模型输出它最可能属于哪个类别。
3.1 准备数据集
俗话说“巧妇难为无米之炊”,没有高质量数据集,再先进的算法也无用武之地。这里以“花卉种类识别”为例,讲解如何准备规范的分类数据集。
假设要训练一个能识别4种花卉的模型:向日葵(sunflower)、玫瑰(rose)、郁金香(tulip)、兰花(orchid)。请按照以下目录结构组织数据:
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通过反复学习来掌握特征。
- 测试集:从未见过的期末考试试卷,不参与学习,专门评估模型是否真正理解,而不是死记硬背答案。
没有测试集,可能训练出一个“练习题满分、新题抓瞎”的书呆子模型——过拟合。测试集让我们能在训练过程中随时“抽考”模型,客观衡量真实水平。
经典做法是按8:2或9:1划分。比如有1000张向日葵图片,放800张到train/sunflower,200张到test/sunflower。这样模型有足够数据学习,也有充足数据测试。
关于图片大小和格式的要求:
- :虽然YOLO支持多种格式,但强烈建议全部用
格式统一
.jpg,兼容性好、体积小、处理快。 - :YOLO模型期望输入正方形图片,最常用640x640像素。通常你不需要手动裁剪每张图,YOLO会自动缩放和填充。但提前批量处理能提高训练效率。
尺寸统一
- :文件名任意,
命名自由
123.jpg或a_beautiful_flower.jpg都可以,只要不重复即可。
图片预处理(如批量格式转换、重命名、智能裁剪)是重要环节,但为避免冲淡主题,这里不讲。网上可以找到很多批量处理工具,或者自己写脚本。配套数据集和脚本可通过社区获取。
本篇教程以一个“插画/现实”二分类任务为例,带大家走一遍用YOLOv11进行分类的完整流程——训练一个能自动区分“真实照片”与“动漫插画”的智能分类模型。(题外话:如果你有大量人类画师作品和AI绘画作品,也可以训练一个二分类模型来判断一张图是否AI生成。)
数据集可以下载,解压后文件夹结构与上述规范一致。这就像一个标准的“分类项目模板”,以后组织自己的数据时务必遵循同样规范——清晰的结构是高效训练的前提。
3.2 模型训练
相比数据集的收集和预处理,训练过程简单得多。得益于YOLO优秀的封装,让AI“学有所成”的核心步骤只需几行代码。
新建一个py文件,输入以下代码:
from ultralytics import YOLO
if __name__ == "__main__":
model = YOLO(r"D:/WorkSpace/yolo11s-cls.pt") # 载入预训练模型,替换为你的路径
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()开始训练,里面配置各种参数。
Part2. train中可配置的重要参数
data:告诉模型数据集在哪。batch:控制学习强度与硬件占用,范围0~1。越大训练越快,但可能显存不足(OOM)。若出错,调低(如0.5)。这里设为0.75,代表使用约75%显存动态计算。project:训练结果存放文件夹名,可任意命名。epochs:数据集被完整学习的轮数。越多训练越久、效果越好。但太少学不透,太多可能过拟合。一般10~30足够收敛,根据验证集效果调整。imgsz:统一输入图像尺寸。设为640,所有图片会被缩放或填充为640x640。这个值必须与预处理图片时的尺寸一致。
除此之外还有很多可配置参数,下面列出一些常用的:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
time | float | None | 最长训练时间(小时),覆盖epochs参数。 |
patience | int | 100 | 验证指标无改善时等待的epoch数,提前停止训练防止过拟合。 |
sa ve_period | int | -1 | 间隔多少epoch保存检查点。 |
cache | bool | False | 缓存数据集图像到内存/磁盘,加速训练。 |
device | int/str/list | None | 选择计算设备:GPU(如0)、CPU(cpu)、MPS(mps)等。 |
workers | int | 8 | 数据加载的工作线程数。 |
name | str | None | 训练运行的名称,用于在project内创建子目录。 |
optimizer | str | 'auto' | 优化器选择,如SGD、Adam等。 |
dropout | float | 0.0 | 分类任务中的dropout率。 |
完整参数表请参考官方文档。最后,关掉网络(建议暂时断开连接,防止环境自动下载更新引发意外),将配置好的代码直接用Python运行,训练就开始了。(注意:务必在.py文件中执行,而不是Jupyter Notebook等交互式环境。)
程序运行中可以看到控制台输出如下内容:
以上图为例,逐一解读关键指标:
Epoch n/30:总轮数30,当前第n轮,可直观知道进度和剩余时间。GPU_mem 7.96G:当前占用的显存,是调整batch参数的重要参考。若接近上限,下次可适当调低batch。loss(损失函数值):模型预测与真实标签之间的误差,评估学习效果的核心指标。
理想情况:loss随训练稳定下降。
过拟合信号:loss降至极低(如0.01以下)但测试准确率不高。
欠拟合信号:loss在较高数值徘徊,需检查数据、模型或学习率。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
train/loss(训练集损失):反映模型在“练习题”上犯错的减少过程。理想情况是随轮次稳步下降并趋于平稳。若剧烈波动或无法下降,说明“学不进去”,可能数据或结构有问题。val/loss(验证集损失):模型在“模拟考卷”上的犯错情况,是检测过拟合的关键指标。最健康的状态是与训练集损失一同下降,且后期二者接近。若训练集损失持续下降但验证集损失回升,就是典型的过拟合信号——模型死记硬背,丧失泛化能力。metrics/accuracy_top1(Top-1准确率):模型在验证集上的“考试分数”,直接告诉你模型第一个预测是正确的概率。越高越好,终极目标是曲线稳步攀升至高位(如95%以上)并保持稳定。metrics/accuracy_top5:多分类任务(类别数≥5)时更有意义,表示正确答案出现在前五个预测中的概率。本教程是二分类,Top1已足够。
results.csv表格中的数据就是上述图表的具体数值,其中time列记录每轮耗时(秒)。
3.3.2 数据本源:results.csv
上面讲的results.png就是由此文件的数据直接绘制。如果你需要对模型表现进行更精细分析,可以查看精确数据。特别实用的字段是time,记录每轮训练耗时(秒)。
3.3.3 训练蓝图:args.yaml 文件
这个文件完整记录了本次训练的所有超参数,可理解为“配方”或“技术图纸”。一般情况下用不到,除非要精确复现。
3.3.4 归一化混淆矩阵
confusion_matrix_normalized.png是非常直观的“诊断报告”,清晰揭示模型哪些地方做对了,哪些地方容易混淆。(confusion_matrix.png本质相同,可忽略其中一个。)
以二分类为例,会看到一个2x2网格:
- 底部横坐标(True Label):实际类别(illustration插画,real真实照片)。
- 左侧纵坐标(Predicted Label):模型预测的类别。
对角线(左上到右下)代表预测正确,颜色越深、数值越高越好。每个格子含义:
- 第一行第一列(0.98):真实是插画,预测也是插画,比率98%。
- 第二行第一列(0.02):真实是插画,预测是真实照片,比率2%。其余同理。
3.3.5 模型权重weight
在weights文件夹中,保存着最重要的成果——模型本身。
best.pt:整个训练过程中性能最优的模型,是后续使用的首选。last.pt:训练最后一轮(本教程第30轮)的快照,代表最终状态。如果训练中断,可以用last.pt从断点继续训练:
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 模型推理
现在模型训练完成,我们也解读了结果图表。那么如何把训练好的模型用到实际项目中?非常简单,几行代码:
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参数)。不但支持单张,也支持多张批量预测。如何解读结果?result是一个列表,以第一张(索引0)为例:
# 输出每个类别的预测概率
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%的可能是插画,最终归类为类别1('real')。
实际上,source不仅可以是文件路径,YOLO支持多种图像来源,以下表格列出了常见的输入类型:
| 来源 | 示例 | 类型 | 备注 |
|---|---|---|---|
| 图像 | '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 |
| numpy | np.zeros((640,1280,3)) | np.ndarray | BGR通道HWC格式uint8 |
| torch | torch.zeros(16,3,320,640) | torch.Tensor | RGB通道BCHW格式float32 |
| CSV | 'sources.csv' | str或Path | 包含图像、视频或目录路径的CSV文件 |
| 视频 ✅ | 'video.mp4' | str或Path | MP4、A VI等视频文件 |
| 目录 ✅ | 'path/' | str或Path | 包含图像或视频的目录 |
| glob ✅ | 'path/*.jpg' | str | 通配符匹配多个文件 |
| 流 ✅ | 'rtsp://example.com/media.mp4' | str | RTSP、RTMP等流媒体URL |
| 多流 ✅ | 'list.streams' | str或Path | 每行一个流URL的文本文件 |
| 网络摄像头 ✅ | 0 | int | 摄像头设备索引 |
另外,model.predict()可以配置很多参数,下面列出常用的:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
source | str | 'ultralytics/assets' | 推理数据源,支持图像、视频、目录、URL、设备ID等 |
conf | float | 0.25 | 最小置信度阈值,低于此值的结果被忽略 |
iou | float | 0.7 | NMS的IoU阈值,降低可减少重复框 |
imgsz | int/tuple | 640 | 推理图像大小 |
rect | bool | True | 最小填充而非正方形填充,提高速度 |
half | bool | False | 半精度(FP16)推理,加速GPU |
device | str | None | 指定推理设备,如cpu、cuda:0 |
batch | int | 1 | 批处理大小(目录/视频/.txt有效) |
max_det | int | 300 | 每张图像最大检测数量 |
vid_stride | int | 1 | 视频帧步长,>1可跳帧加速 |
agnostic_nms | bool | False | 类别无关NMS,合并不同类别重叠框 |
retina_masks | bool | False | 返回高分辨率分割掩码 |
project | str | None | 保存预测输出的项目目录 |
name | str | None | 预测运行名称,在project内创建子目录 |
verbose | bool | True | 是否显示详细推理日志 |
show | bool | False | 可视化:在窗口中显示带注释的图像 |
sa ve | bool | False/True | 保存带注释的图像/视频到文件。CLI默认为True,Python中默认为False |
sa ve_frames | bool | False | 处理视频时将各帧保存为图像 |
sa ve_txt | bool | False | 以txt格式保存检测结果:[class] [x_center] [y_center] [width] [height] [confidence] |
sa ve_conf | bool | False | 在保存的txt中包含置信度 |
sa ve_crop | bool | False | 保存检测到的裁剪图像 |
show_labels | bool | True | 在可视化中显示标签 |
show_conf | bool | True | 在标签旁显示置信度 |
show_boxes | bool | True | 是否绘制边界框 |
line_width | None/int | None | 边界框线条宽度 |
YOLO提供了非常丰富的配置选项。这么多参数,一时不理解某个选项的作用怎么办?这时候可以随时向AI大模型提问。在掌握了YOLO的基本思想和方法后,这些细节问题完全可以交给AI解决。
但需要注意的是,如果完全不了解YOLO就想让AI从头完成一个视觉项目,几乎很难。因为你只能完全依赖AI,对宏观微观的理解都需要AI搭建,你只能从AI提供的答案中做选择。没有扎实的技术基础,仅凭AI生成的项目如同空中楼阁。相反,当你对整体流程有了清晰的概念和想法,AI就能成为得力的助手——是你在主导AI,而不是AI在领导你。这正是“懂技术”和“不懂技术”的人在使用AI时的关键差异。你的技术基础,决定着你的AI生成能力的上限。
3.5 图像增强
在模型训练章节,有三个参数没有展开讲:
degrees=60, flipud=0.3, fliplr=0.3
要理解它们,需要先明白什么是图像增强。
回到我们的“真实图片 vs 插画”二分类任务。假设找不到足够的图片,数据集太小,训练效果会大打折扣。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 | 同上 | 0.0-1.0 | 饱和度调整 |
hsv_v | float | 0.4 | 同上 | 0.0-1.0 | 明度调整 |
degrees | float | 0.0 | detect,segment,pose,obb | 0-180 | 随机旋转角度 |
translate | float | 0.1 | 同上 | 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 | 透视变换 |
flipud | float | 0.0 | detect,segment,pose,obb,classify | 0.0-1.0 | 上下翻转概率 |
fliplr | float | 0.5 | 同上 | 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 | 复制粘贴对象 |
auto_augment | str | randaugment | classify | - | 自动增强策略 |
erasing | float | 0.4 | classify | 0.0-0.9 | 随机擦除 |
其实不只图像识别,其他领域也一样。比如声音任务,可以在原始音频中加入噪音、不同背景音甚至水下或电话特效来扩增数据;文字识别任务,不同字体显示也能得到很多训练集。
补充知识点:YOLO是如何“智能裁剪”任意图片为标准正方形的?
上面提到,只要定义了imgsz参数,无论输入图片是横屏风景照、竖屏人像还是其他尺寸,YOLO都会在背后默默处理成统一大小的正方形张量。核心方法是:等比例缩放 + 智能填充。整个过程分为三步:
- :找到图片原始长宽,将最长边缩放到
等比例缩放长边
imgsz目标尺寸(如640像素),短边按相同比例缩放,保证内容不变形。 - :短边达不到目标尺寸,在短边两侧(上下或左右)填充灰色像素条,将图片“撑”成标准正方形,目标始终居中。
计算并填充灰边
- :对训练图片,填充后几何中心不变,标注框位置需同步调整。YOLO预处理阶段自动完成这个坐标映射。
坐标同步调整
为什么要这样设计?它最大限度保留原始图像的完整信息和比例,避免暴力拉伸导致的失真和目标变形。无论是训练还是推理,模型接收的都是尺寸统一、比例协调的数据,简化了计算过程,提升了泛化能力和预测稳定性。
四. 目标检测任务
4.1 数据集
分类任务教模型“图片里是什么”,目标检测则更进一步——不仅要识别物体,还要精准定位位置,即“在哪里”和“是什么”。这种更复杂的任务需要更丰富的数据组织形式。
与分类任务直接读主文件夹不同,目标检测任务依赖一个以.yaml结尾的数据集配置文件。这个文件就像整个数据集的“导航地图”,训练时程序读取它找到所有需要的数据。可以自由命名,这里命名为data.yaml。
data.yaml本质上是一个文本文件,标准内容结构如下:
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
创建它很简单:新建文本文件,将上述内容复制进去,根据实际修改路径和类别,后缀改为.yaml即可。编辑时用任何文本编辑器都行。
接下来按照以下结构组织数据集文件夹:
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文件内容如下:
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中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。可以从官方仓库下载,解压后主要包含labelImg.exe可执行文件和一个data文件夹。启动前,先进入data文件夹,找到predefined_classes.txt文件,这个txt文件用来记录类别。比如任务是分类猫、狗、人,就把这三个类别提前写入,一行一个:
dog
cat
human
为了让标注过程清晰高效,建议开始前创建两个专门文件夹:images(存放待标注图片)和labels(空文件夹,准备存放自动生成的YOLO格式标注文件)。
打开labelImg.exe,按下图进行初始设置:
设置好后,按图操作进行标注:
标注完一张后,按w继续标注其他内容,按D跳转到下一张并自动保存。小提示:如果不小心跳过或需要回看修改,按A键回到上一张。
完成所有图片标注后,你会得到一个与images对应的labels文件夹,里面是每张图片的精确坐标与标签。不过目前的文件结构(一个图片夹一个标签夹)还不是YOLO要求的标准形式,还需要将数据集科学划分为训练集、验证集和测试集。手动剪切粘贴面对成百上千张图片效率极低且易出错。网上有自动划分数据集的Python脚本,可以寻找并使用。
4.3 模型训练
模型训练非常简单,下面的代码是全部核心,你会发现在分类任务中几乎一模一样的模式:
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, dfl_loss, instances, P, R, mAP50, mAP50-95等。
训练结束后,程序会生成一份总结性评估报告表,列出每个类别的指标:
4.4 结果数据解读
下面这些是评估检测模型好坏的关键指标——掌握了它们,就能对模型性能了如指掌,精准定位其强项和短板。
- (边界框回归损失):衡量模型预测的边界框与真实框之间的差距(中心点、宽度、高度误差)。下降意味着定位越来越准。
box_loss
- (分类损失):衡量对框内物体分类的正确性(比如把“警察”误判为“匪徒”会产生高分类损失)。下降意味着分类准确率提升。
cls_loss
接下来用一个例子帮助理解其他指标:
背景设定
4.4.1 IoU(交并比)——“抓对的证据标准”
警察画了一个圈说“小偷在这里”,这个圈和真实小偷所在位置的重合程度。计算:交集面积/并集面积。比喻:IoU=1.0完美重合,IoU=0.5大约重合一半(常用及格线),IoU=0完全没有重合。IoU是衡量“定位是否准确”的尺子。
4.4.2 精确率 (Precision)
警察抓来的人里面,有多少是真正的小偷。公式:精确率 = 抓对的小偷数量 / 总共抓的人数。比喻:警察A一天抓10人,9个是真的→精确率90%(很靠谱);警察B抓100人,只有10个真的→精确率10%(冤假错案多)。
Box(P): 0.907
意味着模型每标记出100个目标,约91个是真实存在的,另9个是误报。高精确率可减少虚惊。
4.4.3 召回率 (Recall)
所有真实的小偷中,警察抓住了多少。公式:召回率 = 抓对的小偷数量 / 街上真实存在的小偷总数。比喻:街上100个小偷,警察A抓住85个→召回率85%(法网恢恢);警察B只抓5个→召回率5%(大部分逍遥法外)。
Box(R): 0.831
意味着在所有2420个真实目标中,模型成功检测出约83%,剩下17%是漏检。高召回率能减少漏网之鱼。
4.4.4 mAP50——“综合考评(宽松版)”
在“IoU门槛设为50%”这个宽松标准下,对模型性能的综合打分。mean(平均):所有类别取平均。A verage Precision(平均精度):综合不同置信度下的精确率和召回率。50:IoU>0.5就算抓对。
mAP50: 0.913
意思是定位大致准确的标准下,模型综合得分91.3分(百分制)。说明既能准确找到目标,也能很好识别类别。
4.4.5 mAP50-95——“综合考评(严格版)”
在“IoU门槛从50%逐步提升到95%”的一系列严格标准下,取10个门槛的mAP平均值。同时考验分类能力和定位精准度。
mAP50-95: 0.619
这个分数低于mAP50正常,因为标准严苛得多。61.9%表明当要求精确定位时模型性能会下降,但仍是可接受的成绩。
4.4.6 关键图表解读
理解了上面这些指标,再来看训练结果图表就很容易了:
下面四张图表是模型推理时调参的重要工具,帮你洞察模型在不同“自信度”下的表现,找到最佳置信度阈值。
什么是置信度?模型框出目标时,每个边框上方显示的数字(如0.86)就是置信度,代表模型对这个预测的“自信程度”。推理时可通过设置conf参数调整这个门槛:conf=0.5等于告诉模型“只有50%以上把握才框出来”,低于的忽略。
- :F1分数是精确率和召回率的调和平均数,是综合性能的“单科总分”。曲线展示了不同置信度阈值下F1的变化。目标是找到曲线最高点,对应精确率和召回率最佳平衡的“甜蜜点”。
F1-Confidence Curve (F1-置信度曲线)
- :提高置信度阈值会使模型更“保守”,精确率通常升高(误报减少)。如果曲线整体偏低,说明模型误检较多。
Precision-Confidence Curve (精确率-置信度曲线)
- :提高置信度阈值可能使模型漏掉不太确定但真实的目标,召回率通常下降。如果曲线下降过快,说明模型容易“放弃”真实目标。
Recall-Confidence Curve (召回率-置信度曲线)
- :展示准和全的权衡关系,曲线越往右上角(既准又全)说明模型性能越好。
Precision-Recall Curve (精确率-召回率曲线)
综合运用:先在F1曲线上找到最高点确定一个备选阈值,再观察该阈值下精确率和召回率是否都在可接受范围内。通过这样的分析,就能科学设置conf参数,让模型在“不错怪好人”和“不放过坏人”之间取得最佳平衡。
4.5 模型推理
YOLOv11的推理过程与分类任务基本一致。下面这段简洁代码就能加载训练好的模型并进行预测:
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%的检测结果
)
# 提取并分析第一个检测结果(可能有多张,取第一张)
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]])
除了查看数据,还提供可视化功能:
# 方法一:直接显示带检测框的图片
results[0].show()
# 方法二:保存可视化结果
results[0].sa ve(sa ve_dir="./detection_results/")
# 方法三:获取绘制好的图像数组用于后续处理
plotted_image = results[0].plot()
五. 结语
读到这里,相信你已经跟随本教程一步步完成了从环境配置到模型训练、结果解读的全过程。在结束这篇YOLO教程之前,分享一些超越代码工具本身的学习感悟——这些或许比某个具体参数如何设置更重要。
回顾学习历程,曾几何时,很多人会纠结是否要“精通”某门语言,或担心错过某个热门框架。但代码写得越多,越清晰地意识到:程序员的真正核心竞争力,并非体现在对某门语言或框架的熟悉程度上,而在于运用技术解决实际问题的能力。计算机世界日新月异,今天流行的框架可能明年就会过时。唯有保持持续学习的状态,才能在技术浪潮中始终拥有立身之本。当你遇到新场景、需要新工具时,自然就能学会新语言——你缺的从来不是学习能力,而是那个驱动你学习的真实问题。
其次,在学习强大工具库(如SciPy、scikit-learn、PyTorch乃至本文的YOLO)时,高效的策略是“按需所学,而非系统通读”。试图一开始就系统学完一个庞大库的所有内容,容易陷入大量专业术语的泥潭。更好的方式是:在具体项目中遇到什么需求,再去深入学习对应的模块。这样目标清晰,理解也更深刻。
当然,这并不否定打好基础的重要性。像Python、NumPy这类构成生态基石的库,必须系统学习——它们是你能快速“按需所学”其他工具的前提。
最后,也是最重要的一点:
在用中学
语言只是工具,不是目的;代码只是手段,而非终点。真正有价值的,永远是你运用工具去解决真实问题的思维、视野与创造力——而这,是任何技术更新都无法取代的。