YOLOv8 架构深度研究报告

YOLOv8 架构深度研究报告

重要说明:Ultralytics 未发布经过同行评审的 YOLOv8 官方论文,所有架构细节依赖源码(ultralytics GitHub)和官方文档。


术语命名对照表

网络结构模块

缩写 英文全称 中文译名
C3 Cross Stage Partial Bottleneck with 3 Convolutions 跨阶段部分瓶颈-3卷积
C2f Cross Stage Partial Bottleneck with 2 Convolutions and finer flow 跨阶段部分瓶颈-2卷积-细粒度流
CSP Cross Stage Partial (Network) 跨阶段部分(网络)
ELAN Efficient Layer Aggregation Network 高效层聚合网络
E-ELAN Expanded Efficient Layer Aggregation Network 扩展高效层聚合网络
SPPF Spatial Pyramid Pooling - Fast 空间金字塔池化-快速版
Bottleneck Bottleneck (Residual Block) 瓶颈层(残差块)
RepConv Reparameterized Convolution 重参数化卷积
Backbone Backbone Network 主干网络(特征提取)
Neck Neck Network 颈部网络(特征融合)
Head Detection Head 检测头(输出预测)

检测头与标签分配

缩写 英文全称 中文译名
FCOS Fully Convolutional One-Stage (Detector) 全卷积单阶段检测器
TAL TaskAlignedAssigner 任务对齐标签分配器
OTA Optimal Transport Assignment 最优传输标签分配
SimOTA Simplified Optimal Transport Assignment 简化最优传输标签分配
Anchor-free Anchor-free Detection 无锚框检测(无需预定义候选框)
Anchor-based Anchor-based Detection 基于锚框检测(使用预定义候选框)
Decoupled Head Decoupled Detection Head 解耦检测头(分类与回归分支分离)

损失函数

缩写 英文全称 中文译名
IoU Intersection over Union 交并比(预测框与真实框的重叠度量)
GIoU Generalized IoU 广义交并比(IoU + 包围框惩罚)
DIoU Distance IoU 距离交并比(IoU + 中心点距离惩罚)
CIoU Complete IoU 完整交并比(IoU + 中心距离 + 宽高比惩罚)
BCE Binary Cross-Entropy 二元交叉熵(分类损失)
DFL Distribution Focal Loss 分布焦点损失(边界框概率分布建模)
GFL Generalized Focal Loss 广义焦点损失(DFL 的理论基础)
QFL Quality Focal Loss 质量焦点损失(YOLOv8 未采用)
DGQP Distribution-Guided Quality Predictor 分布引导质量预测器

特征金字塔

缩写 英文全称 中文译名
FPN Feature Pyramid Network 特征金字塔网络(自顶向下特征融合)
PAN Path Aggregation Network 路径聚合网络(自底向上特征融合)
PAN-FPN PAN + FPN (Bi-directional) 双向特征金字塔(YOLOv8 Neck 结构)

评估指标

缩写 英文全称 中文译名
AP Average Precision 平均精度(单一 IoU 阈值下的精度)
mAP mean Average Precision 各类别平均精度均值(先求单类 AP,再跨类别取均值)
mAP@50-95 mAP at IoU 0.50 to 0.95 IoU 从 0.50 到 0.95 的 mAP 平均值
COCO Common Objects in Context 上下文中的常见物体(目标检测基准数据集)
FLOPs Floating Point Operations 浮点运算次数(衡量计算量)
FPS Frames Per Second 每秒帧数(衡量推理速度)

模型缩放与部署

缩写 英文全称 中文译名
reg_max Regression Max Bins 回归最大离散桶数(DFL 的离散化参数)
INT8 8-bit Integer Quantization 8 位整数量化
FP16 16-bit Floating Point (Half Precision) 半精度浮点
FP32 32-bit Floating Point (Single Precision) 单精度浮点
TOPS Tera Operations Per Second 每秒万亿次运算(NPU 算力单位)
NPU Neural Processing Unit 神经网络处理单元
RKNN Rockchip Neural Network 瑞芯微神经网络格式
ONNX Open Neural Network Exchange 开放神经网络交换格式
TensorRT TensorRT (NVIDIA Inference Optimizer) NVIDIA 推理优化引擎

数据增强

术语 英文全称 中文译名
Mosaic Mosaic Augmentation 马赛克增强(4 张图拼接为 1 张)
MixUp MixUp Augmentation 混合增强(2 张图按比例叠加混合)
Copy-Paste Copy-Paste Augmentation 复制粘贴增强(实例级复制粘贴)

一、网络整体结构:Backbone + Neck + Head

YOLOv8 是 Ultralytics 于 2023 年发布的目标检测架构,在 YOLOv5 基础上进行了四项核心改进:C2f 模块替代 C3、保留 PAN-FPN 双向 Neck、引入 Anchor-free 解耦检测头、采用 Distribution Focal Loss + CIoU 损失。

1.1 Backbone:C2f 模块 + 5 级特征金字塔

YOLOv8 Backbone 采用 C2f(Cross Stage Partial Bottleneck with 2 Convolutions and finer flow,跨阶段部分瓶颈-2卷积-细粒度流)模块 (替代 YOLOv5 的 C3(Cross Stage Partial Bottleneck with 3 Convolutions,跨阶段部分瓶颈-3卷积) )构成 5 级特征金字塔 P1--P5 ,末端接 SPPF(Spatial Pyramid Pooling - Fast,空间金字塔池化-快速版,k=5, ch=1024)

复制代码
P1/2  →  P2/4  →  P3/8  →  P4/16  →  P5/32
(stem)    C2f       C2f       C2f        C2f + SPPF

C2f vs C3 的核心差异(基于源码分析):

「3」和「2」指的是什么? ------指模块外围主卷积层数量,不是 Bottleneck 内部的卷积数。

C3(Cross Stage Partial Bottleneck with 3 Convolutions,跨阶段部分瓶颈-3卷积)

python 复制代码
# YOLOv5 源码
class C3(nn.Module):
    cv1 = Conv(c1, c_, 1, 1)        # ① 主分支降维
    cv2 = Conv(c1, c_, 1, 1)        # ② 跳跃分支降维
    cv3 = Conv(2*c_, c2, 1)          # ③ 拼接后融合
复制代码
                Input
                  │
        ┌─────────┴─────────┐
        │                   │
      cv1                 cv2          ← 两个分支各自的 1×1 降维
        │                   │
  Bottleneck × n            │          ← 主分支:B1→B2→...→Bn 链式串联
        │                   │
        └──────Concat───────┘          ← 只拼接最后一个 Bottleneck 的输出
                  │
                 cv3                   ← 拼接后 1×1 融合
                  │
               Output
  • 外围 3 个主卷积(cv1, cv2, cv3)→ 故名 C3
  • CSP 分流:输入分成两路,主分支经过 Bottleneck 链,跳跃分支直通
  • 只有最后一个 Bottleneck 的输出参与拼接
  • 梯度必须逐层回传:Loss → cv3 → Concat → Bn → ... → B2 → B1 → cv1

