3、YOLO模型基础:回顾YOLO系列(v5/v8等)的网络结构、输出张量格式(边界框、置信度、类别概率)及锚框机制
在进入RKNN部署实战之前,必须对YOLO系列模型本身有透彻的理解。YOLO(You Only Look Once)系列从v1发展到v8,其核心设计哲学始终未变:将目标检测视为单次回归问题,直接从输入图像预测边界框和类别概率。然而,不同版本在网络结构、输出张量格式以及锚框机制上存在显著差异,这些差异直接决定了我们在RKNN工具链中如何进行模型转换、输入输出配置以及后处理代码的编写。本章将系统梳理YOLOv5和YOLOv8这两个在工业界应用最广的版本,为后续的RKNN部署打下坚实的理论基础。
上图展示了YOLO系列模型从输入到输出的完整数据流。可以看到,无论v5还是v8,其核心架构都遵循Backbone(主干网络)→ Neck(颈部)→ Head(头部)的三段式设计。Backbone负责从原始图像中提取丰富的语义特征,Neck通过特征金字塔网络(FPN)和路径聚合网络(PAN)实现多尺度特征的融合,而Head则最终输出检测结果。理解这一数据流是后续进行RKNN模型转换和NPU部署的前提。
3.1 YOLOv5与YOLOv8的网络结构核心差异
3.1.1 核心原理:从CSPDarknet到C2f
YOLOv5的Backbone采用了CSPDarknet53结构,其核心是CSP(Cross Stage Partial)模块。CSP模块将特征图分为两部分,一部分经过卷积块进行深度特征提取,另一部分直接与提取后的特征进行拼接(Concat),这种设计在减少计算量的同时保证了梯度流的丰富性。而YOLOv8将CSP模块升级为C2f(Cross Stage Partial with 2 convolutions and fusion)模块。C2f模块在CSP的基础上引入了更多的分支连接和更细粒度的特征融合,借鉴了ELAN(Efficient Layer Aggregation Network)的设计思想,使得梯度流更加多样化,特征表示能力更强。
在Neck部分,两者都采用了FPN+PAN的结构。FPN自顶向下传递强语义特征,PAN自底向上传递强定位特征,两者结合实现了多尺度特征的充分融合。但YOLOv8在Neck中同样使用了C2f模块替换了v5中的C3模块,进一步提升了特征融合的效率。
Head部分是两者差异最大的地方。YOLOv5采用Coupled Head(耦合头),即分类和回归任务共享一个卷积层,最后分别输出。而YOLOv8采用Decoupled Head(解耦头),将分类分支和回归分支完全分离,各自使用独立的卷积层。这一设计参考了FCOS和ATSS等Anchor-Free检测器的思路,有效解决了分类和回归任务对特征关注点不同的问题,加速了模型收敛并提升了精度。
| 对比维度 | YOLOv5 | YOLOv8 |
|---|---|---|
| Backbone模块 | CSPDarknet53(C3模块) | C2f模块(基于ELAN) |
| Neck结构 | FPN + PAN(C3) | FPN + PAN(C2f) |
| Head类型 | Coupled Head(耦合) | Decoupled Head(解耦) |
| 锚框机制 | Anchor-Based(预设锚框) | Anchor-Free(无锚框) |
| 损失函数 | GIOU Loss + BCE | DFL + CIOU Loss + BCE |
| 输出通道数 | A × (5 + C) | 4 + C(回归4 + 分类C) |
3.1.2 判断方法:如何从ONNX输出识别模型版本
在RKNN部署时,我们通常先将PyTorch模型导出为ONNX格式,再转换为RKNN格式。通过观察ONNX输出的张量形状,可以快速判断模型版本。对于YOLOv5,输出通常为3个维度的张量,形状为[1, 255, 80, 80]、[1, 255, 40, 40]和[1, 255, 20, 20](以COCO 80类为例,255 = 3 × (5 + 80))。而YOLOv8的输出形状为[1, 84, 8400],其中84 = 4(回归参数)+ 80(类别概率),8400 = 80×80 + 40×40 + 20×20,即所有尺度上的总锚点数量。这种1D扁平化输出是YOLOv8的显著特征。
3.2 输出张量格式深度解析
3.2.1 核心原理:YOLOv5的网格化输出
YOLOv5将输入图像划分为S×S的网格(例如80×80)。每个网格负责预测3个锚框(A=3),每个锚框包含4个边界框坐标(x, y, w, h)、1个目标置信度(objectness)以及C个类别概率。因此,每个网格的输出维度为A × (5 + C)。坐标x和y是相对于网格左上角的偏移量,经过Sigmoid函数归一化到[0,1]区间;w和h是相对于锚框宽高的缩放比例,同样经过指数函数处理。后处理时需要结合网格坐标和锚框尺寸进行解码。
3.2.2 核心原理:YOLOv8的扁平化输出
YOLOv8取消了锚框机制,改为直接预测每个位置到边界框四条边的距离(DFL,Distribution Focal Loss),输出4个回归参数(通常为ltrb格式:left, top, right, bottom)。其输出张量形状为[1, 4+C, S_total],其中S_total是所有尺度网格点的总和。在解码时,需要将ltrb格式转换为标准的xywh格式,并乘以对应的Stride(步长)映射回原图尺寸。由于没有锚框,YOLOv8的解码过程更加简洁,减少了预设锚框带来的超参数调整负担。
# YOLOv5 解码伪代码(Anchor-Based)
for each grid (i, j) at stride s:
for each anchor a:
tx, ty, tw, th, obj, cls = output[i, j, a]
x = (i + sigmoid(tx)) * s
y = (j + sigmoid(ty)) * s
w = anchor_w[a] * exp(tw)
h = anchor_h[a] * exp(th)
# YOLOv8 解码伪代码(Anchor-Free)
for each point k at stride s:
ltrb = output[0:4, k]
x = (point_x - ltrb[0]) * s
y = (point_y - ltrb[1]) * s
w = (ltrb[0] + ltrb[2]) * s
h = (ltrb[1] + ltrb[3]) * s
3.2.3 案例拆解:COCO数据集下的输出维度对比
以COCO数据集(80类)为例,输入640×640图像。YOLOv5的输出为三个4D张量:[1, 255, 80, 80]、[1, 255, 40, 40]、[1, 255, 20, 20],总计25200个候选框。YOLOv8的输出为单个3D张量[1, 84, 8400],总计8400个候选框。在RKNN后处理中,YOLOv5需要遍历三个输出层分别解码,而YOLOv8只需一次矩阵运算即可完成所有候选框的坐标还原。这种差异使得YOLOv8在NPU上的推理效率更高,减少了CPU后处理的负担。
3.3 锚框机制:从Anchor-Based到Anchor-Free的演进
3.3.1 核心原理:锚框的作用与局限
锚框(Anchor)是预先定义的一组不同尺寸和长宽比的矩形框。在YOLOv5中,针对COCO数据集预设了9组锚框,按面积大小分配到3个检测尺度上。例如,小尺度(Stride 8)使用[10,13, 16,30, 33,23],中尺度(Stride 16)使用[30,61, 62,45, 59,119],大尺度(Stride 32)使用[116,90, 156,198, 373,326]。锚框的作用是为模型提供先验的尺寸信息,使模型更容易学习目标的尺度变化。然而,锚框也带来了问题:需要针对特定数据集进行聚类分析来确定锚框尺寸,且锚框的超参数对检测精度影响较大。
3.3.2 判断方法:何时选择Anchor-Free
YOLOv8采用的Anchor-Free策略,直接预测每个位置的目标中心点到四条边的距离,彻底摆脱了对预设锚框的依赖。这种设计的优势在于:简化了模型设计,无需聚类生成锚框;提升了泛化能力,对于不同分布的数据集适应性更强;减少了超参数,降低了调参难度。在RKNN部署中,Anchor-Free模型的后处理代码更简洁,逻辑更清晰,更适合在资源受限的嵌入式平台上运行。
3.3.3 常见误区与总结复盘
- 误区一:认为YOLOv8完全不需要任何先验信息。实际上,YOLOv8虽然取消了锚框,但仍通过DFL损失函数学习边界框的分布,本质上是一种更柔性的先验学习方式。
- 误区二:混淆输出张量的维度顺序。YOLOv5的NCHW格式中,C通道包含所有锚框信息,而YOLOv8的NC S格式中,C通道是类别和回归参数的混合。在RKNN后处理时,必须按照正确的维度顺序进行解析。
- 误区三:忽略Stride对坐标映射的影响。无论是v5还是v8,解码后的坐标都需要乘以对应的Stride才能映射回原图尺寸。在RKNN中,如果输入尺寸不是640的整数倍,Stride的计算需要特别注意。