Memory over maps论文讲解系列一:不构建地图,机器人如何记住并找到物体?
前言(碎碎念,可跳过)
很久没有更新博客了,原因有几点:一是之前的博客更多只是学习过程的记录,而随着学习深入,我发现自己缺乏深刻的感悟与思考,内容逐渐显得浅显且重复;二是今年的重心集中在保研上,精力有限,难以投入太多时间去学习那些对保研无直接帮助的内容。同时,我也在重新思考:究竟什么样的博客才真正符合我的需求?我的初衷并非为了教别人,而是记录自己的学习历程,分享思考过程。若能在这一过程中顺便帮助到他人,自然也是一件令人欣喜的事。
最近,我逐渐开始接触研究生阶段的学习,阅读论文、复现代码,过程远谈不上轻松。常常缺乏动力深入探究,陷入一种“感觉还有很多细节没弄明白,却提不起劲继续钻研”的困境。尤其在AI的辅助下,几乎所有问题都能迅速得到解答,但这种即时反馈反而让我更难真正理解背后的原理与逻辑。这成了一种看似高效实则浅薄的学习方式,令人感到疲惫而焦虑。
因此,我决定重新开始写博客。记录本身是一种自我驱动,它督促我向前走,也提醒我不能只停留在表面。我不愿让内容流于肤浅,更不想用AI代笔来敷衍愿意阅读这篇博客的人。我希望这里的每一篇文字,都是我真实思考的沉淀,是我在探索中留下的足迹。
当然,我会继续借助AI作为工具,因为它确实强大且实用。但更重要的是,在这个过程中,我也在不断反思:如何恰当地使用AI,
才能让它成为思维的延伸,而非替代思考的捷径。(此处AI润色,我的碎碎念没这么有文化,真的是即怕自己写得太过于随意,又怕AI润色的过于正式)
我目前的研究重点聚焦于具身智能相关方向。第一阶段的目标是系统性地理解一篇论文的整体框架,从宏观视角把握其核心脉络。以下将围绕七个关键部分展开介绍:
- 论文简介:简要说明论文的发表会议/期刊、发表时间、下载链接及开源代码地址等基本信息。
- 研究背景与核心问题:在当前大环境背景下,简要梳理已有解决方案的实现路径与技术特点;在此基础上,明确论文所关注的关键问题及其试图解决的具体挑战。
- 创新点:阐述作者为应对该问题所提出的独特思路或方法,突出其新颖性与关键突破(并随机补充一些个人小思考)。
- 完整流程:详细阐述论文所提出的整体研究流程。
- 源码结构:梳理项目目录结构,说明各主要文件夹与模块的功能分工,帮助读者快速定位核心代码。
- 实验数据:受硬件配置限制,我仅在部分数据上进行了测试与实验复现,无法保证完全复现每篇论文所展示的结果,这一局限性确实存在。目前我的设备尚不足以支持所有论文的完整复现,同时部分论文也未提供完整的实验流程脚本。因此,我主要选择那些思想具有启发性的研究进行学习与尝试——只要逻辑合理、不脱离实际,便值得深入探索。
- 运行与测试:详细介绍如何运行模型并测试数据,重点讲解参数含义及其设置依据(不涉及环境配置细节,建议结合 AI 工具根据本地情况灵活调整)。后续,我也将分多期展开介绍论文中每个部分的细节问题。
论文简介
论文全名为《Memory Over Maps: 3D Object Localization Without Reconstruction》,于2026年3月20日发表于IEEE/RSJ国际智能机器人与系统会议(IROS 2026),属于CCF-C类会议。论文PDF与GitHub代码仓库链接如下,可直接点击访问:
研究背景与核心问题
背景任务:基于视觉记忆的三维目标定位
这篇论文研究的是基于视觉记忆的三维目标定位(Visual-Memory-based 3D Object Localization)问题。
所谓基于视觉记忆的三维目标定位,是指机器人利用此前采集并保存的环境视觉信息,在接收到目标查询后,从历史观测中检索目标物体,并估计其在三维空间中的位置。
例如,当用户下达「在房间中找一副眼镜」的指令时,机器人首先需要分析此前扫描环境时采集的 RGB 图像、深度图像及对应的相机位姿等信息,检索可能包含眼镜的历史图像,并进一步判断目标是否存在于这些候选视角中。如果找到目标,则结合目标分割结果、深度信息以及相机位姿,将目标从二维图像中的像素区域转换为三维空间中的位置,并通过多视角信息融合获得更加可靠的定位结果。
最终,系统输出目标物体的三维位置估计,为后续的机器人导航、物体操作等具身任务提供空间目标信息。
传统解决方法:基于三维语义地图的目标定位
说明:本文所说的传统方法,主要指 Memory Over Maps 提出之前,研究中一类较为常见的基于显式三维场景表示的目标定位方法,并不代表所有已有方法都采用相同的技术流程。
这类方法通常会选择先构建环境的三维语义地图(3D Semantic Map),再利用该地图进行目标物体的检索与定位。
具体来说,首先利用机器人采集的 RGB-D 图像及对应的相机位姿信息,将二维图像中的像素结合深度信息反投影到三维空间,得到场景的三维几何表示,例如点云(Point Cloud)、体素网格(Voxel Grid)等。随后,通过视觉语言模型、目标检测模型或语义分割模型提取图像中的语义信息,并将这些信息与对应的三维空间位置进行关联和融合,从而构建同时包含几何信息与语义信息的三维语义地图。
在完成地图构建后,当系统接收到目标查询时,就可以根据文本或视觉语义特征,在三维语义地图中检索对应的目标物体,并获得其在场景中的三维位置,为后续的机器人导航和操作提供空间信息。
然而,这种方法也存在一定的局限性。首先,构建三维语义地图需要对采集到的多视角数据进行几何重建、语义特征提取以及跨视角信息融合,前期通常需要投入一定的计算时间和资源。其次,随着环境规模扩大以及地图精度和细节程度的提高,三维地图所需的存储空间也会相应增加,地图的构建与维护成本可能进一步上升。
核心问题
因此,一个值得思考的问题是:是否一定需要提前构建完整的三维语义地图,才能实现目标物体的三维定位?
如果机器人已经保存了带有相机位姿信息的历史 RGB-D 图像,能否直接从这些视觉记忆中检索目标物体,并在需要时恢复目标的三维位置,而不必提前重建整个环境?
创新点
Memory Over Maps 提出了一种基于视觉记忆的无全局地图目标定位方法。其核心思想是不再提前构建完整的三维场景表示,而是将预先采集的 RGB-D 关键帧及其对应的相机位姿保存为视觉记忆。
当系统接收到目标查询时,首先利用 SigLIP2 提取图像和文本特征,并通过** FAISS** 进行向量检索,从历史视觉记忆中找到 Top-K 候选图像。随后,使用视觉语言模型(VLM)对候选图像进行重新排序,过滤不包含目标物体的图像,并保留更有可能包含目标的视角。
在确定候选视角后,系统利用 SAM 3 对目标物体进行分割,结合对应的深度信息和相机位姿,通过深度反投影(Depth Backprojection)将目标从二维图像转换为三维点云,再通过多视角融合(Multi-view Fusion)获得目标物体的稀疏三维表示及位置估计。
通过这种方式,系统只需要恢复与当前查询目标相关的三维信息,而不需要预先构建整个环境的三维语义地图,从而减少前期场景索引的计算开销和存储需求。
小思考
下游导航任务:不构建完整地图,机器人如何导航?
完成目标物体的三维定位后,还需要考虑如何利用定位结果实现机器人的自主导航。
这里有一个值得思考的问题:Memory Over Maps 不提前构建完整的三维环境地图,那么机器人在缺少全局地图的情况下,如何前往目标位置?
一种思路是在定位目标后构建局部地图,再利用传统路径规划算法进行导航。而论文选择了另一种方案:使用基于 DD-PPO 训练的预训练 PointNav Policy。
实际上,无显式地图导航(Mapless Navigation)已经是一条较为成熟的研究路线。它不依赖预先构建的完整环境地图,而是根据机器人当前的深度观测和目标相对位置,直接预测下一步移动动作。
我觉得这个设计很有意思:既然论文希望摆脱完整三维地图的构建,那么在下游导航环节复用一个不依赖显式地图的导航策略,就成为了一个很自然的选择。 这样既保持了整体方案的一致性,也让论文能够将研究重点集中在视觉记忆检索和三维目标定位上。
完整流程