C2f(Cross Stage Partial Bottleneck with 2 Convolutions and finer flow,跨阶段部分瓶颈-2卷积-细粒度流)

python 复制代码
# YOLOv8 源码
class C2f(nn.Module):
    cv1 = Conv(c1, 2*c_, 1, 1)      # ① 入口卷积
    cv2 = Conv((2+n)*c_, c2, 1)     # ② 出口卷积(处理拼接后的多通道)
复制代码
                Input
                  │
                 cv1
                  │
        ┌─────────┴─────────┐
        │                   │
    y0 (skip)              B1
        │                   │
        │                  B2
        │                   │
        │                  B3
        │                   │
        ▼         ▼    ▼    ▼
      ┌────────────────────────┐
      │  Concat(y0, B1, B2, B3) │
      └────────────────────────┘
                  │
                 cv2
                  │
               Output

注意:每个 Bottleneck 的输出(B1、B2、B3)都独立参与 Concat,而不仅仅是最后一个 B3。这是 C2f 与 C3 的核心区别。

  • 外围仅 2 个主卷积(cv1, cv2)→ 故名 C2
  • 后缀 f = finer flow(更细粒度的梯度流)
  • 每个 Bottleneck 的输出都直接参与最终拼接(类似 DenseNet 的密集连接 + CSP 分流)
  • 梯度路径更短:Loss → Concat → B1/B2/B3/skip 各自独立回传

核心差异不是卷积数量,而是特征拼接策略

对比维度 C3 C2f
外围卷积数 3(cv1, cv2, cv3) 2(cv1, cv2)
Bottleneck 输出拼接 仅最后一个 所有 Bottleneck 输出
梯度回传路径 链式逐层(B3→B2→B1) 并联直达(各层独立)
Concat 通道数 2 × c_ (2 + n) × c_(n = Bottleneck 数)
参数量 --- 与 C3 同量级(取决于 n、e、c1、c2 具体配置)
真正收益 --- 梯度流优化、特征复用增强、小目标特征保留更好

注意 :C2f 的优势不在于减少参数量(实际参数量与 C3 同量级,有时略低、有时持平、有时甚至略大),而在于梯度流优化和特征复用。

核心差异对比图

复制代码
YOLOv5 C3                          YOLOv8 C2f

  Input                              Input
    │                                  │
  ┌─┴─┐                              cv1
  │   │                                │
 cv1 cv2                            split → [y0, y1]
  │   │                                │
  B   │                                ├─ y0 (skip)
  │   │                                ├─ y1
  B   │                                │
  │   │                                B1
  B   │                                │
  │   │                                B2
  │   │                                │
Concat│                                B3
  │   │                                │
  cv3                               Concat(y0, y1, B1, B2, B3)
                                       │
                                      cv2
                                       │
                                    Output

本质区别:只拼接最后一个 Bottleneck  →  拼接所有 Bottleneck 输出

本项目场景启示 :对于跑冒滴漏、积水、烟火、鼠类等小目标和弱纹理目标,C2f 的多层特征保留能力更强------浅层细节不会在链式传递中丢失,这比单纯提升 FPS 更有价值。

Bottleneck 模块详解

C3 和 C2f 内部反复出现的 Bottleneck(瓶颈模块) 是 CNN 中最经典的基础积木之一,本质上是一个带残差连接的轻量特征提取单元

为什么叫"瓶颈"? ------源自 ResNet,通道数经历 宽 → 窄 → 宽 的变化,形似瓶颈:

复制代码
256 通道(宽)
   ↓  1×1 Conv 压缩
 64 通道(窄)← 在此做 3×3 卷积,计算量大幅减少
   ↓  1×1 Conv 恢复
256 通道(宽)

目的:先用 1×1 卷积降通道减少计算量,在窄通道上做 3×3 特征提取,最后恢复通道数。

YOLOv5/YOLOv8 中的 Bottleneck 实现

python 复制代码
# 源码逻辑
cv1 = Conv(c1, c_, 1)     # 1×1 降维
cv2 = Conv(c_, c2, 3)     # 3×3 特征提取
return x + cv2(cv1(x))     # 残差连接
复制代码
            ┌────────────┐
Input ─────►│ 1×1 Conv   │
            └─────┬──────┘
                  │
            ┌─────▼──────┐
            │ 3×3 Conv   │
            └─────┬──────┘
                  │
                  ▼
              Feature
                          ┌───────────┐
Input ───────────────────►│ Add (+)   ├──► Output
                          └───────────┘

残差连接(Residual)的作用Output = F(x) + x,梯度可通过跳跃连接直接回传,缓解深层网络的梯度消失问题。

层级关系(从小到大):

复制代码
Backbone(主干网络)
 └─ C2f / C3(特征组织模块)
      └─ Bottleneck × n(特征提取单元,重复 n 次)
           ├─ 1×1 Conv(降维)
           ├─ 3×3 Conv(特征提取)
           └─ Residual Add(残差连接)

类比:Backbone 是一栋楼,C2f 是一个房间,Bottleneck 是房间里的工位,Conv 是具体干活的员工。真正提取特征的核心单元是 Bottleneck,C2f 的作用是把多个 Bottleneck 组织起来,让梯度和特征流动得更高效。

与 YOLOv7 的对比:YOLOv8 未采用 E-ELAN/RepConv 等重参数化技巧,结构更接近 YOLOv5 的简洁路线。

1.2 Neck:PAN-FPN 双向融合

为什么需要 Neck? Backbone 已经提取了特征,但存在一个根本矛盾:

复制代码
深层特征(P5):知道"是什么",但不知道"在哪里"(语义强,定位弱)
浅层特征(P3):知道"在哪里",但不知道"是什么"(定位强,语义弱)

Neck 的作用就是把不同尺度的信息融合起来。

P3/P4/P5 到底是什么?(特征图详解)

P3/P4/P5 不是图片尺寸 ,而是特征图(Feature Map)的尺寸

P 是什么的缩写? ------来自 FPN(Feature Pyramid Network)论文的命名惯例,P = Pyramid Level(金字塔层级)

命名 含义 来源
C (C2, C3, C4, C5) Conv Stage(骨干网络的卷积阶段输出) Backbone 原始特征层
P (P2, P3, P4, P5) Pyramid Level(金字塔特征层) 经 FPN 融合后的特征层

YOLO 系列沿用了这个习惯,配置文件中 Detect: [P3, P4, P5] 意思就是"在小/中/大三个金字塔层上做检测",不用纠结它是某个具体单词的首字母。

下采样过程:Backbone 中每经过一个 stride=2 的卷积,特征图尺寸缩小一半:

复制代码
输入图片 640×640
    ↓  stride=2(÷2)
   320×320
    ↓  stride=2(÷2)
   160×160
    ↓  stride=2(÷2)
    80×80   ← P3(累计缩小 8 倍 → 记为 P3/8)
    ↓  stride=2(÷2)
    40×40   ← P4(累计缩小 16 倍 → 记为 P4/16)
    ↓  stride=2(÷2)
    20×20   ← P5(累计缩小 32 倍 → 记为 P5/32)

