Phase 1:YOLO 原理与读源码
用大白话说:这一页帮你搞懂——YOLO 这个"认图模型"到底怎么工作的,以及怎么读它的源码、自己动手改一小处把它跑通。
目标:不搞懂原理就永远是被框架牵着走。这一阶往向内走——CNN 基础、YOLO 为什么 work、读 mmyolo/Ultralytics 源码、动手改一处跑通。
一、CNN 基础清单(地基,不牢先看 Python 补强)
- 卷积(说人话:让一个小窗口在图上滑动,提取局部花纹):用 kernel(小窗口)滑窗提取局部特征,输出的通道数 = 用了几个滤波器。
- BN(说人话:训练时给数据"调匀",让训练更稳、更快收敛):训练稳定、加速收敛。
- 激活(说人话:加一道"拐弯",让模型能学复杂形状,比如 ReLU):引入非线性。
- 感受野(说人话:图上某一处"看到了多大一片原图"):深层能看到多大原始区域——检测大目标靠它。
- 下采样(说人话:把图缩小,丢掉细节但保留大意思,比如 stride/pooling):特征图变小、语义变强、位置变粗。
二、YOLO 为什么 work(核心 insight)
先认词:YOLO(说人话:一种很快的"认图模型",能在一张图里框出人/车并认出是什么);模型(说人话:训练好的、能认东西的"大脑"文件)。
核心一句话:把检测变成「单次回归 + 分类」——把图切成网格,每个格子直接预测「有没有目标 + 框在哪 + 是什么类」。一个网络一次出结果,所以快。
几个词先认一下:anchor(说人话:提前设好的一堆"参考框",帮模型猜框在哪);anchor-free(说人话:不预设参考框,直接让模型自己学);IoU(说人话:预测框和真实框重合了多少,越高越准)。
| 概念 | 解决什么 | 你该追问 |
|---|---|---|
| anchor vs anchor-free | 框的先验怎么来 | 新版 YOLO 大多 anchor-free,为什么? |
| grid 分配 | 目标归哪个格子负责 | 一个大目标跨多格怎么办? |
| 损失:box/cls/obj | 框、类、有无目标分别算误差 | 为什么三类要加权? |
| IoU 家族(GIoU/DIoU/CIoU) | 框误差怎么衡量(见方法论章) | CIoU 比 IoU 多补了什么? |
| 标签分配(ATSS/simOTA/TAL) | 哪个预测框配哪个真值 | 动态分配比静态好在哪? |
三、读源码:带一张图追数据流
不要泛读。打开 mmyolo(MMDetection 系,结构清晰)或 Ultralytics,从三层入手:
先认词:backbone(说人话:负责"看"图、一层层提取特征的主体);neck(说人话:把不同大小的特征揉在一起);head(说人话:最后出结果的地方,给出框+类+置信度)。
backbone → 提特征(层层下采样,出多尺度特征图)
neck → 把多尺度特征融合(FPN/PAFPN,让小目标也有语义)
head → 在每个尺度上出预测(框 + 类 + 置信度)
练习:拿一张 640×640 图,跟它从 model(frame) 进来到输出框,在每一层 print(tensor.shape),确认 shape 怎么变。这比读十遍文档有用。
四、动手:改一处跑通(读懂的闭环)
二选一,跑通后对比 mAP(说人话:衡量模型认得准不准的综合分数,越高越好):
- 改损失:把 CIoU 换成 DIoU(或反过来),看小目标 mAP 变化。
- 加注意力:在 neck 后插一个轻量注意力模块(如 SE / CBAM,说人话:让模型学会"盯着"重要区域),看召回变化。
别忘了:每次实验用 wandb/mlflow(说人话:记实验用的本子,帮你记住每次改了啥、结果如何)记超参 + 指标,不然改了一堆不知道哪个有用(见 Phase 2 指标部分)。
五、论文阅读顺序(演进脉络)
- YOLO v1(一次回归的开山)
- v3(多尺度,小目标起点)
- v5 / v8(工程化、anchor-free 化)
- v11(最新架构)
读每篇只抓「它解决了上一代什么痛点」,不用推公式。
六、🔧 Phase 1 验收
- 能讲清「为什么是一次回归」以及 CIoU 在补偿什么。
- 改一处网络/损失并跑通,输出 mAP 对比。
- 画得出 backbone/neck/head 的数据流图。
下一步:Phase 2 训练与数据——解决你之前的近/远漏检。