AI-深度学习

嵌入式视觉模型进阶 13:检测器导出对照与其他结构路线

展开合集目录
  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:综合项目:检测、跟踪与云台跟随验收
嵌入式视觉模型进阶 13:检测器导出对照与其他结构路线的封面

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

对照点必须位于同一阶段

框最终看起来一致,并不保证原始分数正确;框不一致,也可能只是两个端采用了不同阈值。首先固定输入张量,比较导出前后的原始输出;再固定解码与阈值,比较框集合;最后比较整批真实验证数据的任务指标。

本课用小型随机初始化检测头导出类别与框两个输出,分别对照 PyTorch 和 CPU ONNX Runtime。它是导出接口实验,不是 YOLO 真实精度报告。第 11 课的真实 ONNX 入口仍需使用对应 YOLOv8 契约。

输出名字和语义一起保存

类别输出为 [1,2,8,8],框输出为 [1,4,8,8],本例框是未解码的四通道数值。导出保留固定输入、明确名字、opset 与版本。只验证 shape 不够,还要比较 max absolute error 和容差内一致性。

SSD 与 DETR 为什么不能共用解码

SSD 类模型常围绕预设 default boxes 回归偏移,需要对应先验框。DETR 类模型使用查询输出一组预测,训练时涉及集合匹配;其输出通常不是密集网格框偏移。具体背景类、归一化坐标与后处理仍依版本确认。

这些路线的存在说明模型适配器应封装完整输出语义,而不是把所有输出统一当成 [cx,cy,w,h,obj,classes...]。课程不以结构名预判板端支持。

练习与失败定位

将模型的 eval 移除后加入 Dropout,观察为什么两次输出不再适合直接对照。再把输入随机种子改三次,避免只对一张全零图通过。

如果 CPU Runtime 一致而 NPU 不一致,继续比较 NPU 输入字节、量化尺度、算子转换和输出反量化。导出成功只跨过格式转换这一关,尚未跨过板端兼容与任务验收。

配套实验与运行记录

实验:检测器导出对照与其他结构路线

查看完整代码:main.py
"""导出多输出检测头并逐张量对照,认识 SSD、DETR 与后处理边界。"""

from pathlib import Path
from tempfile import TemporaryDirectory
import numpy as np
import torch
from torch import nn
import onnx, onnxruntime as ort


class Head(nn.Module):
    def __init__(self):
        super().__init__()
        self.feature = nn.Conv2d(3, 8, 3, 4, 1)
        self.cls = nn.Conv2d(8, 2, 1)
        self.box = nn.Conv2d(8, 4, 1)

    def forward(self, x):
        x = torch.relu(self.feature(x))
        return self.cls(x), self.box(x)


def main():
    torch.manual_seed(7)
    torch.set_num_threads(2)
    net = Head().eval()
    with TemporaryDirectory() as d:
        path = Path(d) / "head.onnx"
        x = torch.rand(1, 3, 32, 32)
        torch.onnx.export(
            net,
            (x,),
            str(path),
            input_names=["images"],
            output_names=["classes", "boxes"],
            opset_version=17,
            dynamo=False,
        )
        onnx.checker.check_model(onnx.load(path))
        session = ort.InferenceSession(str(path), providers=["CPUExecutionProvider"])
        for seed in [7, 8, 9]:
            torch.manual_seed(seed)
            x = torch.rand(1, 3, 32, 32)
            with torch.inference_mode():
                expected = net(x)
            actual = session.run(None, {"images": x.numpy()})
            for name, a, b in zip(["classes", "boxes"], actual, expected):
                np.testing.assert_allclose(a, b.numpy(), rtol=1e-4, atol=1e-5)
                print(
                    seed, name, a.shape, "max error", float(np.abs(a - b.numpy()).max())
                )


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

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

cd 'content/posts/AI-深度学习/嵌入式视觉模型进阶/13-检测器导出对照与其他结构路线/code' && python3 main.py

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

参考与进一步阅读

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


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