特征图不是图片 :P3 的完整形态是 80×80×256------80×80 是空间位置,256 是特征通道数。这些通道不是 RGB 颜色,而是网络学到的抽象特征(边缘、纹理、形状、语义等),即:

复制代码
80×80 个小格子,每个格子记录 256 种特征

为什么不同层适合不同大小的目标?

以一个 20×20 像素的老鼠为例:

特征层 映射后大小 结果
P3/8 20÷8 ≈ 2.5 格 占 2~3 格,还能看见
P5/32 20÷32 ≈ 0.6 格 不到 1 格,几乎消失

以一个 200×400 像素的人为例:

特征层 映射后大小 结果
P3/8 25×50 格 太大,很多格子描述同一个人,计算浪费
P5/32 6×12 格 刚好合适

因此:

复制代码
P3/8  → 小目标检测层(分辨率高,看得细、看得近)
P4/16 → 中目标检测层(中等分辨率)
P5/32 → 大目标检测层(感受野大,看得远、看得全)

Detect(P3, P4, P5) 即"小/中/大目标检测层",对应同一张输入图缩小 8/16/32 倍后的特征图。

Backbone 输出了什么?
层级 分辨率 下采样 特点 本项目场景
P3 80×80 ÷8 分辨率高,看得细、看得近 漏水、水滴、烟火、鼠类(最重要)
P4 40×40 ÷16 中等 猫、狗、积水
P5 20×20 ÷32 感受野大,看得远、看得全 人员入侵
Neck 中的三个核心操作

理解 Neck 之前,先搞懂它反复使用的三个操作:

① Upsample(上采样)------ 放大特征图,统一尺寸

P5 是 20×20,P4 是 40×40,尺寸不同无法直接融合。Upsample 把 P5 放大到 40×40,才能与 P4 拼接:

复制代码
20×20 特征图              Upsample 2×后             40×40 特征图
┌────┐                                    ┌────────────────┐
│1 2 │                                    │1 1 2 2│
│3 4 │       最近邻插值                     │1 1 2 2│
└────┘      ──────────►                   │3 3 4 4│
                                          │3 3 4 4│
                                          └────────────────┘
  • YOLOv8 默认使用最近邻插值(Nearest Neighbor),速度最快
  • 作用类比:把一张小照片放大,和另一张同样大小的照片放在一起比较
  • 本质:每个格子复制成 2×2 个格子,通道数不变(20×20×512 → 40×40×512)

② Concat(拼接)------ 把特征堆在一起,通道数相加

Concat 不是加法,而是沿通道维度堆叠

复制代码
P4 原始特征:  40×40×256  (256 种特征:边缘、纹理、轮廓...)
P5 上采样后:  40×40×512  (512 种特征:类别语义...)
         ──── Concat ────
拼接结果:     40×40×768  (768 种特征全部保留)
  • 空间尺寸不变(仍是 40×40),只增加通道数
  • 类比:两个部门开会,把各自的资料都堆到桌上------还没讨论,只是放一起

③ C2f(融合处理)------ 真正"炒菜",完成特征融合

Concat 只是把特征堆在一起(768 通道里有大量冗余),C2f 才负责真正的融合

复制代码
输入:40×40×768(P4 定位特征 + P5 语义特征的简单堆叠)
         │
        C2f
  ┌──────────────┐
  │ cv1 → split  │
  │  ├─ skip ─────────────────────┐
  │  ├─ B1(融合筛选)──────────┤
  │  ├─ B2(增强优化)─────────┤
  │  └─ B3(进一步提炼)───────┤
  │  Concat → cv2                │
  └──────────────┘
         │
输出:40×40×c2(融合后的精炼特征:既有定位,又有语义)
  • C2f 内部的多个 Bottleneck 对拼接后的特征进行融合、筛选、增强
  • 类比:Concat 是把菜倒进锅里,C2f 才是真正炒菜
  • 最终输出通道数由 c2 参数控制,通常会压缩回合理范围

三步串联总结

复制代码
P5(20×20×512)
    │
 Upsample          ← 第①步:放大,统一尺寸
    │
 40×40×512
    │
 Concat(P4)        ← 第②步:拼接,堆叠特征
    │
 40×40×768
    │
   C2f             ← 第③步:融合,提炼精华
    │
 40×40×c2          ← 融合后的精炼特征

总结:Upsample 将高层特征送到低层,Concat 将特征堆叠,C2f 完成特征融合。

第一步:FPN(Feature Pyramid Network)------ 语义向下传播

P5 语义丰富但分辨率低(20×20),定位不准;P3 分辨率高但语义不足。FPN 把 P5 的高级语义自顶向下传递给浅层:

复制代码
      P5(20×20,强语义)
       │
   Upsample(上采样放大)
       │
       ▼
P4 ── Concat(拼接)
       │
      C2f(融合处理)
       │
   Upsample
       │
       ▼
P3 ── Concat(拼接)
       │
      C2f(融合处理)
       │
  输出 N3(80×80,兼具语义 + 定位)

效果 :P3 不再只是边缘和纹理,而是变成了带有类别语义的小目标特征

第二步:PAN(Path Aggregation Network)------ 位置向上传播

FPN 自上而下传递语义时,位置信息被稀释 了。PAN 反方向再融合一次,把浅层的精确定位信息自底向上送回高层:

复制代码
P3(80×80,强定位)
 │
Conv s=2(步长2下采样,缩小分辨率)
 │
 ▼
P4 ── Concat(拼接)
 │
C2f(融合处理)
 │
Conv s=2(下采样)
 │
 ▼
P5 ── Concat(拼接)
 │
C2f(融合处理)
 │
输出 N5(20×20,兼具语义 + 定位)

纠正一个常见误解:很多文章写"PAN 传递位置信息、FPN 传递语义信息",容易让人误以为 P3 里只有位置、P5 里只有语义。更准确的理解是:

层级 更擅长什么 不是什么
P3 保留更多空间细节(定位占优势) ❌ 不是"只有位置"
P5 保留更多抽象语义(分类占优势) ❌ 不是"只有语义"

"位置信息"到底是什么?

不是目标的坐标值(x=102, y=217),而是有助于边界框回归的边缘、轮廓、纹理、形状等细节特征:

复制代码
以 640×640 图片中一只老鼠为例:

P3(80×80):老鼠坐标映射到格子(13,27)
  → 耳朵、尾巴、轮廓等细节还在 ← 定位能力强

P5(20×20):同一只老鼠只剩不到1个格子
  → 耳朵没了、尾巴没了、边缘模糊了
  → 只剩"这是个动物"这种抽象信息 ← 语义能力强

FPN 向下传播的是什么?

复制代码
把 P5 的高级认知("这是猫""这是人""这是漏水")送给 P4 和 P3

原来的 P3:看见轮廓,但不知道是猫还是狗
融合 P5 后:既知道轮廓,又知道类别

PAN 向上传播的是什么?