此处直接引用论文中的流程图,整体流程已在前述创新点与导航部分梳理完毕,不再重复赘述。
源码结构
├── checkpoints
│ └── navigation # DD-PPO PointNav 导航策略的模型权重
├── configs # YAML 配置文件(针对不同基准测试的评估配置及 Demo 配置)
├── data # 数据集存放
├── demo # 交互式 3D 可视化工具(viser)
├── docs # 使用文档
├── models # 模型权重(我自己下载的)
│ ├── Qwen2.5-VL-3B-Instruct
│ └── sam3_fingsinz
├── scripts # 环境安装与数据准备脚本
├── src
│ ├── cli # 评估入口(每个基准测试对应一个入口)
│ ├── dataloaders # 数据加载
│ ├── evaluation # 评估指标累加器与评估辅助工具
│ ├── models
│ │ ├── navigation# DD-PPO PointNav 导航策略及多目标导航智能体
│ │ ├── retrieval # 可插拔的特征提取器(默认使用 SigLIP2;支持 CLIP、ALIGN、FLAVA、Qwen3-VL-Embedding)
│ │ ├── segmentation# 基于文本提示的 SAM3 目标分割
│ │ └── vlm # 视觉语言模型(Qwen2.5-VL)
│ ├── pipelines # 论文方法的各个流程步骤(检索 → 定位 → 导航)
│ └── utils # 投影、几何计算、数据加载、关键帧提取、空间融合等工具
└── third_party # 第三方库(我自己下载的,用作者提供的环境安装脚本也会直接下载)
├── habitat-lab
└── sam3
权重问题
项目中使用的模型权重主要来自 Hugging Face 和魔搭社区(ModelScope)。
其中,SigLIP2 的默认权重下载地址为 Hugging Face。首次运行时,程序会将模型权重下载并缓存到本地,后续运行通常可以直接从本地缓存加载。不过,在我的实际运行过程中,仍然需要通过网络连接 Hugging Face 获取相关资源。
Qwen2.5-VL 和 SAM 3 的模型权重默认也是Hugging Face,但我是从魔搭社区下载的,这样可以减少国内网络环境下获取模型权重的困难。
需要注意的是,论文原本使用的是 Qwen2.5-VL-7B-Instruct,而我下载的是 Qwen2.5-VL-3B-Instruct。主要原因是本地 GPU 显存不足以支持 7B 模型的运行,因此选择了参数量更小的 3B 版本。
但在实际复现过程中,即使不启用 VLM 模块,运行其他模型和仿真环境时,GPU 显存也已经接近或达到使用上限。因此,后续实验中我选择关闭了 VLM 重排序阶段,没有实际使用 Qwen2.5-VL 模型。
这也意味着,我目前的实验 Pipeline 与论文完整方法存在一定差异:在检索候选图像之后,跳过了 VLM Re-ranking 阶段,直接进入后续的目标分割与三维定位流程。
Sam3模型权重
Sam3模型权重是需要填写申请表的,但是我当时官方申请被拒绝了,是在魔塔社区找到的一个权重分享,我也不知道跟官方是否是完全一致。
为了更方便调用本地sam3模型,我也对官方代码进行了小小的修改,使得本地sam3模型地址可以通过参数配置文件yaml进行配置,在本地权重寻找失败之后再去找官方权重,这里也给出我修改的地方的介绍,虽然现在完全可以让agent直接操作进行修改。
sam3_segmenter.py(位于src/models/segmentation/)
1.首先是在初始化的时候添加权重地址的参数。
修改前
def __init__(self, device: str = "cuda", confidence_threshold: float = 0.0,
batch_size: int = 5):
修改后
def __init__(self, device: str = "cuda", confidence_threshold: float = 0.0,
batch_size: int = 5, checkpoint_path: str = None):
2.修改模型加载代码中的参数
修改前,默认从Hugging Face加载
self.model = build_sam3_image_model(
device=device,
load_from_HF=True
)
修改后,先进行判断本地权重是否存在,不存在再从Hugging Face加载
checkpoint = checkpoint_path
# 本地文件不存在时,回退到 SAM3 默认加载方式
if checkpoint and not os.path.isfile(checkpoint):
logger.warning(
"SAM3 本地权重不存在: %s,尝试默认 Hugging Face 加载",
checkpoint,
)
checkpoint = None
logger.info(
"SAM3 权重来源: %s",
checkpoint if checkpoint else "Hugging Face",
)
self.model = build_sam3_image_model(
device=device,
checkpoint_path=checkpoint,
load_from_HF=(checkpoint is None),
)
setup.py(位于src/evaluation/)
这里是调用SAM3Segmenter类的地方,添加权重地址调用参数文件对应参数
修改前
def load_sam3(args):
"""Load SAM3 segmenter."""
from src.models.segmentation import SAM3Segmenter
return SAM3Segmenter(
device=args.device, confidence_threshold=args.sam3_confidence,
batch_size=getattr(args, "sam3_batch_size", 5),
)
修改后
def load_sam3(args):
"""Load SAM3 segmenter."""
from src.models.segmentation import SAM3Segmenter
return SAM3Segmenter(
device=args.device, confidence_threshold=args.sam3_confidence,
batch_size=getattr(args, "sam3_batch_size", 5),
checkpoint_path=getattr(args, "sam3_checkpoint_path", None),
)
demo.py(位于demo/)
这部分是可视化展示的时候调用的SAM3Segmenter类,同理添加权重地址调用参数文件对应参数
修改前
sam3_segmenter = SAM3Segmenter(
device="cuda",
confidence_threshold=cfg_get(cfg, "sam3", "confidence"),
batch_size=cfg_get(cfg, "sam3", "batch_size"),
)
修改后
sam3_segmenter = SAM3Segmenter(
device="cuda",
confidence_threshold=cfg_get(cfg, "sam3", "confidence"),
batch_size=cfg_get(cfg, "sam3", "batch_size"),
checkpoint_path=cfg_get(cfg, "sam3", "checkpoint_path"),
)
config.py(位于src/utils/)
这个是参数配置的文件,Ctrl+F搜索sam3
args.sam3_confidence = cfg_get(cfg, "sam3", "confidence")
args.sam3_batch_size = cfg_get(cfg, "sam3", "batch_size")
在这两行下面添加
args.sam3_checkpoint_path = cfg_get(cfg, "sam3", "checkpoint_path")
base.yaml(位于configs/)
最后就是修改配置文件,base.yaml是所有配置文件的基础,在这里可以添加权重路径的占位。
修改前
sam3:
confidence: 0.0
batch_size: 3
修改后
sam3:
confidence: 0.0
batch_size: 3
checkpoint_path: null
然后就可以在最终使用的配置文件hm3d.yaml或者demo.yaml(取决于你要用的配置文件)中添加
sam3:
checkpoint_path: [你的权重地址]
实验数据
本次实验主要使用 HM3D 数据集中的 TEEsavR23oF 场景,因此本节主要介绍 HM3D 数据集及其相关数据准备过程。
HM3D(Habitat-Matterport 3D Research Dataset)包含约 1,000 个真实室内空间的三维数字孪生场景,涵盖住宅、商业及公共空间等不同类型的环境,完整数据集大小约为 30.7 GB。
本次实验下载的是 hm3d-minival-habitat-v0.2.tar,压缩包大小约为 390 MB。该文件属于 HM3D 官方提供的小规模验证集,本次实验选取其中的 TEEsavR23oF 场景,该场景对应 15 个导航任务。
注意:后续所有终端命令均在项目根目录 memory-over-maps 下执行。
相机姿态数据
首先,需要准备相机姿态(Camera Poses)数据。官方仓库的 data 文件夹中提供了 hm3d_poses.tar.gz 压缩包,其中存放了 HM3D 场景对应的相机姿态信息。
在终端中执行以下命令,创建 HM3D 数据集所需的目录结构,并解压相机姿态数据:
mkdir -p data/hm3d/scenes data/hm3d/meshes data/hm3d/episodes
# 如果位姿压缩包存在,就解压
if [ -f data/hm3d_poses.tar.gz ]; then
tar xzf data/hm3d_poses.tar.gz -C data/hm3d/scenes/
echo "HM3D poses extracted"
else
echo "Missing: data/hm3d_poses.tar.gz"
fi
ObjectNav v2 导航任务数据
接下来,需要准备 ObjectNav v2 的导航任务数据。该数据集包含机器人需要执行的导航任务及相关场景信息。
在终端中执行以下命令,下载 ObjectNav v2 任务数据压缩包,并将其解压到项目目录中:
wget -c \
https://dl.fbaipublicfiles.com/habitat/data/datasets/objectnav/hm3d/v2/objectnav_hm3d_v2.zip \
-O data/objectnav_hm3d_v2.zip
unzip -q data/objectnav_hm3d_v2.zip -d .
下载并解压完成后,还需要使用官方提供的数据整理脚本 scripts/prepare_data.py,将导航任务数据整理到项目所需的目录结构中。
python scripts/prepare_data.py --dataset hm3d
三维场景模型数据
最后,需要准备 HM3D 的三维场景模型数据。这部分数据包含场景的几何模型和导航网格,是 Habitat 仿真环境加载和运行室内场景的基础。
相关官方资源如下:
- hm3d数据集官方github仓库
- hm3d数据集minival下载地址,点击这个链接之后登陆matterport账号就可以直接下载minival数据集。
- hm3d数据集val下载地址
下载完成后,在 data 文件夹下创建 hm3d_downloads 文件夹,并将下载的压缩包放入该目录中。
随后,在项目根目录的终端中执行以下命令,将压缩包解压到 data/hm3d/meshes 目录下:
tar -xf data/hm3d_downloads/hm3d-minival-habitat-v0.2.tar \
-C data/hm3d/meshes
渲染TEEsavR23oF场景
完成上述数据准备后,还需要生成机器人在场景中的 RGB 图像和 Depth 深度图像。
官方提供了 scripts/render_rgbd.py 脚本,可以根据场景三维模型和相机姿态信息,对指定场景进行渲染,生成对应的 RGB 图像和 Depth 深度图像。
本次实验只使用 TEEsavR23oF 场景,因此执行以下命令:
python scripts/render_rgbd.py \
--scenes-dir data/hm3d/scenes \
--mesh-root data/hm3d/meshes \
--scenes TEEsavR23oF \
--width 256 \
--height 256 \
--workers 1
其中,–width 和 --height 分别指定渲染图像的宽度和高度,–workers 用于设置并行处理的工作进程数量。
脚本运行完成后,会生成对应场景的 RGB 图像和 Depth 深度图像。

