2025年7月19日

MapTR 的层级查询设计:用类比理解维度推导


前段时间在看 MapTR 这篇论文,一开始对它的层级查询设计有点懵。后来试着用类比的方式理解,发现确实清晰了不少。这里记录一下我的理解过程,顺便把维度推导也补全了。


MapTR 整体架构

下图展示了 MapTR 的整体框架设计,可以看到它采用了典型的编码器-解码器架构,其中层级查询(Hierarchical Queries)是核心创新点:

MapTR 整体架构


核心类比:一家承接城市地图绘制的建筑公司

  • 实例级查询 (Instance-level Queries) -> 50位”首席建筑师”

    • 每位建筑师负责一个潜在的地图元素(比如一条完整的车道线)。他的任务是确定项目的整体定位和类型——“我要建的是什么,大概在哪儿”。
  • 点级查询 (Point-level Queries) -> 一支20人的”精英测量小组”

    • 这个小组是标准化的专家团队,每位成员都擅长定位项目中一个特定的点(起点、中点、转折点之类的)。他们是共享资源,提供”如何精确描绘形状”的专业技能。
  • 分层查询 (Hierarchical Queries) -> 组建50个”项目团队”

    • 在开工前,公司为每一位建筑师都配备了一支完整的测量小组。通过将建筑师和测量员的信息相加(这里用的是广播机制,一开始我以为是拼接,后来看代码才发现是加法),形成了50个项目团队,共计1000名”专业人员”(50 * 20个分层查询)。每个团队的目标都很明确:负责绘制一个特定地图元素的精确形状。
  • BEV特征图 (BEV Feature Map) -> 施工现场的”地形勘探图”

    • 由车载摄像头的图像,经过 ResNet 提取特征,再通过 BEV 转换模块投影到统一的鸟瞰图视角下,形成的一张富含信息的”地形图”。
  • Transformer解码器 -> 项目的”中央协调指挥部”

    • 这里上演着一场”记者采访会”。每个项目团队的成员(分层查询)都化身为记者,拿着自己的采访提纲 (Q)。他们同时向整个”地形图”(BEV特征)进行”采访”。地形图上的每个位置都会亮出自己的名牌 (K) 来表明身份。记者通过对比自己的提纲(Q)和所有位置的名牌(K),计算出注意力权重(“哪里与我的问题最相关”),然后根据权重,有选择性地从每个位置的详细稿件 (V) 中提取信息,聚合成一份精华摘要,用来更新自己。

    • 经过多轮”头脑风暴”和信息交换,每个团队成员都对自己的任务有了更深的理解。

  • 输出头 (Output Heads) -> “成果翻译与交付部”

    • 将指挥部里高度抽象的”会议纪要”(最终的查询向量)翻译成可用的结果。

    • 分类翻译官: 通过聚合一个项目团队所有成员的信息,判断出这位建筑师负责的项目类别(比如”车道线”)。

    • 坐标翻译官: 逐一解析团队里每一位测量员的最终报告,输出他们负责的那个点的精确(x, y)坐标。

说白了,MapTR 就是通过这种层级设计,让模型既能关注”整体是什么”,又能关注”细节在哪里”。

下图更详细地展示了MapTR的框架设计,包括层级查询的生成和解码器的工作流程:

MapTR 框架详细设计


维度推导:从输入到输出

这部分我花了点时间才搞明白,主要是矩阵维度的变化。下面以 d_model=256 为例,把完整流程梳理一遍。

输入:

  • q_instance: [50, 256] (50个实例查询,每个256维)
  • q_point: [20, 256] (20个点查询,每个256维)
  • BEV Features: [H, W, 256] -> 展平后为 [N, 256] (其中 N = H * W)

分层查询组合:

  • 通过广播机制相加,得到 q_hie: [50, 20, 256] -> 展平后为 [1000, 256]

Transformer解码器中的注意力计算:

  • q_hie ([1000, 256]) 送入 Q网络 (权重W_Q[256, 256]) -> Q: [1000, 256]
  • BEV Features ([N, 256]) 送入 K网络 (权重W_K[256, 256]) -> K: [N, 256]
  • BEV Features ([N, 256]) 送入 V网络 (权重W_V[256, 256]) -> V: [N, 256]
  • 计算注意力权重: Q ([1000, 256]) 与 K的转置 ([256, N]) 相乘 -> Attention Scores: [1000, N]
  • 聚合信息: Attention Scores ([1000, N]) 与 V ([N, 256]) 相乘 -> Updated Queries: [1000, 256]

输出头:

  • 输入: 最终的q_hie_final: [1000, 256] -> 重塑为 [50, 20, 256]
  • 分类头:
    • 聚合操作 (对20个点取平均): [50, 20, 256] -> q_agg: [50, 256]
    • 送入分类FFN (权重W_cls[256, num_classes]) -> Class Probs: [50, num_classes]
  • 回归头:
    • q_hie_final ([50, 20, 256]) 直接送入回归FFN (权重W_reg[256, 2]) -> Coordinates: [50, 20, 2]

我试着改过几次维度配置,发现这套设计还挺稳定的。关键是实例查询和点查询的数量要根据任务调整,太多会拖慢速度,太少又容易漏检。


关于 ResNet 和特征图大小

有人问过我:“ResNet理论上特征图越大,它能看得越清楚,特征图越小看得就越不清楚,在这篇论文中用了多大的特征图?”

对,你说得没错。特征图的分辨率直接影响模型对细节的感知能力。下图展示了MapTR不同版本(tiny、nano)的性能对比:

MapTR 性能对比

论文附录A的 Model Setting 部分给出了答案:

  • 原始输入图像大小: 1600 x 900
  • MapTR-tiny的图像缩放比例: 0.5 -> 输入图像变为 800 x 450
  • MapTR-nano的图像缩放比例: 0.2 -> 输入图像变为 320 x 180

更关键的是 BEV网格大小

  • MapTR-tiny: 0.3m (鸟瞰图中的每个”像素”代表真实世界中 0.3米 x 0.3米 的区域)
  • MapTR-nano: 0.75m (分辨率低了很多,每个像素代表的区域更大,细节自然会更模糊)

虽然论文没有直接给出BEV特征图的像素维度(比如200x100),但我们可以根据感知范围和网格大小推断出来。nuScenes数据集的感知范围通常是前后-50m50m(Y轴),左右-50m50m(X轴)。如果以一个简化的60m x 30m范围为例:

  • MapTR-tiny的BEV特征图大小: 大约是 (60/0.3) x (30/0.3) = 200 x 100 像素
  • MapTR-nano的BEV特征图大小: 大约是 (60/0.75) x (30/0.75) = 80 x 40 像素

所以 nano 版本是牺牲了 BEV 特征图的分辨率来换取速度。我自己跑过一次对比,tiny 的精度确实高一些,但 nano 在实时性要求高的场景也够用了。


写在最后

MapTR 的层级查询设计其实挺巧妙的,它把”找到元素”和”定位形状”这两个任务解耦了。不过我觉得这套设计还有优化空间,比如点查询的数量是固定的20个,对于形状复杂的元素(比如弯曲的车道线)可能还不够精细。

下面是MapTR在nuScenes数据集上的可视化结果,可以看到它在复杂驾驶场景中的表现:

MapTR 可视化结果

MapTRv2在Argoverse2数据集上也展现出了稳定的地图构建质量:

MapTRv2 在Argoverse2上的可视化结果

从这些可视化结果可以看出,MapTR能够在各种复杂场景下稳定地检测和重建车道线、人行横道等地图元素。

后续我打算试试动态调整点查询数量,或者看看能不能用可变形注意力来减少计算量。