经过 FPN 后,P3/P4/P5 都有语义了,但高层仍然缺少精细边界。PAN 把 P3 的高分辨率特征重新送回去:

复制代码
送的不是坐标值(x=100, y=200)
而是:边缘、轮廓、纹理、形状 ← 有助于边界框回归的信息

总结:FPN 将高层语义特征("是什么")传递给低层;PAN 将低层空间细节特征("边界在哪里")传递给高层。

本项目场景:漏水、水滴、火苗、鼠类这些目标边界都比较模糊,小目标又多,PAN 的价值往往比很多人想象的更大。没有 PAN,仅靠 FPN,检测框通常会更粗、更飘,尤其是漏水和火苗这类目标。

双向融合总览

PAN 阶段的输入不是 Backbone 的原始 P3/P4/P5,而是 FPN 的输出。两阶段是串联关系:

命名说明 :N3/N4/N5 和 N3'/N4'/N5' 不是 YOLOv8 官方命名,官方源码始终使用 P3/P4/P5。N 是论文和博客中为区分 Neck 不同阶段特征而添加的非正式标签(N = Neck Feature)。实际工程中,由于空间尺寸始终为 80×80/40×40/20×20,很多资料统称 P3/P4/P5,只是内部特征已被 FPN 和 PAN 重新融合。

复制代码
        ┌─── FPN(自顶向下)───┐   ┌─── PAN(自底向上)───┐
        │ 增强低层语义表达能力 │   │ 增强高层空间细节能力 │
        │                      │   │                      │
        │  P5 ──────────┐      │   │                      │
        │   ↓ Upsample  │      │   │  N3 ──────────┐      │
        │  P4 ← Concat  │      │   │   ↓ Conv s=2  │      │
        │   ↓ C2f       │      │   │  N4 ← Concat  │      │
        │   ↓ Upsample  │      │   │   ↓ C2f       │      │
        │  P3 ← Concat  │      │   │   ↓ Conv s=2  │      │
        │   ↓ C2f       │      │   │  N5 ← Concat  │      │
        │   ↓           │      │   │   ↓ C2f       │      │
        │  输出 N3      │ ───► │   │   ↓           │      │
        └───────────────┘      │   │  输出 N5'     │      │
                               │   └───────────────┘

完整数据流

复制代码
Backbone 输出          FPN 阶段              PAN 阶段              最终输出
─────────────    ────────────────    ────────────────    ────────────────
P5 (20×20)  ──┐                      N3 (80×80)  ──┐
              │                                     │
P4 (40×40)  ──┼── FPN ──► N3 (80×80) ──┐           ├── PAN ──► N3' (80×80)
              │           N4 (40×40)  ──┼──┐        │           N4' (40×40)
P3 (80×80)  ──┘           N5 (20×20)  ──┘  └──┐    │           N5' (20×20)
                                               └────┘

FPN / PAN 实际作用

阶段 层级 操作 实际作用
FPN(Top-Down) P5→P4→P3 Upsample → Concat → C2f 增强低层特征的语义表达能力(将高层强语义注入低层高分辨率特征,提升小目标识别)
PAN(Bottom-Up) N3→N4→N5 Conv-s2 → Concat → C2f 增强高层特征的空间细节与定位能力(将低层边缘轮廓信息传回高层,提升目标定位与边界回归)

注意 :严格来说 P5 也有位置信息、P3 也有语义,只是占比不同。FPN 向下传播的准确术语是 Semantic Feature (语义特征),PAN 向上传播的是 Localization Feature(空间细节特征:边缘、轮廓、纹理),均非坐标值。

Detect 输出三尺度

最终 Neck 输出三个尺度的特征图,送给 Detect Head:

输出层 分辨率 更擅长检测 本项目场景
P3/8 80×80 小目标 漏水、水滴、烟火、鼠类
P4/16 40×40 中目标 积水、猫、狗
P5/32 20×20 大目标 人员入侵

注意:表中"更擅长检测"是经验规律而非硬规则。训练时 TaskAlignedAssigner(TAL)会动态决定每个目标由哪个尺度层负责。一个中等大小目标(如 120×120)可能同时在 P3 和 P4 产生候选框,最终由 TAL 分配最优匹配。

本项目场景的尺度分布

目标 主要检测尺度
水滴 P3
小面积漏水 P3
火苗 P3
鼠类 P3
猫、狗 P3/P4
积水 P4
人员入侵 P4/P5

对于跑冒滴漏等小目标检测任务,检测效果主要取决于输入分辨率、Backbone 特征提取能力以及 Neck 的 PAN-FPN 多尺度特征融合能力。Detect Head 负责最终分类与边界框回归,但小目标特征能否在网络中被有效保留,关键在于 Backbone 与 Neck 的设计。


二、Anchor-free 解耦检测头

2.1 解耦设计(Decoupled Head)

YOLOv8 采用 Anchor-free 解耦检测头,共享输入特征、独立预测分支:

复制代码
                  ┌─ cv2(回归分支)→ 4×reg_max 个回归分布通道
特征图 ──→ Detect ┤
                  └─ cv3(分类分支)→ nc 个类别通道
  • cv2nn.ModuleList):输出 4×reg_max 个回归分布通道(reg_max=16),表示 left/top/right/bottom 四个方向的概率分布,经 DFL 解码后得到边界框坐标
  • cv3nn.ModuleList):输出 nc 个类别通道,得到各类别概率
  • 两者共享输入特征图 ,但使用独立的卷积层进行预测优化

回归分支完整流程

复制代码
cv2
 ↓
4×reg_max 回归分布(64个通道,表示 LTRB 概率分布)
 ↓
DFL 解码(Distribution Focal Loss)
 ↓
LTRB 距离值
 ↓
decode(结合网格中心点)
 ↓
xywh 边界框坐标

DFL 与 reg_max 深度解析(YOLOv8 检测头的核心创新)

理解 reg_maxDFLAnchor-free 三者的关系,是掌握 YOLOv8 检测头的关键。

1. YOLOv5 的回归方式:直接预测连续值

假设中心点 (x,y),目标框的四条边距离为:

复制代码
      Top
       ↑
       │ 7.3
       │
3.2 ← ● → 5.8
       │
       │ 4.7
       ↓
     Bottom

YOLOv5 直接预测这 4 个浮点数:

复制代码
Feature → Conv → [3.2, 7.3, 5.8, 4.7]

问题:对于真实值 7.3,网络需要直接学习这个连续值,训练比较困难。

2. YOLOv8 的创新:概率分布回归

YOLOv8 不再直接预测 7.3,而是预测7 附近的概率、8 附近的概率

例如,真实距离 Left = 7.3,网络预测:

距离桶 0 1 2 3 4 5 6 7 8 9 10~15
概率 0.00 0.00 0.00 0.01 0.03 0.08 0.25 0.45 0.15 0.03 ≈0

网络表达的是:"我觉得 7 最可能,8 也可能,6 有一点可能"。这种方式更容易学习。

3. reg_max 到底是什么?

源码中 reg_max = 16 表示距离范围 0~15 共 16 个桶(bin):

