复现MSG:Multiview Scene Graph (NeurIPS 2024)
复现项目需要的步骤
指南涵盖了环境搭建、数据集准备、模型推理和训练的流程:
1. 克隆项目代码
首先从官方仓库克隆代码:
git clone https://github.com/ai4ce/MSG.git
cd MSG
2. 配置运行环境
项目提供了两种方式来设置运行环境,推荐使用 environment.yml
方法,以确保完整的环境依赖。
方法 1:使用 requirements.txt
如果想搭建最小依赖环境:
conda create --name msg python=3.11.8
conda activate msg
pip install -r requirements.txt
方法 2:使用 environment.yml
如果想完全复现官方环境:
conda env create -f environment.yml
conda activate msg
提示:第二种方法可以避免遗漏依赖项,推荐使用。
如果遇到需要激活
conda init
source ~/.bashrc
conda activate msg
3. 数据集准备
官方数据集基于 Apple 的 ARKitScenes 转换而来,需要从 Huggingface 下载:
下载和解压数据
- 下载数据:
- 数据链接在 Huggingface Dataset Hub 中。
- 下载以下压缩包:
Training_aa.zip
至Training_aj.zip
Validation.zip
Test.zip
mini-val.zip
用wget下载
- 存储路径:
下载完成后,文件会存储到./data/msg
目录,形成如下结构:./data/msg/ ├── Test.zip ├── Training_aa.zip ├── Training_ab.zip ├── ... ├── Validation.zip ├── mini-val.zip
后台运行(可选)
如果文件较大,下载可能需要较长时间。为了避免 SSH 会话中断影响下载任务,可以用以下方式让脚本在后台运行:
使用 nohup
后台运行:
nohup python download_msg.py > download.log 2>&1 &
> download.log
: 将下载进度记录到download.log
文件。&
: 将任务放到后台。
查看日志:
tail -f download.log
验证文件完整性
下载完成后,建议检查文件大小与 Huggingface 页面显示是否一致。可以运行以下命令:
ls -lh ./data/msg/
检测数据是否完整
解压后的目录应如下:
./data/msg/
├── Training/
├── Validation/
├── Test/
├── mini-val/
data_process的py文件解释
convert_2d.py
将 3D 注释转换为 2D 注释,并通过 多进程加速 处理。它的核心目标是读取 3D 数据(如点云、深度图像、相机参数等),将其投影到 2D 平面上,并生成相应的 2D 边界框或关键点注释,用于图像处理任务,例如目标检测或跟踪。处理类似 ARKit 数据集 的 3D 数据,并需要将其转换为 2D 注释(例如生成自动驾驶、AR/VR 数据集)。
应用场景
- AR/VR 和 机器人感知:将 3D 数据投影到 2D 平面是很多计算机视觉任务的前置步骤,例如 SLAM、目标跟踪和导航。
- 数据集处理:适用于需要从 3D 数据中生成 2D 注释的数据集,例如自动驾驶数据集的转换。
- 深度学习模型训练:生成的 2D 注释可以用于目标检测模型(如 YOLO、Faster R-CNN)的训练和评估。
脚本具体解释
- 数据加载与预处理
读取 ARKit 数据集中的 3D 注释、轨迹文件(traj)、深度图像和相机内参。
Convert2DDataLoader 类负责逐帧加载数据,包括:
深度图像 (depth): 用于生成点云。
轨迹文件 (traj): 提供每帧的相机位姿。
内参文件 (pincam): 用于将 3D 坐标投影到 2D 图像平面。 - 3D 点云投影到 2D
generate_point 函数:
使用相机内参将深度图像生成的 3D 点云投影到 2D 图像平面。
如果指定世界坐标系,还会应用相机位姿转换。
投影后的点云包括 3D 坐标和对应的 2D 像素坐标。 - 边界框处理
get_2d_box 和 post_process_coords 函数:
通过 3D 边界框的角点坐标,将其投影到 2D 平面。
检查投影结果是否在图像画布内,并进行后处理(例如获取凸包或交集)。 - 注释生成
每帧图像都会生成对应的 2D 注释,包括:
2D 边界框 (bbox): xmin, ymin, xmax, ymax。
标签 (label): 表示物体类别。
唯一标识 (uid): 用于区分物体。 - 多进程处理
使用 multiprocessing.Pool 将视频分割成多个部分,每个子进程处理一部分视频,提升处理速度。 - 注释保存
最终将生成的 2D 注释保存为 JSON 文件,文件名类似 2d_annotations_<video_id>.json。
脚本优点
- 效率优化
使用多进程 (multiprocessing.Pool) 来并行化处理多个视频,节省时间。
对点云和边界框进行了过滤(如仅保留至少 20 个点的边界框)。 - 精度控制
在轨迹时间戳和帧 ID 匹配时,允许微小误差(±0.001 秒),以最大限度匹配数据。 - 灵活性
支持动态分辨率调整(如裁剪图像以匹配深度图像尺寸)。
gt_generation.py
生成拓扑结构的 Ground Truth 数据 (Ground Truth for Topological Adjacency),主要是为了描述场景中不同位置和物体的关系,包括位置之间的相邻关系(P-P Adjacency)和位置与物体之间的相邻关系(P-O Adjacency)。
目的
- 场景拓扑结构分析;通过 P-P 邻接矩阵,可以分析不同帧之间的空间关系,帮助构建场景的拓扑结构。
- 物体与场景关系建模:P-O 邻接矩阵描述了物体在场景中的分布,便于后续任务(如场景重建、导航规划)使用。
- 自动驾驶与机器人应用:在自动驾驶或机器人应用中,这些拓扑数据有助于理解场景布局和物体分布,支持路径规划和决策。
脚本解释
- 从轨迹数据中提取相机位姿
函数 get_poses:
解析轨迹文件 (lowres_wide.traj) 中的每帧位姿数据,返回所有帧的 4x4 位姿矩阵。
如果当前帧的内参文件 (pincam) 不存在,会尝试向前或向后微调时间戳以匹配。 - 计算帧间的旋转和位移差异
函数 rot_distance 和 trans_distance:
分别计算帧与帧之间的旋转角度差(通过旋转矩阵的几何距离)和位移差(通过欧几里得距离)。
函数 pairwise_diff:
通过批处理方式计算所有帧之间的旋转差异矩阵和位移差异矩阵。 - 生成位置与位置之间的相邻关系
函数 place_adj:
根据旋转差异阈值和位移差异阈值,生成帧之间的相邻关系矩阵(P-P Adjacency)。
函数 make_data:
对每个视频生成 P-P 邻接矩阵,并记录哪些帧没有邻居(孤立帧)。 - 生成位置与物体之间的相邻关系
函数 get_gt_po 和 regen_po_adj:
根据 2D 注释文件(2d_annotations_.json),生成位置与物体之间的邻接矩阵(P-O Adjacency)。
P-O Adjacency 描述了在特定帧中,物体是否出现在对应位置。 - 记录 Ground Truth
包括:
元数据 (meta):旋转差异和位移差异的最大值,采样帧率,孤立帧数量等。
邻接矩阵 (p-p 和 p-o):分别描述位置与位置、位置与物体的关系。
注释 (annotations):记录每帧的物体信息,包括边界框和类别。 - 对数据集的所有视频进行处理
主函数中,通过 regen_po_adj 遍历不同数据集分组(如 Validation、Training),处理每个视频的 Ground Truth 数据,并跳过指定的无效视频。
关键点
- 旋转与平移阈值的选择
rot_thres 和 trans_thres 是决定相邻关系的重要参数:
旋转阈值(单位:弧度)控制帧间的角度相似性。
平移阈值(单位:米)控制帧间的空间接近性。
合理选择这些阈值,可以过滤掉过于遥远或角度偏差过大的帧。 - 优化性能
使用批量计算(torch 的广播机制)加速帧间差异的计算。
对数据进行采样(frame_every 参数)以减少计算量。 - 容错处理
处理丢失帧的情况(如缺少内参或注释)时,尝试通过微调时间戳或跳过无效帧来保证脚本的健壮性。
preprocess_utils.py
定义了一些 拓扑结构处理(topo process) 所需的实用工具函数,用于解析相机轨迹(pose)和内参(intrinsics),并生成 4x4 的相机变换矩阵或 3x3 的相机内参矩阵。
可以帮助将数据从轨迹文件或内参文件中提取并格式化,为后续的 SLAM、场景重建或导航任务提供基础数据支持。
- 旋转向量转换为旋转矩阵
函数 convert_angle_axis_to_matrix3:
输入:旋转向量(角轴表示,angle_axis)。
输出:对应的旋转矩阵(3x3)。
原理:
使用 OpenCV 的 cv2.Rodrigues 函数,将角轴表示的旋转向量(Angle-Axis)转换为旋转矩阵。
角轴表示是一种紧凑的旋转表示法,其中旋转向量的方向表示旋转轴,长度表示旋转角度。 - 轨迹字符串转换为变换矩阵
函数 TrajStringToMatrix:
输入:轨迹字符串(traj_str),每行包含以下 7 列信息:
时间戳(timestamp)
旋转(角轴表示,3 个值)
平移(3 个值)
输出:
时间戳(ts)。
相机的 4x4 位姿矩阵(Rt)。
原理:
提取角轴表示的旋转向量,使用 convert_angle_axis_to_matrix3 转换为旋转矩阵。
提取平移向量,组合旋转矩阵和平移向量,生成 4x4 的外参矩阵。
通过矩阵求逆(np.linalg.inv)将其转换到相机坐标系。 - 读取相机内参
函数 st2_camera_intrinsics:
输入:包含相机内参的文件路径(filename)。
文件内容格式:
w, h, fx, fy, hw, hh
w, h: 图像宽高。
fx, fy: 焦距(以像素为单位)。
hw, hh: 主点坐标(通常为图像中心点)。
输出:3x3 的相机内参矩阵:
[[fx, 0, hw],
[ 0, fy, hh],
[ 0, 0, 1]]
下载检查点
curl -o ./exp-results/aomsg/aomsg-s-4.pth https://huggingface.co/datasets/ai4ce/MSG/resolve/main/chkpt/aomsg-s-4.pth
ls ./exp-results/aomsg/
ls -lh ./exp-results/aomsg/aomsg-s-4.pth
sha256sum ./exp-results/aomsg/aomsg-s-4.pth
下载结果文件
wget https://huggingface.co/datasets/ai4ce/MSG/resolve/main/msg-gdino-results.zip -O ./msg-gdino-results.zip
mkdir -p ./exp-results/gdino-direct
unzip ./msg-gdino-results.zip -d ./exp-results/gdino-direct
mv ./exp-results/gdino-direct/msg-gdino-results/* ./exp-results/gdino-direct/
打开 inference.py 或配置文件(例如 configs/experiments/inference.yaml)
detection_path: ./exp-results/gdino-direct/msg-gdino-results
inference.yaml
主要配置参数
数据相关
dataset_path: './data/msg'
指定数据集路径为 ./data/msg。确认该目录下包含如 Test, Training, Validation, real 的子目录。
eval_split: real
指定当前推理的子数据集为 real。确保 ./data/msg/real 中有数据。
eval_output_dir: './exp-results/aomsg'
指定推理结果的输出目录。
eval_chkpt: aomsg-s-4.pth
使用 aomsg-s-4.pth 作为模型权重文件,确认该文件存在于 ./exp-results/aomsg/。
save_every: True
每个视频的推理结果单独保存。
vis_det: True
生成推理结果的可视化文件。
python inference.py --experiment inference
ls ./msg-gdino-results
eval_split: Test
# eval_split: Test # 或 Training, Validation, mini-val
./exp-results/aomsg
4. 预训练模型准备
-
下载预训练模型:
- 预训练的 AoMSG 模型可从 Huggingface 数据库下载。
- 将模型下载到
./exp-results/aomsg
目录下:mkdir -p ./exp-results/aomsg # 将预训练模型文件移动到此目录
-
检查路径:
确保模型的路径如下:./exp-results/aomsg/ └── [预训练模型文件,如 29-step22470+.pth]
5. 推理(Inference)
使用预训练模型进行推理:
python inference.py --experiment inference
配置文件说明
默认配置文件为 ./configs/experiments/inference.yaml
,以下参数可以覆盖 YAML 文件中的配置:
- 数据集路径:
--dataset_path
- 模型权重路径:
--eval_output_dir
- 使用的 checkpoint 文件:
--eval_chkpt
示例:
python inference.py --experiment inference \
--dataset_path ./data/msg \
--eval_output_dir ./exp-results/aomsg \
--eval_chkpt 29-step22470+.pth
6. 训练
训练 AoMSG 模型
运行以下命令:
python train.py --experiment aomsg
- 配置文件:
./configs/experiments/aomsg.yaml
训练 SepMSG 基线模型
运行以下命令:
python train.py --experiment sepmsg
- 配置文件:
./configs/experiments/sepmsg.yaml
从 checkpoint 恢复训练
在 YAML 文件中设置以下参数:
resume: true
resume_path: ./exp-results/aomsg/[checkpoint_file.pth]
7. 评估
评估训练好的模型性能:
- 评估 AoMSG:
python eval.py --experiment aomsg
- 评估 SepMSG:
python eval.py --experiment sepmsg
- 评估直接使用冻结特征的模型:
python eval.py --experiment direct
8. 注意事项
-
目标检测依赖:
- 当前版本未包含对象检测的代码。您需要单独运行目标检测,并将检测结果存储到指定路径。
- GroundingDINO 结果文件已在数据集中提供,可直接使用。
- 在
./configs/experiments/aomsg_gdino.yaml
中,指定目标检测结果路径。
-
在线检测:
- 当前版本不支持在线检测,后续版本可能会支持。
9. 数据处理(可选)
如果想要自定义数据转换,可参考 data_preprocess
中的代码来复现从 3D 注释到 2D 数据的转换过程。
10. 结果可视化
推理结果和可视化会保存在指定的 eval_output_dir
下,您可以在本地查看结果文件(如 JSON 文件或图片)。
服务器上可以使用的下载方法
在服务器上可以使用以下方法,让下载任务在后台运行,同时确保任务不会因为会话断开而停止:
方法 1:使用 nohup
nohup
命令允许进程在后台运行,即使你断开 SSH 会话,任务也会继续执行。
-
运行后台下载任务:
nohup wget -i file_list.txt > download.log 2>&1 &
wget -i file_list.txt
: 批量下载文件。> download.log
: 将输出记录到download.log
文件中,便于查看进度。2>&1
: 将标准错误重定向到日志文件中。&
: 将任务放入后台运行。
-
检查运行状态:
- 查看后台任务:
jobs
- 如果需要重新连接任务,使用:
fg %1
- 查看后台任务:
-
查看下载日志:
- 你可以通过以下命令查看日志:
tail -f download.log
- 你可以通过以下命令查看日志:
方法 2:使用 screen
screen
是一个多窗口管理工具,允许你在断开连接后重新连接到任务。
-
启动一个新会话:
screen -S download
-
运行下载任务:
在新窗口中运行下载命令:wget -i file_list.txt
-
分离会话:
按下Ctrl + A
,然后按D
键,可以将会话分离到后台。 -
重新连接会话:
当你重新登录服务器时,使用以下命令重新连接:screen -r download
方法 3:使用 tmux
tmux
是类似于 screen
的工具,可以管理多个终端会话。
-
启动
tmux
会话:tmux new -s download
-
运行下载任务:
在会话中运行下载命令:wget -i file_list.txt
-
分离会话:
按下Ctrl + B
,然后按D
,将会话分离到后台。 -
重新连接会话:
当需要重新连接时,运行:tmux attach -t download
方法 4:使用 &
和 disown
-
运行下载任务:
wget -i file_list.txt > download.log 2>&1 &
-
断开任务与当前会话的关系:
disown
方法对比
方法 | 优点 | 缺点 |
---|---|---|
nohup |
简单易用,适合短期任务 | 不支持任务管理,需手动查看日志 |
screen |
可重连会话,支持多个任务管理 | 初次使用需要记住快捷键 |
tmux |
功能强大,支持分屏、重连 | 配置稍复杂,初次使用需学习 |
& + disown |
命令简单,适合小任务 | 无法重连任务,需谨慎使用 |
推荐方法
- 如果任务较多且复杂,推荐使用
screen
或tmux
。 - 如果是简单的批量下载,推荐使用
nohup
。
对于你描述的这种批量下载多个大文件的场景(Huggingface 数据集),建议使用 nohup
或 tmux
,具体选择取决于以下因素:
推荐 1:nohup
(简单高效,适合一次性下载)
如果你只需要运行一个简单的批量下载任务,不需要频繁监控或重新进入任务,那么 nohup
是最合适的选择。
优点:
- 简单易用,无需额外学习或配置。
- 下载完成后可以查看日志文件,检查是否有错误。
- 适合这种短时间的批量下载任务(只下载一组文件)。
操作步骤:
-
运行命令:
nohup wget -i file_list.txt > download.log 2>&1 &
wget
会读取file_list.txt
中的链接依次下载。- 下载日志会保存在
download.log
文件中。
-
查看进度:
tail -f download.log
-
任务完成后:
- 如果你重新登录服务器,可以通过查看
download.log
确认任务是否成功。
- 如果你重新登录服务器,可以通过查看
推荐 2:tmux
(需要灵活监控的任务)
如果你希望在下载过程中能够实时监控任务进度,甚至在网络中断后重新连接到任务,tmux
是更适合的选择。
优点:
- 支持重连,适合长时间运行的任务。
- 支持在同一会话中运行多个任务(如同时解压文件、检查文件完整性)。
- 使用灵活,支持实时切换任务窗口。
操作步骤:
-
启动
tmux
会话:tmux new -s download
-
运行下载命令:
wget -i file_list.txt
-
分离会话:
按下Ctrl + B
,然后按D
,将会话分离。 -
重新连接:
如果你断开连接,可以重新连接到任务:tmux attach -t download
-
查看文件下载进度:
wget
本身会显示每个文件的下载进度(包括百分比、下载速度等)。
选择依据
- 任务简单、一次性完成: 使用
nohup
,非常简单,运行后就不用管了。 - 需要实时监控、可能断网: 使用
tmux
,方便断网后重连并继续监控任务。
不推荐的方案
screen
:- 功能类似于
tmux
,但快捷键不如tmux
直观,扩展性稍差。
- 功能类似于
- 直接运行任务(不后台运行):
- 如果没有
nohup
或tmux
,会话断开任务也会中断,不安全。
- 如果没有
推荐方案:nohup
示例
对于你的场景,直接运行以下命令即可:
nohup wget -i file_list.txt > download.log 2>&1 &
后台运行下载任务,避免因为网络断开导致任务中断。
额外建议:验证文件完整性
下载完成后,使用以下方式检查文件完整性:
-
检查文件大小:
确认每个文件的大小是否与 Huggingface 页面显示一致:ls -lh
-
解压测试:
在解压前测试文件完整性(以 ZIP 为例):unzip -t Training_aa.zip
如果你的任务时间较长或者网络环境不稳定,我更推荐 tmux
。如果不想复杂操作,nohup
也能很好地解决问题。根据你的偏好选择即可!
计划将模型应用到机器人系统中
如果你计划将模型应用到机器人系统中,实时性通常是一个关键要求,尤其是涉及感知(如视觉、激光雷达数据处理)和决策控制的任务。以下是一些关键点和建议,帮助你优化模型的实时性和部署效果。
为什么实时性很重要?
动态环境中的决策需求:机器人需要在变化的环境中快速处理传感器数据,避免延迟导致错误决策或碰撞。
高频控制循环:例如,导航系统可能要求传感器数据处理的频率达到 20Hz 或更高,延迟会直接影响控制效果。
任务连续性:实时处理能保证机器人动作流畅,不出现“卡顿”或“犹豫”的现象。
实现实时性的方法
- 硬件优化
选择合适的硬件:
使用 NVIDIA Jetson 系列(如 Jetson Xavier、Jetson Orin),集成 GPU 并支持 TensorRT。
对于低功耗场景,可以选择带 VPU(如 Intel Movidius)或 FPGA 的嵌入式设备。
如果需要高算力,配备高性能 GPU(如 NVIDIA A100)在机器人主机端运行。
分布式计算:
在机器人上部署传感器处理和关键推理功能。
更复杂的模型推理或决策可以交由云端或边缘设备完成,使用高速网络(如 5G)连接。
2. 软件优化
模型优化:
使用 TensorRT 或 OpenVINO 对模型进行量化和硬件加速。
将模型的计算图优化成静态图(如 PyTorch 的 TorchScript)。
精度和速度平衡:
根据需求选择模型精度:INT8 > FP16 > FP32。
精度需求较低的任务(如简单分类或检测)可使用较低精度模型,获得数倍的推理速度提升。
轻量级模型设计:
考虑使用轻量化模型结构(如 MobileNet、YOLOv5-Nano)。
削减冗余计算层,裁剪掉影响不大的通道或权重。
3. 系统架构优化
多线程/异步处理:
将传感器数据采集、模型推理和控制逻辑分开运行,避免任务之间互相阻塞。
使用框架如 ROS/ROS2,充分利用多核 CPU 和 GPU。
推理流水线:
对输入数据进行批量化处理,减少每帧的推理开销。
推理任务可以与其他任务并行运行,尽量减少单线程计算。
减少输入数据量:
将输入图像分辨率降低(如从 1080p 降到 720p 或 480p),减少推理时间。
剪裁输入区域(Region of Interest,ROI),只处理关注的区域。
4. 使用实时框架
ROS/ROS 2:机器人中最常用的中间件,支持实时传感器数据处理和模型推理。
DeepStream:NVIDIA 提供的高效实时视频流分析框架,适合机器人视觉应用。
FastAPI + Edge AI:通过 FastAPI 部署轻量级 API,将模型部署到边缘设备,实时处理请求。
需要实时运行的任务例子
物体检测与分类:
使用 YOLOv8 或类似模型,实时检测周围环境中的障碍物或目标。
SLAM(即时定位与地图构建):
使用 ORB-SLAM3 或 LIO-SAM 系统结合视觉/激光雷达数据。
人机交互:
实时检测手势、语音指令,并快速响应。
实时性评估
在机器人的实际应用中,你可以通过以下指标评估实时性是否达标:
延迟:
单帧处理时间是否低于任务要求的帧率(例如 30 FPS)。
资源利用率:
CPU/GPU 使用率是否维持在合理范围内,不出现过载。
行为流畅性:
机器人是否能对环境变化做出平滑、及时的反应。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!