复现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 下载:

下载和解压数据

  1. 下载数据
    • 数据链接在 Huggingface Dataset Hub 中。
    • 下载以下压缩包:
      • Training_aa.zipTraining_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 数据集)。

应用场景
  1. AR/VR 和 机器人感知:将 3D 数据投影到 2D 平面是很多计算机视觉任务的前置步骤,例如 SLAM、目标跟踪和导航。
  2. 数据集处理:适用于需要从 3D 数据中生成 2D 注释的数据集,例如自动驾驶数据集的转换。
  3. 深度学习模型训练:生成的 2D 注释可以用于目标检测模型(如 YOLO、Faster R-CNN)的训练和评估。
脚本具体解释
  1. 数据加载与预处理
    读取 ARKit 数据集中的 3D 注释、轨迹文件(traj)、深度图像和相机内参。
    Convert2DDataLoader 类负责逐帧加载数据,包括:
    深度图像 (depth): 用于生成点云。
    轨迹文件 (traj): 提供每帧的相机位姿。
    内参文件 (pincam): 用于将 3D 坐标投影到 2D 图像平面。
  2. 3D 点云投影到 2D
    generate_point 函数:
    使用相机内参将深度图像生成的 3D 点云投影到 2D 图像平面。
    如果指定世界坐标系,还会应用相机位姿转换。
    投影后的点云包括 3D 坐标和对应的 2D 像素坐标。
  3. 边界框处理
    get_2d_box 和 post_process_coords 函数:
    通过 3D 边界框的角点坐标,将其投影到 2D 平面。
    检查投影结果是否在图像画布内,并进行后处理(例如获取凸包或交集)。
  4. 注释生成
    每帧图像都会生成对应的 2D 注释,包括:
    2D 边界框 (bbox): xmin, ymin, xmax, ymax。
    标签 (label): 表示物体类别。
    唯一标识 (uid): 用于区分物体。
  5. 多进程处理
    使用 multiprocessing.Pool 将视频分割成多个部分,每个子进程处理一部分视频,提升处理速度。
  6. 注释保存
    最终将生成的 2D 注释保存为 JSON 文件,文件名类似 2d_annotations_<video_id>.json。
脚本优点
  1. 效率优化
    使用多进程 (multiprocessing.Pool) 来并行化处理多个视频,节省时间。
    对点云和边界框进行了过滤(如仅保留至少 20 个点的边界框)。
  2. 精度控制
    在轨迹时间戳和帧 ID 匹配时,允许微小误差(±0.001 秒),以最大限度匹配数据。
  3. 灵活性
    支持动态分辨率调整(如裁剪图像以匹配深度图像尺寸)。

gt_generation.py

生成拓扑结构的 Ground Truth 数据 (Ground Truth for Topological Adjacency),主要是为了描述场景中不同位置和物体的关系,包括位置之间的相邻关系(P-P Adjacency)和位置与物体之间的相邻关系(P-O Adjacency)。

目的
  1. 场景拓扑结构分析;通过 P-P 邻接矩阵,可以分析不同帧之间的空间关系,帮助构建场景的拓扑结构。
  2. 物体与场景关系建模:P-O 邻接矩阵描述了物体在场景中的分布,便于后续任务(如场景重建、导航规划)使用。
  3. 自动驾驶与机器人应用:在自动驾驶或机器人应用中,这些拓扑数据有助于理解场景布局和物体分布,支持路径规划和决策。
脚本解释
  1. 从轨迹数据中提取相机位姿
    函数 get_poses:
    解析轨迹文件 (lowres_wide.traj) 中的每帧位姿数据,返回所有帧的 4x4 位姿矩阵。
    如果当前帧的内参文件 (pincam) 不存在,会尝试向前或向后微调时间戳以匹配。
  2. 计算帧间的旋转和位移差异
    函数 rot_distance 和 trans_distance:
    分别计算帧与帧之间的旋转角度差(通过旋转矩阵的几何距离)和位移差(通过欧几里得距离)。
    函数 pairwise_diff:
    通过批处理方式计算所有帧之间的旋转差异矩阵和位移差异矩阵。
  3. 生成位置与位置之间的相邻关系
    函数 place_adj:
    根据旋转差异阈值和位移差异阈值,生成帧之间的相邻关系矩阵(P-P Adjacency)。
    函数 make_data:
    对每个视频生成 P-P 邻接矩阵,并记录哪些帧没有邻居(孤立帧)。
  4. 生成位置与物体之间的相邻关系
    函数 get_gt_po 和 regen_po_adj:
    根据 2D 注释文件(2d_annotations_.json),生成位置与物体之间的邻接矩阵(P-O Adjacency)。
    P-O Adjacency 描述了在特定帧中,物体是否出现在对应位置。
  5. 记录 Ground Truth
    包括:
    元数据 (meta):旋转差异和位移差异的最大值,采样帧率,孤立帧数量等。
    邻接矩阵 (p-p 和 p-o):分别描述位置与位置、位置与物体的关系。
    注释 (annotations):记录每帧的物体信息,包括边界框和类别。
  6. 对数据集的所有视频进行处理
    主函数中,通过 regen_po_adj 遍历不同数据集分组(如 Validation、Training),处理每个视频的 Ground Truth 数据,并跳过指定的无效视频。