复制代码
0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15

每个桶代表一个距离区间。例如 Left = 7.3 对应 7、8 两个桶,所以 reg_max=16 表示每个方向用 16 个概率表示。

3.1 reg_max=16 怎么表示 100 像素距离?

DFL 的 16 个桶预测的是特征图上的距离(网格单位),而不是原图上的像素距离。最后通过 stride 映射回原图坐标。

Anchor-Free 预测的是什么?

YOLOv8 不再预测 (x, y, w, h),而是选一个网格中心点,预测四条边界离这个点有多远:

复制代码
      Top=50
         ↑
         │
Left=100 ● Right=100    ● = 网格中心点 (200, 300)
         │
         ↓
      Bottom=50

目标框:左上角 (100, 250),右下角 (300, 350)

Left   = 200 - 100 = 100 像素
Top    = 300 - 250 = 50 像素
Right  = 300 - 200 = 100 像素
Bottom = 350 - 300 = 50 像素

stride(步长)的作用

YOLOv8 的检测是在特征图上完成的。以 P3 层为例:

复制代码
原图:640×640×3(RGB 像素)
P3:  80×80×256(特征向量)
stride = 640 ÷ 80 = 8

特征图格子不是像素:原图每个位置存储 (R, G, B) 颜色值,而特征图每个格子存储 256 维特征向量(边缘强度、纹理、语义等抽象信息)。由于 CNN 的感受野,1 个 P3 格子对应原图 8×8 区域的信息,所以 stride=8 表示特征图 1 格对应原图 8 像素。

为什么是 256 维特征向量?

256 维不是数学上必须的,而是网络设计者故意给每个位置准备了 256 个"观察角度"。

从原图到特征图的维度变化过程:

复制代码
原图 (640×640×3)
  ↓ 第一层 Conv:64 个卷积核,每个学习一种模式
640×640×64
  ↓ 继续下采样 + 卷积
80×80×256  ← P3

每层卷积核学习不同的特征模式:

复制代码
通道 1:水平边缘
通道 2:垂直边缘
通道 3:斜线
通道 4:圆形
通道 5:纹理
...
通道 256:某种抽象语义

所以 P3 上位置 (20, 35) 的 256 维向量可能是:

复制代码
[边缘强度, 纹理强度, 圆形程度, 耳朵特征, 尾巴特征, 猫脸特征, 动物特征, ...]
共 256 个数字

为什么需要这么多维度? 一个位置可能同时包含很多信息(这里有边缘、有毛发纹理、有耳朵、有眼睛、像猫、不像狗......),一个数字无法表达,需要 256 个维度共同描述。

通道数的选择是工程权衡:太少(如 8)信息不够,太多(如 10000)显存和计算爆炸。YOLOv8 的经验值:

复制代码
P3: 80×80×256
P4: 40×40×512
P5: 20×20×1024

这和大语言模型中的 embedding 类似------词 "cat" 不会表示成单个数字 1,而是几百维向量 [0.12, -0.35, 0.88, ...],因为一个数字无法表达丰富语义。

Detect Head 的工作方式

复制代码
256 维特征向量
    ↓
分类头(cv3)→ 这是猫
    ↓
回归头(cv2)→ 框的位置

检测头就在这个 256 维向量上工作,根据丰富的特征信息判断:这里是不是目标?是什么目标?边界在哪里?

Detect Head 接收的输入已经是特征图(80×80×256),它天然只能在特征图坐标系里预测距离,最后再乘以 stride 映射回原图坐标系。这样设计比直接预测原图像素坐标更容易训练。

原图上 100 像素的距离,映射到 P3 特征图:

复制代码
100 ÷ 8 = 12.5 格

此时 DFL 不需要预测 100,它预测 12.5 就够了:

复制代码
桶 12 → 0.5
桶 13 → 0.5

DFL 解码:12 × 0.5 + 13 × 0.5 = 12.5(特征图网格单位)

映射回原图:12.5 × 8 = 100 像素

各层单侧边界距离的有效表达范围

特征层 stride DFL 最大距离(15 格) 单侧边界有效范围
P3 8 15 15 × 8 = 120 像素
P4 16 15 15 × 16 = 240 像素
P5 32 15 15 × 32 = 480 像素

注意 :这些数值表示该层上单侧边界距离(L/T/R/B 之一)的有效表达范围,而非目标框的最大覆盖范围。实际上:

  1. 目标框尺寸不受此限制:目标的 width/height 由两侧边界共同决定,且一个 GT 不会固定只在某个尺度层负责
  2. TAL 动态分配:TaskAlignedAssigner 会根据目标大小将其分配到合适的尺度层(大目标分配到更高 stride 的层)
  3. 多尺度协同:同一个目标可能在多个尺度层产生候选框,最终由 TAL 选择最优匹配

因此,P3 层并非只能检测 ≤120px 的目标,而是其单侧边界预测在该范围内表达最精确。

3.2 为什么选择 16 而不是更多?

16 个桶并不是理论上必须的。YOLOv8 选择 16,是在精度、计算量、显存占用、训练稳定性之间做的工程权衡。

桶数增加的影响

复制代码
reg_max=16 → 4×16 = 64 通道
reg_max=30 → 4×30 = 120 通道(翻倍)

但对于局部精度,16 个桶和 30 个桶结果一样------真实值 7.3 时都是 7→0.7, 8→0.3。增加桶数提升的是距离范围,不是局部精度。

GFL 论文实验结果

复制代码
reg_max = 4  → 精度不足
reg_max = 8  → 还行
reg_max = 16 → 最佳
reg_max = 32 → 收益很小
reg_max = 64 → 基本不涨

8→16 精度提升明显,16→24 提升极小,24→32 几乎没有提升,但参数量、显存、推理时间持续增加。

16 不是数学上最优,而是工程上最划算的点(sweet spot)。 就像 Transformer 的 attention head 经常取 8 或 16,不是因为别的不行,而是实验发现再大收益已经很小了。

4. 为什么是 4×reg_max = 64 通道?

框有四条边(Left/Top/Right/Bottom),每条边需要 16 个桶:

复制代码
      Top
       ↑
       │
Left ← ● → Right    ● = 网格中心点
       │
       ↓
     Bottom

Left:   [p₀, p₁, ..., p₁₅]    → 16 个概率,表示左边界距离 0~15 的可能性
Top:    [p₀, p₁, ..., p₁₅]    → 16 个概率
Right:  [p₀, p₁, ..., p₁₅]    → 16 个概率
Bottom: [p₀, p₁, ..., p₁₅]    → 16 个概率
──────────────────────────────────────────
总计: 4 × 16 = 64 个通道

检测头输出 64 channels 的来源就在这里。

5. DFL(Distribution Focal Loss)是什么?

全称 Distribution Focal Loss,核心思想:预测概率分布,而不是预测数值

GT 标签构造方式(源自 GFL 论文):

复制代码
left  = floor(y) = 7
right = ceil(y)  = 8

w_left  = right - y = 8 - 7.3 = 0.7
w_right = y - left  = 7.3 - 7 = 0.3

