1. YOLO初探

1.1 目标检测到底在做什么?

先问个问题:图像分类和目标检测,区别在哪?

图像分类,就是给一张图打标签——"这是一只猫"。而目标检测,不仅要回答"这是什么",还要回答"它在哪里"。说白了,检测 = 分类 + 定位。

我刚开始接触这个领域时,觉得不就是多画个框嘛。后来才发现,这个"框"才是真正的难点。一张图里可能有多个物体,大小不一,相互遮挡,背景复杂。你要同时预测出每个物体的类别和位置,这比单纯分类难了一个量级。

目标检测的核心输出:
  • 每个目标的类别标签(如:人、车、狗)
  • 每个目标的边界框(Bounding Box,通常用 (x, y, w, h) 表示)
  • 每个目标的置信度分数(模型对这个预测有多确定)

举个例子。一张街景图,检测模型会输出:行人A在(120, 340)处,置信度0.95;汽车B在(560, 200)处,置信度0.88。这就是目标检测的"标准答案"。

1.2 从v1到v8:YOLO的进化之路

YOLO的历史,我把它分成三个阶段。每个阶段都有标志性的突破。

版本 发布时间 核心贡献 我的评价
YOLOv1 2016 首次提出"单阶段检测"思想 开山之作,但精度一般
YOLOv2 2017 引入Anchor Box、Batch Normalization 稳定了训练,速度更快
YOLOv3 2018 多尺度预测、Darknet-53骨干 真正能用的版本,我项目里用了很久
YOLOv4 2020 Bag of Freebies、CSPDarknet 工程优化集大成者
YOLOv5 2020 PyTorch实现、更易用 社区最活跃,入门首选
YOLOv6/v7 2022 工业级优化、重参数化 部署友好,但生态不如v5
YOLOv8 2023 统一框架、支持检测/分割/姿态 目前最推荐的新项目起点

我记得2018年做第一个检测项目时,用的就是YOLOv3。当时在GPU上跑30 FPS,觉得已经很快了。现在回头看,v8在同样硬件上能跑到100+ FPS,精度还更高。技术迭代就是这么残酷。

给新手的建议: 如果你刚入门,直接从YOLOv5或v8开始。别从v1看起,那些里的坑,后人已经帮你填平了。

1.3 YOLO的核心思想:You Only Look Once

YOLO这个名字,直译就是"你只看一次"。这恰恰点出了它和传统方法的本质区别。

在YOLO出现之前,主流方法是R-CNN系列。它们怎么做?先找出可能包含物体的区域(候选框),然后对每个区域单独做分类。你想想看,一张图可能要生成2000个候选框,每个框都要过一遍分类网络。速度能快才怪。

YOLO的思路完全不同。它把检测当作一个回归问题来处理。一张图输入网络,直接输出所有目标的类别和位置。一次前向传播,搞定所有事情。

YOLO的核心流程(以v1为例):
  1. 将输入图片划分为 S×S 的网格(如 7×7)
  2. 每个网格负责预测 B 个边界框(如 2 个)
  3. 每个边界框输出:x, y, w, h, confidence
  4. 每个网格还预测 C 个类别概率
  5. 最终输出张量形状:S × S × (B*5 + C)

说白了,YOLO把整个检测任务压缩成了一个端到端的神经网络。没有候选区域生成,没有特征重采样,没有多阶段流水线。就是"图进去,框出来"。

我曾经在给团队培训时画过一张图,把YOLO和Faster R-CNN的流程对比了一下。YOLO的简洁性一目了然。

YOLO vs 传统方法(R-CNN系列)流程对比 传统方法(多阶段) 输入图片 生成候选框 (~2000个) 每个框 分类+回归 输出结果 ❌ 速度慢:候选框多,重复计算 YOLO(单阶段) 输入图片 一次前向传播 (CNN直接回归) S×S网格 预测框+类别 输出结果 ✅ 速度快:一次推理,直接出结果 核心差异:YOLO将检测视为回归问题,传统方法视为分类问题

1.4 为什么YOLO能这么快?

YOLO的速度优势,根源在于它的单阶段设计。但具体到实现层面,有几个关键设计值得注意。

  • 网格化预测:把图片分成网格,每个网格只负责自己区域内的目标。这相当于把全局问题分解成了局部问题,计算量大幅降低。
  • 全局上下文:YOLO在预测时能看到整张图,不像滑动窗口方法只能看到局部。这意味着它不容易被背景干扰。
  • 端到端训练:整个网络可以联合优化,不需要分阶段训练。损失函数直接衡量检测质量。
注意: YOLO的网格设计有一个隐含假设——每个网格最多只能预测固定数量的目标(如2个)。如果多个小目标挤在同一个网格里,YOLO可能会漏检。我曾经在密集人群检测项目中就踩过这个坑,后来通过调整网格大小和Anchor数量解决了。

1.5 YOLO的损失函数长什么样?

YOLO的损失函数,我当年看时觉得挺复杂。其实拆开来看,就三部分。

# YOLO损失函数(简化版)
Loss = λ_coord * 定位损失 + λ_obj * 置信度损失 + λ_cls * 分类损失

# 定位损失:预测框和真实框的坐标差异(MSE)
定位损失 = Σ (x_pred - x_true)² + (y_pred - y_true)² + (w_pred - w_true)² + (h_pred - h_true)²

# 置信度损失:预测框是否有目标的置信度差异
置信度损失 = Σ (confidence_pred - IoU)²

# 分类损失:预测类别和真实类别的差异
分类损失 = Σ (p_pred(c) - p_true(c))²

这里有个细节:定位损失的权重 λ_coord 通常设得比较大(比如5),因为坐标预测的准确性直接影响检测效果。而置信度损失中,没有目标的网格权重 λ_noobj 设得比较小(比如0.5),因为大部分网格都是背景。

嗯,这个权重设计其实挺讲究的。我刚开始调参时,直接把所有权重设成1,结果模型疯狂预测背景框。后来才明白,背景网格远多于前景网格,必须压低它们的权重。

1.6 本章小结

这一章我们走马观花地看了YOLO的全貌。从目标检测的基本任务,到YOLO家族的发展脉络,再到它"只看一次"的核心思想。你可能会觉得信息量有点大,没关系,后面每一章都会把这些概念掰开揉碎了讲。

记住一句话就够了:YOLO把目标检测变成了一个回归问题,用一次前向传播同时预测所有目标的类别和位置。 这是它快的原因,也是它优雅的地方。

动手试试: 打开你的浏览器,搜索"YOLOv8 demo",找个在线体验的网站,上传一张图片看看效果。亲眼看到模型画出框的那一刻,比读十篇都有用。