介绍数据文件
完成前面三个部分的数据准备后,HM3D 数据目录下会包含以下三个主要文件夹:
- episodes:存放导航任务数据,主要记录机器人需要执行的任务及相关信息,例如需要寻找的目标物体。对于本次使用的 TEEsavR23oF 场景,共包含 15 个导航任务。
- meshes:存放 HM3D 场景的三维模型数据,供 Habitat 仿真环境加载和使用。
- scenes:存放场景对应的相机姿态(Camera Poses)等数据,为后续 RGB-D 图像渲染和三维定位提供空间信息。

至此,HM3D Minival 数据集的基础准备工作就完成了。我们已经获得了场景三维模型、相机姿态、导航任务以及渲染所需的 RGB-D 图像,可以开始后续的论文方法复现与代码分析。
运行与测试
eval_hm3d.py(位于src/cli/)
完成数据集准备后,就可以开始运行论文的评估程序了。
不过,在运行之前需要注意:官方代码默认提供的 HM3D 数据划分只有 Train 和 Val,并没有直接提供 Minival 选项。 由于本次实验使用的是 HM3D Minival 子集,因此需要对数据划分配置进行少量修改。如果使用官方提供的 Train 或 Val 数据集,则可以跳过这部分。
添加minival选项
首先,需要修改 src/cli/arg_groups.py,在 HM3D 的数据划分选项中增加 val_mini。
arg_groups.py(位于src/cli/)
修改前
"hm3d": dict(
group="HM3D data",
config="configs/hm3d.yaml",
data_root_help="Path to hm3d root (with scenes/, meshes/, and episodes/)",
scene_example="TEEsavR23oF",
splits=["val","train"],
),
修改后
"hm3d": dict(
group="HM3D data",
config="configs/hm3d.yaml",
data_root_help="Path to hm3d root (with scenes/, meshes/, and episodes/)",
scene_example="TEEsavR23oF",
splits=["val","val_mini","train"],
),
这样,程序就可以识别 val_mini 这一数据划分。
配置文件
从上面的代码可以看到,HM3D 默认使用的配置文件是 configs/hm3d.yaml。该配置文件还会继承 base_nav.yaml,而 base_nav.yaml 又依赖 base.yaml,因此最终的运行参数由多层配置共同决定。
由于本地 GPU 显存有限,无法直接使用官方默认配置运行完整流程,因此我选择在原有配置的基础上,新建一个低显存配置文件 hm3d_lowmem.yaml。
该配置文件继承 hm3d.yaml,并针对本地实验环境调整数据划分、SAM 3 权重路径以及 VLM 模型配置。
在项目根目录下执行以下命令,创建配置文件:
cat > configs/hm3d_lowmem.yaml <<'EOF'
_base: hm3d.yaml
data:
root: data/hm3d
split: val_mini
sam3:
batch_size: 1
checkpoint_path: [sam3权重本地路径]
vlm:
model: /home/snow/projects/graduation/research/memory-over-maps/models/Qwen2.5-VL-3B-Instruct
batch_size: 1
EOF
echo "=== 低显存配置 ==="
cat configs/hm3d_lowmem.yaml
其中,主要修改了以下几个参数:
- data.root:指定 HM3D 数据集的根目录。
- data.split:将数据划分设置为 val_mini。
- sam3.batch_size:将 SAM 3 的批处理大小调整为 1,以降低显存占用。
- sam3.checkpoint_path:指定本地 SAM 3 模型权重路径,避免从 Hugging Face 下载。
- vlm.model:指定本地 Qwen2.5-VL-3B-Instruct 模型路径。
- vlm.batch_size:将 VLM 批处理大小设置为 1。
需要注意的是,本次实验运行时使用了 --no-vlm 参数,因此虽然配置文件中保留了 VLM 的模型路径和批处理参数,但实际评估过程中不会执行 VLM 重排序阶段。
运行测试
完成上述修改后,就可以运行 HM3D 评估程序了。
本次实验选取 TEEsavR23oF 场景中的 15 个导航任务进行测试,并通过 --no-vlm 关闭 VLM 重排序阶段,以适应本地 GPU 显存条件。
在项目根目录下执行:
python -m src.cli.eval_hm3d \
--config configs/hm3d_lowmem.yaml \
--scene TEEsavR23oF \
--no-vlm \
--device cuda \
--output results/hm3d_TEE_minival.json
参数说明:
- –config:指定本次实验使用的低显存配置文件。
- –scene:指定需要评估的 HM3D 场景。
- –no-vlm:关闭 VLM 重排序阶段。
- –device cuda:使用 GPU 运行模型。
- –output:指定实验结果的保存路径。
程序运行完成后,评估结果将保存到 results/hm3d_TEE_minival.json,便于后续分析和复现实验。
demo.py(位于demo/)
除了通过命令行运行评估程序,官方还提供了交互式 Demo,用于可视化场景、目标检索和三维定位结果。
具体使用方法可以参考官方文档 docs/demo.md。
在项目根目录下执行:
python demo/demo.py --dataset hm3d --scene TEEsavR23oF
程序启动后,在浏览器中打开:http://localhost:8080/
即可进入交互式可视化界面,查看 HM3D 场景及相关的目标定位结果。
效果如下:

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)