2. YOLO算法基础回顾
做嵌入式AI这几年,我接触最多的目标检测框架就是YOLO。说实话,从v3到v5,每一代都有让我眼前一亮的设计。今天咱们就把这三代的核心思想、网络结构、Anchor机制捋一遍。这些东西是后面做多线程流水线的基础,你得吃透。
YOLOv3:奠定现代YOLO的基石
YOLOv3在2018年发布,我至今记得第一次在嵌入式设备上跑通它时的兴奋。它解决了之前版本对小目标检测差的问题,核心改进有三点。
1. Backbone:Darknet-53
Darknet-53借鉴了ResNet的残差结构,但去掉了那些花哨的瓶颈设计。它用连续的3×3和1×1卷积堆叠,配合步长为2的卷积做下采样。我做过对比,在同样计算量下,Darknet-53比ResNet-50的mAP高2-3个点。
关键参数:Darknet-53包含53个卷积层,下采样32倍。特征图尺寸变化:416→208→104→52→26→13。
2. Neck:FPN结构
YOLOv3引入了特征金字塔网络(FPN)。它把深层语义信息和浅层位置信息融合起来。具体做法是:从13×26×52三个尺度分别做上采样和拼接。
我在项目中遇到过一个问题:FPN的拼接操作在嵌入式设备上很吃内存带宽。后来我们做了通道裁剪,把拼接后的通道数从512降到256,速度提升30%,精度只掉了0.5%。
3. Head:多尺度预测
YOLOv3在三个尺度上做预测,每个尺度负责不同大小的目标。13×13负责大目标,26×26负责中目标,52×52负责小目标。每个网格预测3个边界框,每个框包含(x, y, w, h, confidence, 80类概率)。
| 特征图尺寸 | 感受野 | 负责目标 | 输出通道 |
|---|---|---|---|
| 13×13 | 大 | 大目标(如汽车) | 255 |
| 26×26 | 中 | 中目标(如人) | 255 |
| 52×52 | 小 | 小目标(如鸟) | 255 |
我的经验:在嵌入式场景下,52×52这个尺度的计算量最大,但小目标召回率提升明显。如果场景中小目标不多,可以砍掉这个分支。
YOLOv4:工程优化的集大成者
YOLOv4在2020年发布,它没有提出全新的网络结构,而是把当时最有效的trick都整合到一起。我个人觉得,v4是工程落地最友好的一版。
1. Backbone:CSPDarknet-53
v4把Darknet-53改成了CSP结构。CSPNet的核心思想是把特征图分成两部分,一部分走密集连接,一部分走捷径。这样做的好处是减少了计算量,同时缓解了梯度消失。
我记得第一次在Jetson Nano上跑v4,帧率比v3高了15%。原因就是CSP结构减少了内存访问次数。
2. Neck:SPP + PANet
v4在Neck部分做了两个重要改进:
- SPP模块:用不同尺寸的池化核(5×5、9×9、13×13)提取多尺度特征,然后拼接。这个模块对感受野的增强效果很明显。
- PANet:在FPN基础上增加了一条自底向上的路径。FPN是把高层信息传给低层,PANet又把低层位置信息传回高层。双向融合后,小目标的定位精度提升明显。
避坑指南:我曾经在部署时发现SPP模块的padding计算容易出错。池化核尺寸和stride不匹配会导致特征图尺寸对不上。建议用PyTorch的nn.AdaptiveAvgPool2d替代固定尺寸池化。
3. Head:延续v3的多尺度设计
v4的Head基本沿用v3的设计,但做了两点优化:
- 用CIoU Loss替代IoU Loss,解决了预测框和真实框不重叠时梯度为0的问题。
- 用DIoU NMS替代普通NMS,在密集场景下漏检率更低。
YOLOv5:轻量化与易用性的平衡
YOLOv5不是官方团队的作品,但它在工程界的普及度最高。我身边做嵌入式部署的同事,90%都在用v5。为什么?因为它太好用了。
1. Backbone:CSPNet + Focus结构
v5在v4的基础上做了轻量化改造。Focus结构把输入图像每隔一个像素取一个值,拼成4张特征图。这样在保持信息量的同时,把计算量降到了原来的1/4。
举个例子:输入640×640×3的图像,经过Focus变成320×320×12。这个操作在硬件上可以用切片+拼接实现,非常高效。
2. Neck:CSP-PANet
v5把PANet中的普通卷积换成了CSP卷积。CSP卷积的计算量比普通卷积少20%,但精度几乎不变。对于嵌入式设备来说,这20%的节省很关键。
3. Head:自适应Anchor
v5在训练时会自动计算数据集的Anchor尺寸。你不需要手动调参,它会根据训练集的标注框分布,用K-means聚类出最优的Anchor。
实测数据:在COCO数据集上,v5s(小模型)的mAP@0.5达到56.8%,在Jetson Nano上推理速度达到30FPS。这个性价比在2021年几乎没有对手。
Anchor机制:从手工设计到自适应
Anchor机制是YOLO的核心。说白了,就是预设一些固定尺寸的框,让模型在这些框的基础上做微调。
1. Anchor是什么
每个网格预测3个Anchor。Anchor的尺寸是相对于特征图的,比如13×13特征图上的Anchor可能是(116, 90)、(156, 198)、(373, 326)。这些值是通过K-means聚类训练集标注框得到的。
2. 预测公式
YOLO不直接预测框的坐标,而是预测偏移量:
bx = σ(tx) + cx
by = σ(ty) + cy
bw = pw * exp(tw)
bh = ph * exp(th)
其中(cx, cy)是网格坐标,(pw, ph)是Anchor宽高。σ是sigmoid函数,把偏移量限制在0-1之间。
3. 不同版本的Anchor设计
| 版本 | Anchor数量 | 获取方式 | 特点 |
|---|---|---|---|
| v3 | 9(3尺度×3个) | K-means聚类 | 固定,需手动计算 |
| v4 | 9 | K-means + 遗传算法优化 | 更贴合数据集分布 |
| v5 | 9 | 自适应计算 | 训练时自动调整 |
我的建议:在嵌入式场景下,不要直接用COCO的Anchor。你的数据集目标尺寸分布可能完全不同。我习惯在训练前先跑一次K-means,把Anchor换成适合自己场景的。
YOLO v3/v4/v5核心对比
下面这张表是我做技术选型时常用的参考:
| 维度 | YOLOv3 | YOLOv4 | YOLOv5 |
|---|---|---|---|
| Backbone | Darknet-53 | CSPDarknet-53 | CSPNet + Focus |
| Neck | FPN | SPP + PANet | CSP-PANet |
| Head | 多尺度 | 多尺度 + CIoU | 多尺度 + 自适应Anchor |
| 计算量 | 65.2 GFLOPs | 60.1 GFLOPs | 16.5 GFLOPs (v5s) |
| 嵌入式友好度 | 中等 | 较好 | 优秀 |
YOLO v3/v4/v5 核心架构对比图
下面这张SVG图展示了三代YOLO在Backbone、Neck、Head三个模块上的演进关系。你可以直观看到v3到v5的变化脉络。
嵌入式部署的选型建议
说了这么多,到底该选哪个版本?我根据实际项目经验给个参考:
- 算力充足(如Jetson Xavier):选YOLOv4,精度最高,部署工具链成熟。
- 算力中等(如Jetson Nano):选YOLOv5s或v5n,速度和精度的平衡点最好。
- 算力受限(如MCU):选YOLOv5n,配合INT8量化,可以在1-2W功耗下跑15FPS。
注意:不要盲目追求最新版本。我在一个工业检测项目中试过YOLOv8,精度确实高,但模型体积大了3倍,在嵌入式设备上根本跑不动。选型要看实际硬件约束。
好了,YOLO的基础知识就回顾到这里。这些内容看起来多,但核心就三件事:Backbone提特征、Neck做融合、Head出结果。后面的章节我们会把这些模块拆开,放到多线程流水线里逐个优化。