关键点

  1. 旋转与平移阈值的选择
    rot_thres 和 trans_thres 是决定相邻关系的重要参数:
    旋转阈值(单位:弧度)控制帧间的角度相似性。
    平移阈值(单位:米)控制帧间的空间接近性。
    合理选择这些阈值,可以过滤掉过于遥远或角度偏差过大的帧。
  2. 优化性能
    使用批量计算(torch 的广播机制)加速帧间差异的计算。
    对数据进行采样(frame_every 参数)以减少计算量。
  3. 容错处理
    处理丢失帧的情况(如缺少内参或注释)时,尝试通过微调时间戳或跳过无效帧来保证脚本的健壮性。

preprocess_utils.py

定义了一些 拓扑结构处理(topo process) 所需的实用工具函数,用于解析相机轨迹(pose)和内参(intrinsics),并生成 4x4 的相机变换矩阵或 3x3 的相机内参矩阵。
可以帮助将数据从轨迹文件或内参文件中提取并格式化,为后续的 SLAM、场景重建或导航任务提供基础数据支持。

  1. 旋转向量转换为旋转矩阵
    函数 convert_angle_axis_to_matrix3:
    输入:旋转向量(角轴表示,angle_axis)。
    输出:对应的旋转矩阵(3x3)。
    原理:
    使用 OpenCV 的 cv2.Rodrigues 函数,将角轴表示的旋转向量(Angle-Axis)转换为旋转矩阵。
    角轴表示是一种紧凑的旋转表示法,其中旋转向量的方向表示旋转轴,长度表示旋转角度。
  2. 轨迹字符串转换为变换矩阵
    函数 TrajStringToMatrix:
    输入:轨迹字符串(traj_str),每行包含以下 7 列信息:
    时间戳(timestamp)
    旋转(角轴表示,3 个值)
    平移(3 个值)
    输出:
    时间戳(ts)。
    相机的 4x4 位姿矩阵(Rt)。
    原理:
    提取角轴表示的旋转向量,使用 convert_angle_axis_to_matrix3 转换为旋转矩阵。
    提取平移向量,组合旋转矩阵和平移向量,生成 4x4 的外参矩阵。
    通过矩阵求逆(np.linalg.inv)将其转换到相机坐标系。
  3. 读取相机内参
    函数 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. 预训练模型准备

  1. 下载预训练模型

    • 预训练的 AoMSG 模型可从 Huggingface 数据库下载。
    • 将模型下载到 ./exp-results/aomsg 目录下:
      mkdir -p ./exp-results/aomsg
      # 将预训练模型文件移动到此目录
      
  2. 检查路径
    确保模型的路径如下:

    ./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. 注意事项

  1. 目标检测依赖

    • 当前版本未包含对象检测的代码。您需要单独运行目标检测,并将检测结果存储到指定路径。
    • GroundingDINO 结果文件已在数据集中提供,可直接使用。
    • ./configs/experiments/aomsg_gdino.yaml 中,指定目标检测结果路径。
  2. 在线检测

    • 当前版本不支持在线检测,后续版本可能会支持。

9. 数据处理(可选)

如果想要自定义数据转换,可参考 data_preprocess 中的代码来复现从 3D 注释到 2D 数据的转换过程。


10. 结果可视化

推理结果和可视化会保存在指定的 eval_output_dir 下,您可以在本地查看结果文件(如 JSON 文件或图片)。

服务器上可以使用的下载方法

在服务器上可以使用以下方法,让下载任务在后台运行,同时确保任务不会因为会话断开而停止:


方法 1:使用 nohup

nohup 命令允许进程在后台运行,即使你断开 SSH 会话,任务也会继续执行。

  1. 运行后台下载任务

    nohup wget -i file_list.txt > download.log 2>&1 &
    
    • wget -i file_list.txt: 批量下载文件。
    • > download.log: 将输出记录到 download.log 文件中,便于查看进度。
    • 2>&1: 将标准错误重定向到日志文件中。
    • &: 将任务放入后台运行。
  2. 检查运行状态

    • 查看后台任务:
      jobs
      
    • 如果需要重新连接任务,使用:
      fg %1
      
  3. 查看下载日志

    • 你可以通过以下命令查看日志:
      tail -f download.log
      

方法 2:使用 screen

screen 是一个多窗口管理工具,允许你在断开连接后重新连接到任务。

  1. 启动一个新会话

    screen -S download
    
  2. 运行下载任务
    在新窗口中运行下载命令:

    wget -i file_list.txt
    
  3. 分离会话
    按下 Ctrl + A,然后按 D 键,可以将会话分离到后台。

  4. 重新连接会话
    当你重新登录服务器时,使用以下命令重新连接:

    screen -r download
    

