AI-深度学习

嵌入式视觉模型进阶 08:FPN 与 PAN:怎样融合不同尺度的信息

展开合集目录
  1. 嵌入式视觉模型进阶 01:怎样读懂一个实际模型
  2. 嵌入式视觉模型进阶 02:卷积进阶:分组、深度、逐点与空洞卷积
  3. 嵌入式视觉模型进阶 03:MobileNet:深度可分离卷积与倒残差
  4. 嵌入式视觉模型进阶 04:通道注意力与 MobileNetV3
  5. 嵌入式视觉模型进阶 05:ShuffleNet:通道拆分与重排
  6. 嵌入式视觉模型进阶 06:结构重参数化:训练分支怎样合为一个卷积
  7. 嵌入式视觉模型进阶 07:Backbone、Neck、Head 与多尺度特征
  8. 嵌入式视觉模型进阶 08:FPN 与 PAN:怎样融合不同尺度的信息
  9. 嵌入式视觉模型进阶 09:检测头:分类、位置与置信度
  10. 嵌入式视觉模型进阶 10:检测训练:标签分配与损失计算
  11. 嵌入式视觉模型进阶 11:完整 YOLOv8 推理:从图片到原图目标框
  12. 嵌入式视觉模型进阶 12:训练自己的检测器与错误分析
  13. 嵌入式视觉模型进阶 13:检测器导出对照与其他结构路线
  14. 嵌入式视觉模型进阶 14:跟踪基础:运动预测、匹配与轨迹生命周期
  15. 嵌入式视觉模型进阶 15:ByteTrack 思路:用低分框恢复已有轨迹
  16. 嵌入式视觉模型进阶 16:外观特征与 ReID:怎样比较两个目标
  17. 嵌入式视觉模型进阶 17:目标跟随:从轨迹到云台控制接口
  18. 嵌入式视觉模型进阶 18:视频系统:队列、时间戳与异步流水线
  19. 嵌入式视觉模型进阶 19:人脸处理流程:检测、关键点与对齐
  20. 嵌入式视觉模型进阶 20:特征识别:人脸向量、相似度与阈值
  21. 嵌入式视觉模型进阶 21:人体关键点与姿态估计
  22. 嵌入式视觉模型进阶 22:OCR 检测:从文字区域到矫正图片
  23. 嵌入式视觉模型进阶 23:OCR 识别:序列模型与 CTC
  24. 嵌入式视觉模型进阶 24:完整 OCR 流程与识别错误分析
  25. 嵌入式视觉模型进阶 25:轻量语义分割与实例分割
  26. 嵌入式视觉模型进阶 26:工业异常检测:缺陷样本少时怎么办
  27. 嵌入式视觉模型进阶 27:深度估计与图像恢复:两个专题入口
  28. 嵌入式视觉模型进阶 28:面向 NPU 的计算图与算子兼容
  29. 嵌入式视觉模型进阶 29:量化、蒸馏与剪枝的实际取舍
  30. 嵌入式视觉模型进阶 30:综合项目:检测、跟踪与云台跟随验收
嵌入式视觉模型进阶 08:FPN 与 PAN:怎样融合不同尺度的信息的封面

第 8 / 30 课。 前置:上一课。本篇的运行范围以实验说明和验证记录为准,构造样例不代表真实任务精度或板端性能。

为什么不能直接把特征相加

C3、C4、C5 通道与分辨率不同。先用 1×1 横向投影把它们转为相同通道数,再把低分辨率特征插值到高分辨率层的实际大小,才能逐元素相加。相加要求所有维度兼容;拼接只要求除拼接轴以外的维度一致,并会增加通道数。

FPN 的典型思路是把深层信息逐级向高分辨率传播。PAN 类路径再把融合后的高分辨率信息向下聚合。具体模型会选择相加、拼接和不同卷积块,本课是最小路径演示,不是任意 YOLO neck 的逐层复刻。

追踪本课路径

输入通道为 32、64、128,统一成 24。先得到 P5,再计算 P4=L4+up(P5)、P3=L3+up(P4)。向下用 stride=2 的卷积,将 P3 加到 P4,再将结果加到 P5。

本课使用 17、9、5 的奇数尺寸,检验“按目标 size 插值”的必要性。若只是写 scale_factor=2,会出现 5→10 与 9 不匹配。

运行后应该看什么

输出层的空间大小不变、通道变为 24;反向梯度能到达每个输入层。使用随机特征只能验证结构,不能据此判断小目标效果。

修改任务与工程检查

把相加替换成 concat,先计算后续卷积的输入通道,再运行。将输出通道从 24 改为 48,记录权重和激活增长。交付 neck 的输入输出表,并说明为什么降低 backbone 成本后,neck 仍可能占据主要运行时间。

配套实验与运行记录

实验:FPN 与 PAN:怎样融合不同尺度的信息

查看完整代码:main.py
"""搭建自顶向下与自底向上的融合路径,检查相加、拼接和空间对齐。"""

import torch
from torch import nn
import torch.nn.functional as F


class Pyramid(nn.Module):
    def __init__(self):
        super().__init__()
        self.lateral = nn.ModuleList([nn.Conv2d(c, 24, 1) for c in [32, 64, 128]])
        self.down = nn.ModuleList([nn.Conv2d(24, 24, 3, 2, 1) for _ in range(2)])

    def forward(self, features):
        p = [layer(x) for layer, x in zip(self.lateral, features)]
        for i in [1, 0]:
            p[i] = p[i] + F.interpolate(p[i + 1], size=p[i].shape[-2:], mode="nearest")
        out = [p[0]]
        for i in [0, 1]:
            down = self.down[i](out[-1])
            assert down.shape == p[i + 1].shape
            out.append(p[i + 1] + down)
        return out


def main():
    torch.manual_seed(7)
    torch.set_num_threads(2)
    xs = [
        torch.randn(1, c, s, s, requires_grad=True)
        for c, s in [(32, 17), (64, 9), (128, 5)]
    ]
    ys = Pyramid()(xs)
    sum(y.square().mean() for y in ys).backward()
    assert all(x.grad is not None and torch.isfinite(x.grad).all() for x in xs)
    print("outputs", [list(y.shape) for y in ys])


if __name__ == "__main__":
    main()
下载代码

在项目根目录执行;下载包解压后,在解压目录执行 python3 main.py。

cd 'content/posts/AI-深度学习/嵌入式视觉模型进阶/08-FPN 与 PAN/code' && python3 main.py

在本篇代码目录执行 python3 main.py。依赖安装、可选入口见包内 README.md;实际运行结果见 verification.md。下载包包含本课使用的辅助模块与样例。

参考与进一步阅读

原始论文或官方文档用于核对结构、接口和适用范围。本篇代码是围绕教学目标编写的最小实验;除明确注明的完整入口外,不视为对应论文模型的完整复现。


完整进阶目录 · 入门系列 · 上一篇 · 下一篇