即 GT 标签分布为:

复制代码
7 → 0.7
8 → 0.3

解码后:7 × 0.7 + 8 × 0.3 = 7.3 ✓

注意 :GT 标签是上述精确分布,但网络预测的输出分布(Prediction)通常不会完全等于 GT 分布,例如预测可能是 7→0.6, 8→0.35, ...。DFL 训练目标是通过交叉熵让预测分布逼近 GT 分布,而非让输出严格等于 0.7/0.3。

6. DFL 解码过程:计算期望值

假设预测结果:

6 7 8 9
概率 0.10 0.60 0.25 0.05

DFL 解码计算期望值:

d = ∑ i = 0 15 p i × i d = \sum_{i=0}^{15} p_i \times i d=i=0∑15pi×i

代入:

6 × 0.10 + 7 × 0.60 + 8 × 0.25 + 9 × 0.05 = 0.6 + 4.2 + 2.0 + 0.45 = 7.25 6 \times 0.10 + 7 \times 0.60 + 8 \times 0.25 + 9 \times 0.05 = 0.6 + 4.2 + 2.0 + 0.45 = 7.25 6×0.10+7×0.60+8×0.25+9×0.05=0.6+4.2+2.0+0.45=7.25

这就是最终距离。

7. 完整推理流程示例

假设 P3 层(80×80)的某个格子 (20, 35):

复制代码
回归头输出 64 通道
    ↓
拆分为 L/T/R/B 各 16 通道
    ↓
DFL 解码得到:L=7.3, T=5.1, R=9.4, B=6.7
    ↓
结合网格中心点 (20, 35) 解码
    ↓
计算边界框坐标:
  x₁ = 20 - 7.3 = 12.7
  y₁ = 35 - 5.1 = 29.9
  x₂ = 20 + 9.4 = 29.4
  y₂ = 35 + 6.7 = 41.7
    ↓
最终 Bounding Box: (12.7, 29.9, 29.4, 41.7)

8. YOLOv5 vs YOLOv8 对比

复制代码
YOLOv5:                          YOLOv8:
Feature                          Feature
  ↓                                ↓
Conv                             Conv
  ↓                                ↓
x, y, w, h (直接回归坐标)        L: [p₀...p₁₅]  16个概率
优点:简单、速度快                 T: [p₀...p₁₅]  16个概率
缺点:定位精度有限                 R: [p₀...p₁₅]  16个概率
                                 B: [p₀...p₁₅]  16个概率
                                 共 64 通道
                                   ↓
                                 DFL Decoder(计算期望值)
                                   ↓
                                 x, y, w, h (坐标)
                                 优点:更容易训练、更稳定、
                                       定位更准、高 IoU 表现更好

9. 为什么 YOLOv8 要这样改?

概率分布回归的优势:

  • 收敛更稳定
  • 定位更准确
  • 高 IoU 场景下精度提升更明显
  • mAP@50-95 提升明显(虽然 mAP@50 提升不一定特别大)

对本项目的意义

对于漏水、水滴、烟火、鼠类这类目标,特点是目标小、边界模糊。传统回归方式框容易飘,而 DFL 让边界定位更稳定。因此 YOLOv8 在 mAP@50-95(衡量严格定位精度的指标)上提升明显,原因之一就是 Anchor-free + DFL 让边界框回归精度提高了。

2.2 Anchor-free 检测机制

YOLOv8 采用 Anchor-free(无锚框)检测方式,不再依赖预定义的 Anchor Box 宽高,而是以特征图上的网格中心点(Grid Point)作为空间参考进行目标定位。

Anchor-based(YOLOv5)

YOLOv5 使用预定义 Anchor:

yaml 复制代码
anchors:
  - [10,13, 16,30, 33,23]
  - [30,61, 62,45, 59,119]
  - [116,90, 156,198, 373,326]

训练时需要:

  1. 为每个 GT(Ground Truth)寻找最匹配的 Anchor
  2. 预测相对于 Anchor 的偏移量

即:

复制代码
预测:Δx, Δy, Δw, Δh
最终框:Anchor + Offset

因此预测结果与 Anchor 尺寸强相关。

Anchor-free(YOLOv8)

YOLOv8 不再定义 Anchor 宽高。配置文件中 Detect 层仅保留:

yaml 复制代码
Detect:
  - nc

不再存在 anchors: ...。网络直接以特征图网格中心点作为参考点:

复制代码
P3 (80×80)

□ □ □ □
□ □ ● □    ● = 网格中心点
□ □ □ □

检测头直接预测 Left/Top/Right/Bottom 四个方向到目标边界的距离,再通过 DFL 解码得到最终边界框。

make_anchors 的真实含义

源码中虽然存在 make_anchors(),但这里生成的并不是传统意义上的 Anchor Box。其作用仅仅是生成 (x_center, y_center) 形式的网格中心点坐标,例如 (0.5, 0.5), (1.5, 0.5), (2.5, 0.5), ...

YOLOv8 中的 make_anchors 本质上是在生成 Reference Points(参考点),而不是生成 Anchor Box。这一实现方式与 FCOS 系列检测器较为接近。

Anchor-free 的优势

相比 Anchor-based:

  • 不需要人工设计 Anchor 尺寸
  • 不需要 Anchor 聚类(K-Means)
  • 减少超参数
  • 对不同尺寸目标泛化更好
  • 训练流程更简单

尤其对于尺寸变化较大的场景(漏水、火苗、鼠类、人员),无需针对目标尺寸重新设计 Anchor。

2.3 解耦检测头与 TaskAlignedAssigner

YOLOv8 使用 Decoupled Head(解耦检测头)。输入特征共享,随后分类与回归分支分别进行优化:

复制代码
Feature
    │
 ┌──┴──┐
 │     │
Cls   Reg
 │     │
分类   回归
分类分支(Classification Branch)

预测"这是猫?这是狗?这是漏水?",输出 Class Score。

回归分支(Regression Branch)

预测 Left/Top/Right/Bottom 对应的 DFL 分布(4×reg_max),输出 Bounding Box。

为什么要解耦?

分类任务关注"是什么",回归任务关注"在哪里",两者优化目标不同。如果强行共享同一套预测参数,分类梯度和回归梯度可能互相干扰。因此 YOLOv8 将二者拆分,分别学习,通常能获得更稳定训练、更快收敛、更高定位精度。

TaskAlignedAssigner(TAL)

YOLOv8 精度提升并不仅仅来自解耦头。另一个关键组件是 TaskAlignedAssigner(TAL)

其核心思想是:标签分配时同时考虑分类质量和定位质量。传统匹配通常只看 IoU 或 Anchor 匹配程度,而 TAL(源自 TOOD 论文)使用分类得分和 IoU 的加权组合构建对齐指标:

复制代码
t = s^α · u^β

s = Classification Score(分类得分)
u = IoU(预测框与 GT 框的交并比)
α = 0.5(默认)
β = 6.0(默认,IoU 权重远大于分类权重)

