NUE-NeRF-nav 实验复现流程说明文档
NUE-NeRF-nav 实验复现流程说明文档
论文: “Enhancing Exploratory Capability of Visual Navigation Using Uncertainty of Implicit Scene Representation” (IROS 2024)
复现日期: 2026年3月
有问题可以关于咸鱼用户:代码跑通pytorch。一个金鱼图像
目录
1. 项目概述
NUE (Navigation with Uncertainty-driven Exploration) 是一种基于 NeRF 隐式场景表示的视觉导航方法。
核心思想:
- 使用 NeRF 作为在线认知结构,实时构建场景的隐式表示
- 通过 NeRF 的不确定性估计来增强探索能力
- 从 NeRF 中提取记忆信息来辅助目标定位推理
- 将探索(exploration)和利用(exploitation)无缝结合,生成导航动作
任务类型:Image-Goal Navigation(给定目标图像,导航到对应位置)
2. 环境配置
2.1 实际运行环境
| 组件 | 版本 |
|---|---|
| Python | 3.8.10 |
| CUDA | 11.3 |
| PyTorch | 1.10.0+cu113 |
| iGibson | 2.2.2 |
| NumPy | 1.22.x |
| TensorBoard | 2.14.0 |
| 操作系统 | Linux (AutoDL 云服务器) |
| GPU | 双卡(cuda:0 + cuda:1) |
2.2 安装步骤
# 1. 创建 conda 环境
conda create -n nue python=3.8
conda activate nue
# 2. 安装 PyTorch (CUDA 11.3)
pip install torch==1.10.0+cu113 torchvision==0.11.0+cu113 \
-f https://download.pytorch.org/whl/cu113/torch_stable.html
# 3. 安装 iGibson
# 参考: https://github.com/StanfordVL/iGibson
pip install igibson
# 4. 安装其他依赖
pip install numpy==1.22.2 tensorboard==2.14.0 pyyaml opencv-python matplotlib tqdm
2.3 iGibson 数据集配置
iGibson 的场景数据需按如下结构放置:
iGibson/igibson/data/
├── assets/ # iGibson 基础资源
├── ig_dataset/ # iGibson 场景数据
├── g_dataset/ # Gibson 场景数据 (本项目使用)
│ ├── Adrian/
│ ├── Avonia/
│ ├── Kerrtown/
│ └── ...
└── igibson.key # 许可证密钥
注意: 下载 Gibson 数据集需要通过 Stanford 官方申请,获取 igibson.key 后才能下载。
3. 数据集准备
3.1 Waypoints 数据集(用于生成专家数据)
下载 waypoints 数据集后放置在项目根目录:
NUE-NeRF-nav/navigation_scenarios/waypoints/
├── tiny/ # 最小规模
├── medium/ # 中等规模
├── full/ # 完整规模
└── full+/ # 增强规模
3.2 生成训练数据(专家数据集)
# 通过模仿学习的方式采集专家轨迹
python sample.py
生成的训练数据结构:
NUE-NeRF-nav/dataset/
├── Kerrtown/ # 训练场景1
│ ├── 0000/
│ │ ├── observation.npy # 观测数据
│ │ ├── action.npy # 专家动作标签
│ │ └── info.txt # episode 信息
│ ├── 0001/
│ └── ...
├── Oyens/ # 训练场景2
├── Ribera/ # 训练场景3(注意:也出现在测试集中)
├── Rosenberg/ # 训练场景4
├── Roxboro/ # 训练场景5
└── Superior/ # 训练场景6
3.3 测试数据集
测试用的 episode 配置文件:
NUE-NeRF-nav/test_dataset/
├── Avonia.json # 测试场景配置(含起点、目标等信息)
├── Lathrup.json
├── Mosinee.json
├── Rabbit.json
├── Sawpit.json
├── Ribera.json
└── ...(共 14 个场景可用)
实际测试使用了 6 个场景:Avonia, Lathrup, Mosinee, Rabbit, Sawpit, Ribera
4. 模型训练
4.1 关键配置参数
在 main_imitate_navig.py 中的主要参数:
# 训练模式
training = 1 # 1 = 训练模式
# 训练超参数
episodeLimit = 24000 # 最大训练 episode 数
batchSize = 4 # 批次大小(实际采样用 256)
initialLearningRate = 5e-4 # 初始学习率(模型训练实际用 1e-3)
save_model_every_n_step = 10000 # 每隔多少步保存模型(实际每1000步保存一次)
# 设备配置
device_0 = "cuda:0" # 主模型所在 GPU
device_1 = "cuda:1" # NeRF 训练所在 GPU
# 模型加载(接续训练时使用)
model_load = './model/9000.pkl' # 预训练模型路径
4.2 仿真环境配置
turtlebot_nav.yaml 关键配置:
# 机器人
robot: Turtlebot # 使用 Turtlebot 机器人
action_type: continuous # 连续动作空间
# 图像传感器
image_width: 240 # 图像宽度
image_height: 180 # 图像高度
vertical_fov: 75 # 垂直视场角
# 深度传感器
depth_low: 0.8 # 最小深度范围
depth_high: 10.0 # 最大深度范围
# 终止条件(设置极大值,由代码控制)
max_step: 99999999
dist_tol: 0.36 # 成功判定距离(机器人体宽)
4.3 相机内参
cameras.txt 中记录了相机内参矩阵参数:
fx=117.56 fy=117.56 cx=120.43 cy=89.90 H=180 W=240
4.4 训练架构
训练采用多进程架构:
- 主进程: 运行 iGibson 仿真环境,收集轨迹数据
- Process-1: 模型训练进程(模仿学习 + 策略优化)
- Process-2: NeRF 在线训练进程(实时更新场景表示)
进程间通过 multiprocessing.Queue、Manager().list() 和 Pipe 通信。
4.5 运行训练
# 前台运行
python main_imitate_navig.py
# 后台运行(推荐,因为训练时间很长)
nohup python main_imitate_navig.py > nohup_main_imitate.log 2>&1 &
4.6 训练输出
NUE-NeRF-nav/
├── model/2026-03-11/ # 模型 checkpoint
│ ├── 6000.pkl
│ ├── 7000.pkl
│ ├── ...
│ └── 57000.pkl # 共 53 个 checkpoint,每 1000 步保存
├── summary/2026-03-11/ # TensorBoard 日志
│ └── events.out.tfevents.*
└── nohup_main_imitate.log # 训练过程日志
查看训练曲线:
tensorboard --logdir summary/2026-03-11/ --port 6006
5. 模型测试
5.1 测试配置
在 test.py 中的关键参数:
max_step_num = 500 # 每个 episode 最大步数
device_0 = "cuda:0" # 主模型 GPU
device_1 = "cuda:1" # NeRF GPU
# 使用的模型 checkpoint
model_index = '57000'
model_load = 'model/2026-03-11/57000.pkl'
# 测试场景(共 6 个)
test_scenes = [
'Avonia.json',
'Lathrup.json',
'Mosinee.json',
'Rabbit.json',
'Sawpit.json',
'Ribera.json'
]
5.2 测试架构
测试同样采用多进程:
- 主进程: 运行仿真环境,逐 episode 执行导航
- Process-2: NeRF 在线训练进程(
nerf_train_for_test),每个 episode 重置
每个 episode 的流程:
- 加载起点和目标图像
- 初始化 NeRF
- 每步:观测 -> Cognition Extraction (~3ms) -> Policy Generation (~2ms) -> 执行动作
- NeRF 在后台持续用观测数据训练(~73ms/步)
- 达到目标(距离 < 0.8m)或超过 500 步后结束
5.3 运行测试
# 前台运行
python test.py
# 后台运行(推荐,测试约需 4 小时)
nohup python test.py > test_output.log 2>&1 &
# 查看实时进度
tail -f test_output.log
5.4 测试输出
NUE-NeRF-nav/
├── test_result/57000/ # 测试结果目录
│ ├── Avonia.json # 各场景的逐 episode 结果
│ ├── Lathrup.json
│ ├── Mosinee.json
│ ├── Rabbit.json
│ ├── Ribera.json
│ ├── Sawpit.json
│ └── events.out.tfevents.* # TensorBoard 日志
└── test_output.log # 测试过程日志
每个 JSON 结果文件的单条记录格式:
{
"if success": true,
"path dist": 9.80,
"closed_dist": 0.93,
"optimal dist": 5.16,
"dist": 5.16,
"label": ["straight", "hard"],
"border": 0.8,
"endDist": 0.93
}
字段说明:
if success: 是否导航成功path dist: 实际行走路径长度(米)closed_dist: 过程中最近距离目标的距离optimal dist: 最优路径长度(米)dist: 目标距离label: [路径类型(straight/curved), 难度级别(easy/medium/hard)]border: 成功判定阈值(米)endDist: 终止时距目标的距离
6. 结果分析
6.1 查看结果命令
# 使用项目自带脚本查看完整指标
python compute_metrics.py 57000
6.2 评估指标说明
| 指标 | 全称 | 含义 | 方向 |
|---|---|---|---|
| SR | Success Rate | 成功率 = 成功数 / 总数 x 100% | 越高越好 |
| SPL | Success weighted by Path Length | 路径效率 = (1/N) x sum(S_i x l_i / max(p_i, l_i)) | 越高越好 |
| DTS | Distance To Success/goal | 终止时距目标的平均距离 | 越低越好 |
其中:
- S_i = 1 如果成功,0 如果失败
- l_i = 最优路径长度 (optimal dist)
- p_i = 实际行走路径长度 (path dist)
6.3 按难度分类的结果
难度由目标距离和路径复杂度决定(标签在 test_dataset 的 JSON 中预定义):
| 难度 | 数量 | SR (复现) | SR (论文) | SPL (复现) | SPL (论文) | DTS (复现) | DTS (论文) |
|---|---|---|---|---|---|---|---|
| Easy | 159 | 61.64% | 66.00% | 0.407 | 0.458 | 2.030 | 1.289 |
| Medium | 187 | 52.94% | 59.50% | 0.373 | 0.388 | 2.658 | 1.511 |
| Hard | 131 | 52.67% | 54.75% | 0.406 | 0.388 | 3.039 | 2.684 |
| Total | 477 | 55.77% | 59.65% | 0.393 | 0.385 | 2.553 | 2.053 |
6.4 按场景的结果
| 场景 | 数量 | SR | SPL | DTS |
|---|---|---|---|---|
| Avonia | 76 | 55.26% | 0.306 | 2.191 |
| Lathrup | 77 | 55.84% | 0.415 | 2.513 |
| Mosinee | 79 | 60.76% | 0.397 | 2.182 |
| Rabbit | 73 | 65.75% | 0.497 | 2.199 |
| Ribera | 89 | 39.33% | 0.279 | 3.057 |
| Sawpit | 83 | 60.24% | 0.480 | 3.049 |
- 最好:Rabbit(SR=65.75%, SPL=0.497)
- 最差:Ribera(SR=39.33%, SPL=0.279)
6.5 复现差距分析
- SR 整体低约 3.9 个百分点,Easy 和 Medium 差距较大
- SPL Total 和 Hard 实际上略优于论文值
- DTS 整体偏高约 0.5m
可能的差距原因:
- 随机种子不同
- 训练 episode 数可能不同(本次训练约 57000 步)
- iGibson 版本差异(论文使用 2.0.6,复现使用 2.2.2)
- 场景渲染的微小差异
6.6 推理速度
| 模块 | 平均耗时 |
|---|---|
| Cognition Extraction | ~3.0 ms |
| Policy Generation | ~1.9 ms |
| 单步总时间 | ~60 ms |
| NeRF 训练(每步) | ~73 ms |
7. 项目文件结构
NUE-NeRF-nav/
│
├── main_imitate_navig.py # 【训练入口】模仿学习训练主脚本
├── test.py # 【测试入口】模型测试主脚本
├── compute_metrics.py # 【结果分析】计算 SR/SPL/DTS 指标
├── sample.py # 【数据采集】从 waypoints 生成专家数据
│
├── model.py # 模型定义(E2E_model, NeRF, 训练/测试进程)
├── model_qkv.py # QKV 注意力变体模型
├── trainer.py # 训练器、仿真交互逻辑
├── dataset.py # 数据集加载器
├── util.py # 工具函数(渲染热力图等)
│
├── turtlebot_nav.yaml # iGibson 仿真环境配置
├── cameras.txt # 相机内参
├── scenes_for_training.txt # 训练场景列表(6个场景)
│
├── dataset/ # 训练数据(专家轨迹)
│ ├── Kerrtown/
│ ├── Oyens/
│ ├── Ribera/
│ ├── Rosenberg/
│ ├── Roxboro/
│ └── Superior/
│
├── test_dataset/ # 测试 episode 配置
│ ├── Avonia.json ~ Ribera.json (共14个场景可用)
│
├── navigation_scenarios/ # waypoints 原始数据
│ └── waypoints/
│ ├── tiny/ medium/ full/ full+/
│
├── model/ # 训练保存的模型 checkpoint
│ └── 2026-03-11/
│ ├── 6000.pkl ~ 57000.pkl (共53个)
│
├── summary/ # TensorBoard 训练日志
│ └── 2026-03-11/
│
├── test_result/ # 测试结果
│ ├── 4000/ # 早期测试(仅 Avonia, SR=23.1%)
│ └── 57000/ # 最终测试(6场景, SR=55.8%)
│
├── test_output.log # 测试过程日志
├── nohup_main_imitate.log # 训练过程日志
├── model.py.bak # model.py 修复前的备份
│
└── doc/ # 文档和图片
├── network.png # 网络结构图
└── result.png # 论文结果表
8. 常用命令速查
# ===== 训练 =====
# 启动训练(后台)
nohup python main_imitate_navig.py > nohup_main_imitate.log 2>&1 &
# 查看训练进度
tail -f nohup_main_imitate.log
# 查看训练曲线
tensorboard --logdir summary/2026-03-11/ --port 6006
# ===== 测试 =====
# 启动测试(后台,约需 4 小时)
nohup python test.py > test_output.log 2>&1 &
# 查看测试进度
tail -f test_output.log
# ===== 结果分析 =====
# 查看 checkpoint 57000 的完整指标
python compute_metrics.py 57000
# 查看 checkpoint 4000 的指标
python compute_metrics.py 4000
# ===== 环境 =====
# 激活环境
conda activate base
# 查看 GPU 使用情况
nvidia-smi
9. 已知问题与修复
9.1 BrokenPipeError(已修复)
问题: 测试完成后,nerf_train_for_test 子进程访问已销毁的 Manager 共享列表时抛出 BrokenPipeError。
位置: model.py 第 785 行
修复: 将 reset_list[-1] 的直接访问包裹在 try/except 中:
# 修复前:
if reset_list[-1]:
# 修复后:
try:
should_reset = reset_list[-1]
except (BrokenPipeError, EOFError, ConnectionResetError, OSError):
break
if should_reset:
影响: 此错误仅在测试全部完成后的清理阶段发生,不影响测试结果的正确性。
备份: 修复前的文件已备份为 model.py.bak
9.2 Gym 废弃警告
运行时会出现 Gym 过期警告,这是因为 iGibson 2.x 依赖旧版 Gym。该警告不影响功能,可以忽略。
最后更新: 2026-03-12
更多推荐


所有评论(0)