MapTR 的层级查询设计:用类比理解维度推导
前段时间在看 MapTR 这篇论文,一开始对它的层级查询设计有点懵。后来试着用类比的方式理解,发现确实清晰了不少。这里记录一下我的理解过程,顺便把维度推导也补全了。
MapTR 整体架构
下图展示了 MapTR 的整体框架设计,可以看到它采用了典型的编码器-解码器架构,其中层级查询(Hierarchical Queries)是核心创新点:

核心类比:一家承接城市地图绘制的建筑公司
-
实例级查询 (Instance-level Queries) -> 50位”首席建筑师”
- 每位建筑师负责一个潜在的地图元素(比如一条完整的车道线)。他的任务是确定项目的整体定位和类型——“我要建的是什么,大概在哪儿”。
-
点级查询 (Point-level Queries) -> 一支20人的”精英测量小组”
- 这个小组是标准化的专家团队,每位成员都擅长定位项目中一个特定的点(起点、中点、转折点之类的)。他们是共享资源,提供”如何精确描绘形状”的专业技能。
-
分层查询 (Hierarchical Queries) -> 组建50个”项目团队”
- 在开工前,公司为每一位建筑师都配备了一支完整的测量小组。通过将建筑师和测量员的信息相加(这里用的是广播机制,一开始我以为是拼接,后来看代码才发现是加法),形成了50个项目团队,共计1000名”专业人员”(
50 * 20个分层查询)。每个团队的目标都很明确:负责绘制一个特定地图元素的精确形状。
- 在开工前,公司为每一位建筑师都配备了一支完整的测量小组。通过将建筑师和测量员的信息相加(这里用的是广播机制,一开始我以为是拼接,后来看代码才发现是加法),形成了50个项目团队,共计1000名”专业人员”(
-
BEV特征图 (BEV Feature Map) -> 施工现场的”地形勘探图”
- 由车载摄像头的图像,经过 ResNet 提取特征,再通过 BEV 转换模块投影到统一的鸟瞰图视角下,形成的一张富含信息的”地形图”。
-
Transformer解码器 -> 项目的”中央协调指挥部”
-
这里上演着一场”记者采访会”。每个项目团队的成员(分层查询)都化身为记者,拿着自己的采访提纲 (Q)。他们同时向整个”地形图”(BEV特征)进行”采访”。地形图上的每个位置都会亮出自己的名牌 (K) 来表明身份。记者通过对比自己的提纲(Q)和所有位置的名牌(K),计算出注意力权重(“哪里与我的问题最相关”),然后根据权重,有选择性地从每个位置的详细稿件 (V) 中提取信息,聚合成一份精华摘要,用来更新自己。
-
经过多轮”头脑风暴”和信息交换,每个团队成员都对自己的任务有了更深的理解。
-
-
输出头 (Output Heads) -> “成果翻译与交付部”
-
将指挥部里高度抽象的”会议纪要”(最终的查询向量)翻译成可用的结果。
-
分类翻译官: 通过聚合一个项目团队所有成员的信息,判断出这位建筑师负责的项目类别(比如”车道线”)。
-
坐标翻译官: 逐一解析团队里每一位测量员的最终报告,输出他们负责的那个点的精确(x, y)坐标。
-
说白了,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]
- 聚合操作 (对20个点取平均):
- 回归头:
- 将
q_hie_final([50, 20, 256]) 直接送入回归FFN (权重W_reg为[256, 2]) ->Coordinates:[50, 20, 2]
- 将
我试着改过几次维度配置,发现这套设计还挺稳定的。关键是实例查询和点查询的数量要根据任务调整,太多会拖慢速度,太少又容易漏检。
关于 ResNet 和特征图大小
有人问过我:“ResNet理论上特征图越大,它能看得越清楚,特征图越小看得就越不清楚,在这篇论文中用了多大的特征图?”
对,你说得没错。特征图的分辨率直接影响模型对细节的感知能力。下图展示了MapTR不同版本(tiny、nano)的性能对比:

论文附录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数据集的感知范围通常是前后-50m到50m(Y轴),左右-50m到50m(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数据集上的可视化结果,可以看到它在复杂驾驶场景中的表现:

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

从这些可视化结果可以看出,MapTR能够在各种复杂场景下稳定地检测和重建车道线、人行横道等地图元素。
后续我打算试试动态调整点查询数量,或者看看能不能用可变形注意力来减少计算量。