跳转到内容
新建笔记

YOLOv8 检测:结构、边界框解码与输出张量

本文讨论普通 YOLOv8 水平矩形框目标检测,不把分割、姿态与旋转框的输出混用。官方模型说明确认 YOLOv8 使用无锚框、分类与回归分支分离的检测头。YOLOv8 文档

处理链是:输入图像预处理 → 骨干网络提取特征 → 多尺度特征融合 → 检测头预测位置与类别 → 后处理。

YOLOv8 的 C2f、SPPF 与多尺度检测结构参考图

原图为已有笔记保留的结构参考,图中署名 RangeKing;实现细节以所使用的模型配置和代码版本为准。C2f 用于特征处理,SPPF 聚合不同感受野的信息,多尺度输出帮助处理大小不同的目标。

无锚框不等于没有参考位置

跳转到“无锚框不等于没有参考位置”

旧锚框方法可能用预设框宽高 pw,php_w,p_h 计算 w=pwetww=p_w e^{t_w}、h=phethh=p_h e^{t_h}。这不是本文 YOLOv8 检测头的解码公式,旧笔记中混入的对应图片已移除。

以 v8.3.0 的实现为例,网络在特征图参考点附近预测到框四边的距离。设参考点为 (ax,ay)(a_x,a_y),距离为 (l,t,r,b)(l,t,r,b),则在该特征层坐标中:

x1=ax−l,y1=ay−t,x2=ax+r,y2=ay+b.x_1=a_x-l,\quad y_1=a_y-t,\quad x_2=a_x+r,\quad y_2=a_y+b.

换成中心与尺寸:

cx=x1+x22,cy=y1+y22,w=x2−x1,h=y2−y1.c_x=\frac{x_1+x_2}{2},\quad c_y=\frac{y_1+y_2}{2},\quad w=x_2-x_1,\quad h=y_2-y_1.

再按对应步长换算到网络输入尺度。距离回归使用离散分布时,某一边的距离可写成期望 d=∑kk pkd=\sum_k k\,p_k,其中 pkp_k 是该边离散位置的归一化概率。代码中的 anchors 可指参考点,并不意味着存在预设宽高的锚框。固定版本 Detect、dist2bbox 与 make_anchors

为什么常见输出是 1 × 84 × 8400

跳转到“为什么常见输出是 1 × 84 × 8400”

假设批量为 1、网络输入为 640×640640\times640,三个检测层步长为 8、16、32:

N=(640/8)2+(640/16)2+(640/32)2=802+402+202=8400.N=(640/8)^2+(640/16)^2+(640/32)^2 =80^2+40^2+20^2=8400.

COCO 检测模型有 80 个类别,常见的已解码、未执行 NMS 的导出输出每个候选包含 4 个框坐标和 80 个类别分数,于是通道数为 4+80=844+80=84。这一格式没有另外一个需要再乘的独立 objectness 通道。

已有笔记中的 84×8400 检测张量示意;仅适用于对应模型配置

类别数、输入大小、导出选项和任务类型改变时,形状也会改变。先读取实际张量维度,不能只按某张图硬编码。

  1. 确认输出布局是 [B,C,N] 还是其他布局;必要时转成逐候选的 [N,C]。
  2. 从类别分数选取类别与分数,按阈值筛选;这一步不等于 NMS。
  3. 将中心宽高转换为角坐标,按所用策略执行类别相关或无关的 NMS。
  4. 撤销预处理中的缩放与 padding,映射回原图并裁剪边界。
  5. 检查导出模型是否已内置 NMS;已处理过的输出不要再按原始候选格式重复解析。

一份可复现记录至少写明:权重名称、Ultralytics 版本、任务、输入尺寸、预处理方式、导出选项以及运行时读取的输出形状。