方法 3:使用 tmux

tmux 是类似于 screen 的工具,可以管理多个终端会话。

  1. 启动 tmux 会话

    tmux new -s download
    
  2. 运行下载任务
    在会话中运行下载命令:

    wget -i file_list.txt
    
  3. 分离会话
    按下 Ctrl + B,然后按 D,将会话分离到后台。

  4. 重新连接会话
    当需要重新连接时,运行:

    tmux attach -t download
    

方法 4:使用 &disown

  1. 运行下载任务

    wget -i file_list.txt > download.log 2>&1 &
    
  2. 断开任务与当前会话的关系

    disown
    

方法对比

方法 优点 缺点
nohup 简单易用,适合短期任务 不支持任务管理,需手动查看日志
screen 可重连会话,支持多个任务管理 初次使用需要记住快捷键
tmux 功能强大,支持分屏、重连 配置稍复杂,初次使用需学习
& + disown 命令简单,适合小任务 无法重连任务,需谨慎使用

推荐方法

  • 如果任务较多且复杂,推荐使用 screentmux
  • 如果是简单的批量下载,推荐使用 nohup

对于你描述的这种批量下载多个大文件的场景(Huggingface 数据集),建议使用 nohuptmux,具体选择取决于以下因素:


推荐 1:nohup(简单高效,适合一次性下载)

如果你只需要运行一个简单的批量下载任务,不需要频繁监控或重新进入任务,那么 nohup 是最合适的选择。

优点

  • 简单易用,无需额外学习或配置。
  • 下载完成后可以查看日志文件,检查是否有错误。
  • 适合这种短时间的批量下载任务(只下载一组文件)。

操作步骤

  1. 运行命令

    nohup wget -i file_list.txt > download.log 2>&1 &
    
    • wget 会读取 file_list.txt 中的链接依次下载。
    • 下载日志会保存在 download.log 文件中。
  2. 查看进度

    tail -f download.log
    
  3. 任务完成后

    • 如果你重新登录服务器,可以通过查看 download.log 确认任务是否成功。

推荐 2:tmux(需要灵活监控的任务)

如果你希望在下载过程中能够实时监控任务进度,甚至在网络中断后重新连接到任务,tmux 是更适合的选择。

优点

  • 支持重连,适合长时间运行的任务。
  • 支持在同一会话中运行多个任务(如同时解压文件、检查文件完整性)。
  • 使用灵活,支持实时切换任务窗口。

操作步骤

  1. 启动 tmux 会话

    tmux new -s download
    
  2. 运行下载命令

    wget -i file_list.txt
    
  3. 分离会话
    按下 Ctrl + B,然后按 D,将会话分离。

  4. 重新连接
    如果你断开连接,可以重新连接到任务:

    tmux attach -t download
    
  5. 查看文件下载进度

    • wget 本身会显示每个文件的下载进度(包括百分比、下载速度等)。

选择依据

  • 任务简单、一次性完成: 使用 nohup,非常简单,运行后就不用管了。
  • 需要实时监控、可能断网: 使用 tmux,方便断网后重连并继续监控任务。

不推荐的方案

  • screen
    • 功能类似于 tmux,但快捷键不如 tmux 直观,扩展性稍差。
  • 直接运行任务(不后台运行):
    • 如果没有 nohuptmux,会话断开任务也会中断,不安全。

推荐方案:nohup 示例

对于你的场景,直接运行以下命令即可:

nohup wget -i file_list.txt > download.log 2>&1 &

后台运行下载任务,避免因为网络断开导致任务中断。


额外建议:验证文件完整性

下载完成后,使用以下方式检查文件完整性:

  1. 检查文件大小
    确认每个文件的大小是否与 Huggingface 页面显示一致:

    ls -lh
    
  2. 解压测试
    在解压前测试文件完整性(以 ZIP 为例):

    unzip -t Training_aa.zip
    

如果你的任务时间较长或者网络环境不稳定,我更推荐 tmux。如果不想复杂操作,nohup 也能很好地解决问题。根据你的偏好选择即可!

计划将模型应用到机器人系统中

如果你计划将模型应用到机器人系统中,实时性通常是一个关键要求,尤其是涉及感知(如视觉、激光雷达数据处理)和决策控制的任务。以下是一些关键点和建议,帮助你优化模型的实时性和部署效果。

为什么实时性很重要?
动态环境中的决策需求:机器人需要在变化的环境中快速处理传感器数据,避免延迟导致错误决策或碰撞。
高频控制循环:例如,导航系统可能要求传感器数据处理的频率达到 20Hz 或更高,延迟会直接影响控制效果。
任务连续性:实时处理能保证机器人动作流畅,不出现“卡顿”或“犹豫”的现象。
实现实时性的方法

  1. 硬件优化
    选择合适的硬件:

使用 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 使用率是否维持在合理范围内,不出现过载。
行为流畅性:
机器人是否能对环境变化做出平滑、及时的反应。

posted @   asandstar  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示