因此"分类好定位差"或者"分类差定位好"都不一定被选为最佳匹配。由于 β >> α,TAL 实际上更重视定位质量。TAL 使分类目标和定位目标在训练过程中更加一致。

说明

YOLOv8 的性能提升来源于多项改进共同作用:

  • C2f Backbone
  • PAN-FPN Neck
  • Anchor-free 检测机制
  • Decoupled Head
  • Distribution Focal Loss(DFL)
  • CIoU Loss
  • TaskAlignedAssigner(TAL)

因此不能将精度提升简单归因于某一个模块。尤其在小目标场景中,Backbone、Neck、DFL 与 TAL 往往同样重要。


三、损失函数设计

YOLOv8 损失函数包含三个组成部分:box_loss (边界框回归)、dfl_loss (分布焦点损失)、cls_loss(分类损失)。

3.1 IoU-based Box Loss(边界框回归)

YOLOv8 默认采用 IoU-based Box Loss,当前实现中使用 CIoU(Complete IoU)。

实现说明 :源码中通过 bbox_iou(..., CIoU=True) 调用,但 Ultralytics 框架支持多种 IoU 变体(CIoU/EIoU/SIoU/WIoU),不同版本或配置可能有所调整。

CIoU(Zheng et al., CVPR 2020)同时考虑三个几何因素:

复制代码
CIoU = IoU − (ρ²/c² + v·α)
含义 公式
IoU 重叠面积 预测框 ∩ 真实框 / 预测框 ∪ 真实框
ρ²/c² 归一化中心距离 ρ = 两中心点欧氏距离,c = 最小包围框对角线
v·α 宽高比一致性 v = (4/π²)(arctan(w₂/h₂) − arctan(w₁/h₁))²,α 为动态权重

对比其他 IoU 损失

  • GIoU:仅考虑重叠 + 包围框
  • DIoU:重叠 + 中心距离(缺少宽高比)
  • CIoU:几何建模最完整

CIoU 在 YOLOv3/SSD/Faster R-CNN 等多个检测器上带来一致 AP 提升(但 Faster R-CNN 小目标 AP 略有下降)。

3.2 Distribution Focal Loss / DFL(边界框建模)

DFL (Li et al., arXiv:2006.04388)将边界框坐标从单一值 (Dirac delta)建模为离散概率分布

复制代码
DFL(Sᵢ, Sᵢ₊₁) = −[(yᵢ₊₁ − y)log(Sᵢ) + (y − yᵢ)log(Sᵢ₊₁)]
  • Ultralytics 实现采用 reg_max=16,对应每条边预测 16 个离散概率值(0~15)
  • 全局最优解使估计值无限逼近标签
  • 核心优势:DFL 允许网络表达边界位置的不确定性,而非直接回归单一点值。例如真实距离为 7.3 时,网络预测"7 的概率为 0.7,8 的概率为 0.3"比直接预测 7.3 更容易优化

背景 :GFLv2(arXiv:2011.12885, CVPR 2021)进一步验证了 General Distribution 表示的有效性,发现分布统计特征与定位质量具有显著相关性(distribution statistics are highly correlated with localization quality)。例如,集中在真实值附近的分布通常对应较高 IoU,但这是相关性而非充分必要条件------偏移但尖锐的分布可能 IoU 很差,稍宽但中心正确的分布反而 IoU 更高。GFLv2 还提出轻量 DGQP 子网络(两层 FC,隐藏层 p=64)即可从分布形状预测定位质量。

3.3 BCE(分类损失)

YOLOv8 使用标准 Binary Cross-EntropyBCEWithLogitsLoss)作为分类损失,未采用 QFL(Quality Focal Loss)。

常见误解:很多人以为"用了 DFL = 用了 GFL = 用了 QFL",实际上 YOLOv8 分类损失确实是标准 BCE,不是 QFL。

最终损失组合Loss = box_loss + cls_loss + dfl_loss

权重来自配置文件(default.yaml):

yaml 复制代码
box: 7.5
cls: 0.5
dfl: 1.5

3.4 为什么既有 CIoU 又有 DFL?

这是很多人第一次看 YOLOv8 损失函数最困惑的地方:DFL 已经在回归边界框了,为什么还要 CIoU?

两者的职责不同

  • DFL :学习边界距离的概率分布(L/T/R/B 各 16 个概率值)
  • CIoU :优化解码后最终框的几何关系(重叠面积、中心距离、宽高比)

训练时的数据流:

复制代码
DFL
 ↓ 预测 L/T/R/B 的 16 个概率
解码
 ↓ DFL 解码为 4 个距离值
Bounding Box
 ↓ 结合网格中心点计算最终框坐标
CIoU
 ↓ 比较预测框和 GT 框的几何关系

因此 DFL 和 CIoU 不是替代关系,而是协作关系:DFL 负责从分布中学习到精确的边界距离,CIoU 负责确保最终框在几何意义上尽可能与 GT 对齐。两者共同完成定位学习。


四、YOLOv8 模型规模变体(n/s/m/l/x)

YOLOv8 通过 三维缩放机制 对网络深度、宽度和最深层通道数进行灵活调整,以满足不同场景的精度与计算资源需求。

4.1 三维缩放机制

参数 控制内容 注释
depth_multiple C2f 模块内部 Bottleneck 重复次数 控制网络深度,越大网络越深,感受野更大,特征表达能力增强
width_multiple 通道数缩放 控制网络每层通道数,增加通道可提升特征表达能力,但增加计算量
max_channels 最深层通道上限 限制网络最深层最大通道数,避免过大导致显存浪费或过拟合

说明:三维缩放机制允许网络在参数量、FLOPs 和精度之间做平衡,同时为边缘设备部署提供可控空间。

4.2 模型规模参数与性能

变体 depth width max_ch 参数量 FLOPs COCO mAP@50-95 (Val2017)
n 0.33 0.25 1024 3.2M 8.7B 37.3
s 0.33 0.50 1024 11.2M 28.6B 44.9
m 0.67 0.75 768 25.9M 78.9B 50.2
l 1.00 1.00 512 43.7M 165.2B 52.9
x 1.00 1.25 512 68.2M 257.8B 53.9

备注

  • max_channels 在 m/l/x 递减(1024→768→512),用于在保持表达能力的前提下降低深层计算量和显存消耗。
  • FLOPs 与参数量基于 640×640 输入图像 测算,不同输入分辨率计算量会成比例变化。
  • mAP 为官方 Val2017 自报结果,社区复现可能略低(±0.5~1 mAP)。

4.3 精度-效率权衡

YOLOv8 各规模模型在精度与效率上的边际收益呈递减趋势:

升级 参数增加 mAP 增益 分析
n→s +3.5× +7.6 性价比高,适合资源受限场景
s→m +2.3× +5.3 仍合理,适合中高端设备
m→l +1.7× +2.7 边际收益开始下降
l→x +1.6× +1.0 增益有限,适合高算力追求极限精度场景

说明:随着模型规模增大,每增加单位参数量带来的 mAP 提升逐渐减小,选择模型需根据算力与实际应用场景权衡。

4.4 边缘设备部署建议

芯片 推荐变体 理由
RK3568 (1 TOPS) n / s 高算力模型如 m(25.9M/78.9B)可能无法达到实时帧率
RK3588 (6 TOPS) n / s / m 算力充裕,s 是精度与速度平衡点,可适当选择 m 提升精度

注意

  • TOPS 为理论峰值,实际部署 FPS 受输入分辨率、内存带宽、NPU/CPU 调度、后处理开销等因素影响。
  • 以上推荐仅供参考,实际部署需根据硬件测试实时帧率调整。

五、训练策略与数据增强

5.1 默认增强策略

增强方法 默认概率 说明
Mosaic 1.0 4 图拼接,增加小目标和上下文多样性
MixUp 0.0 两图混合叠加,默认关闭
Copy-Paste 0.0 实例级复制粘贴,默认关闭

关键细节

  • close_mosaic=10:训练最后 10 个 epoch 自动关闭 Mosaic,避免过度增强影响收敛(Mosaic 生成的图像分布与真实推理图像分布不同,训练结束前持续使用会影响最终收敛)
  • 当前 Ultralytics 实现中,Copy-Paste 主要用于实例分割(Segment)任务,在目标检测(Detect)任务中通常不会生效(这是实现限制而非算法原理限制,很多论文在 Detect 上使用 Copy-Paste)

5.2 HSV 增强(容易忽略的重要增强)

YOLOv8 默认包含 HSV 颜色空间增强:

yaml 复制代码
hsv_h: 0.015    # 色调变化
hsv_s: 0.7      # 饱和度变化
hsv_v: 0.4      # 亮度变化

HSV 增强对以下场景影响很大:

  • 室外摄像头(白天/夜晚、阴天/晴天)
  • 工厂监控(光照变化)
  • 不同季节/时间段

实际项目经验:很多工业检测项目中,HSV 增强的贡献 > MixUp 的贡献。

5.3 本项目(管道泄露 + 人员检测)的调优建议

默认配置已较合理

yaml 复制代码
mosaic: 1.0
mixup: 0.0
copy_paste: 0.0
close_mosaic: 10

若 leak 样本稀少,优先考虑以下方案(按优先级排序):

  1. 增加真实样本:数据采集是最有效的方式
  2. 类别重采样(Class Rebalancing):增加少数类采样频率
  3. 保持 Mosaic:已默认开启,对小目标有帮助
  4. 适度增强 Scale/Translate/Flip
yaml 复制代码
degrees: 5
translate: 0.1
scale: 0.5
fliplr: 0.5
  1. 保留 HSV 增强:默认已开启,对光照变化有帮助

不推荐的方案

  • MixUp:对于小目标、弱纹理、低对比度的泄漏目标,MixUp 可能使目标更模糊,反而伤害检测。MixUp 更适合分类任务和大目标检测(如 COCO、ImageNet)
  • Copy-Paste:当前 YOLOv8 Detect 任务中通常不会生效,如需使用需自行扩展实现

总结:工业缺陷检测项目通常优先使用 Mosaic + HSV + Scale/Translate/Flip,而非 MixUp。


六、边缘部署:RKNN 转换与量化

6.1 RKNN 导出支持

RKNN 已被 Ultralytics 纳入官方导出格式列表,可通过 model.export(format='rknn') 调用。底层流程以 ONNX 作为中间表示,再调用 RKNN Toolkit2 完成模型编译与量化。

支持能力

  • 支持 INT8 量化
  • 当前 Ultralytics 的 RKNN 导出能力主要面向检测模型,其他任务(分类、分割、姿态估计)的支持情况需以对应版本文档为准

环境要求

  • RKNN Toolkit2 官方推荐在 x86 Linux 环境完成模型转换与量化,板端通常仅负责推理部署
  • 需安装与目标 NPU 平台兼容的 RKNN Toolkit2 版本

6.2 本项目流水线 vs 官方 API

方面 官方 model.export(format='rknn') 本项目 export_onnx.py + build_rknn.py
控制粒度 封装度高,参数有限 精细控制量化数据集、RKNN 参数
灵活性
建议 快速验证 生产环境继续使用

6.3 ONNX 导出注意事项

  • int8 参数:ONNX Runtime INT8 量化与 RKNN INT8 量化是两套独立的校准流程。RKNN 通常使用自身校准流程完成 INT8 量化,不依赖 Ultralytics 导出的 ONNX Runtime INT8 模型
  • half 参数:FP16 ONNX 在某些 RKNN 版本和平台上可以正常转换,但为提高兼容性,通常建议导出 FP32 ONNX,再由 RKNN Toolkit 完成量化
  • dynamic 参数:RKNN 更适合固定输入尺寸模型。虽然部分版本支持动态输入,但通常不建议在生产环境启用 dynamic,因为可能导致 NPU 无法充分优化
  • 本项目应使用 simplify=True(图优化)和正确的 imgsz(必须匹配 RKNN 配置)

6.4 INT8 量化校准建议

对于 RK3568/RK3588 项目,量化精度主要取决于校准集(Calibration Dataset)质量,而非 ONNX 导出参数。

校准集要求

  • 覆盖多种场景:白天、夜晚、室内、室外、泄漏场景、非泄漏场景
  • 推荐 50~500 张代表性图片
  • 图片应与实际部署环境一致(分辨率、光照、角度)

总结:量化误差主要由校准集质量决定。校准集越能代表真实推理场景,量化后的精度损失越小。


参考来源

一手来源(Primary)

二手来源(Blog / Secondary)

相关推荐
Coovally AI模型快速验证2 个月前
RK3588上111 FPS:轻量YOLOv8+异步视频处理系统实现无人机自主电力巡检
yolo·无人机·rk3588·yolov8·塔杆定位
懷淰メ2 个月前
python3GUI---基于PyQt5+YOLOv8+DeepSort的智慧行车可视化系统(详细介绍)
开发语言·yolo·计算机视觉·pyqt·yolov8·deepsort·车距
bylander4 个月前
【AI学习】快速了解YOLO模型的发展
人工智能·学习·yolo·小模型·图像检测
蓝虫虫4 个月前
YOLOv8结合区块链:检测结果上链确保数据不可篡改
yolov8· 区块链· 数据防篡改
微尘hjx5 个月前
【数据集 01】家庭室内烟火数据集(按比例划分训练、验证、测试)包含训练好的yolo11/yolov8模型
深度学习·yolov8·yolo11·训练模型·烟火数据集·家庭火灾数据集·火灾数据集
陈嘿萌5 个月前
图像融合任务在目标检测中的性能评估与深度思考
目标检测·yolov8·图像融合·深度思考·代码实现
迪菲赫尔曼6 个月前
YAML2ModelGraph【v1.0】:一键生成 Ultralytics 模型结构图
人工智能·yolo·目标检测·yolov5·yolov8·yolo11·结构图
jinglong.zha6 个月前
【Yolov8】图形化检测视频-源码免费分享
人工智能·yolo·目标跟踪·视觉检测·yolov8·yolov11