Advertisement

Superpoint Transformer | 代码复现

阅读量:

前言

Superpoint Transformer 和 Superpoint Graph 的核心区别在于它们的架构设计和数据处理方式。
Superpoint Graph (SPG):

复制代码
    基于图结构:
    将点云划分为超点(superpoints),每个超点表示具有相似几何和语义属性的点集。
    构建超点之间的 图结构,图的节点是超点,边是超点之间的关系(如几何相邻性、相似性等)。
    使用 图神经网络 (GNN) 在超点图上进行推理。
    
    超点分割:
    通过传统的分割算法(如基于欧几里得距离、法向量聚类)对点云进行分割。
    不需要处理所有点,而是通过图节点的稀疏化表示大幅降低计算复杂度。

Superpoint Transformer (SPT):

复制代码
    基于 Transformer:
    将超点看作序列,使用 Transformer 架构 对超点进行推理。
    自注意力机制捕获超点之间的全局依赖关系,无需显式构建图结构。
    
    超点生成:
    类似 SPG,先通过几何特征生成超点,但在超点之间的推理中采用了不同的方法(基于自注意力)。

Superpoint Graph (SPG):

复制代码
    输入表示:
    图结构 G=(V,E)G=(V,E),其中 VV 是超点节点,EE 是节点之间的边。
    每个节点有一个特征向量,表示超点的属性(如大小、平均颜色、几何特性)。
    
    图神经网络 (GNN):
    在图上运行 GNN,例如 Edge Convolution (EdgeConv),用来捕获超点之间的几何关系。
    通过消息传递机制更新节点特征。
    依赖图结构,因此需要预定义超点之间的连接关系。
    
    限制:
    图结构构建可能存在信息丢失,尤其是在点云稀疏或超点划分质量不高的情况下。
    图操作可能对并行性支持不够,特别是在大规模数据上。

Superpoint Transformer (SPT):

复制代码
    输入表示:
    超点序列 S=[s1,s2,...,sn]S=[s1​,s2​,...,sn​],每个超点 sisi​ 是一个特征向量,表示超点的属性。
    不需要构建显式图结构。
    
    Transformer 架构:
    使用 多头自注意力机制 (Multi-head Self-Attention) 计算超点之间的相关性:
    Attention(Q,K,V)=softmax(QK⊤dk)V
    Attention(Q,K,V)=softmax(dk​
    
    ​QK⊤​)V 其中 QQ, KK, VV 是超点的特征表示。
    每个超点的表示更新时,会考虑所有其他超点的全局关系,适合捕获长距离依赖。

优势:

复制代码
    全局感知能力强,自注意力机制可以捕获远程依赖关系。
    支持并行计算,尤其适合 GPU 加速。

github链接🔗 https://github.com/drprojects/superpoint_transformer

在这里插入图片描述

1. 安装依赖

复制代码
    ./install.sh

检查安装是否成功
激活环境:

复制代码
    conda activate spt

测试 PyTorch 是否正确安装并支持 GPU:

复制代码
    python -c "import torch; print(torch.cuda.is_available())"

返回 True 表示安装成功。

如果本地cuda环境不匹配,可以在虚拟环境里面安装新的cuda

复制代码
    conda create -n spt python=3.9 -y
    conda activate spt
    pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
    python -c "import torch; print(torch.cuda.is_available())"

install.sh 中有硬性 CUDA 检查逻辑,需要跳过它

关键修改点 1:跳过 CUDA 版本检查

在脚本中,CUDA 检查部分会导致问题,因为它检测的是系统 CUDA,而不是虚拟 CUDA。可以直接跳过这部分检查。

复制代码
    找到以下代码:
复制代码
    CUDA_VERSION=`nvcc --version | grep release | sed 's/.*, release //' | sed 's/,.*//'`
    CUDA_MAJOR=`echo ${CUDA_VERSION} | sed 's/\..*//'`
    CUDA_MINOR=`echo ${CUDA_VERSION} | sed 's/.*\.//'`
    
    if [[ ! " ${CUDA_SUPPORTED[*]} " =~ " ${CUDA_VERSION} " ]]
    then
    echo "Found CUDA ${CUDA_VERSION} installed, which is not among the supported versions: "`echo ${CUDA_SUPPORTED[*]}`
    echo "Please update CUDA to one of the supported versions."
    exit 1
    fi

将其注释掉。

关键修改点 2:强制使用虚拟 CUDA
找到以下代码(PyTorch 和相关依赖安装部分):

复制代码
    pip install torch==${TORCH} torchvision --index-url https://download.pytorch.org/whl/cu${CUDA_MAJOR}${CUDA_MINOR}
    pip install pyg_lib torch_scatter torch_cluster torch_spline_conv -f https://data.pyg.org/whl/torch-${TORCH}+cu${CUDA_MAJOR}${CUDA_MINOR}.html

修改为使用你创建的虚拟环境 CUDA(例如,CUDA 11.8):

复制代码
    pip install torch==${TORCH} torchvision --index-url https://download.pytorch.org/whl/cu118
    pip install pyg_lib torch_scatter torch_cluster torch_spline_conv -f https://data.pyg.org/whl/torch-${TORCH}+cu118.html

运行

复制代码
    ./install.sh

2. 设置 S3DIS 数据集路径

新建data和logs文件夹,data/s3dis/Stanford3dDataset_v1.2/…
在 configs/local/ 文件夹中创建 default.yaml 文件:

复制代码
    # @package paths
    
    # 数据集路径
    data_dir: ./data/s3dis/
    
    # 日志路径
    log_dir: ./logs/

还需要一个数据文件夹:
superpoint_transformer/data/s3dis/s3dis/raw/Area1~Area6

3. 数据预处理

在 src/datasets/base.py 中修改 os.symlink 的调用逻辑

复制代码
    if not osp.exists(val_dir):
    if self.val_mixed_in_train:
        os.makedirs(osp.dirname(val_dir), exist_ok=True)
        try:
            os.symlink(train_dir, val_dir, target_is_directory=True)
            print(f"Created symbolic link from {train_dir} to {val_dir}")
        except FileExistsError:
            print(f"Symbolic link {val_dir} already exists, skipping creation.")
    else:
        os.makedirs(val_dir, exist_ok=True)
    
    if not osp.exists(test_dir):
    if self.test_mixed_in_val:
        os.makedirs(osp.dirname(test_dir), exist_ok=True)
        try:
            os.symlink(val_dir, test_dir, target_is_directory=True)
            print(f"Created symbolic link from {val_dir} to {test_dir}")
        except FileExistsError:
            print(f"Symbolic link {test_dir} already exists, skipping creation.")
    else:
        os.makedirs(test_dir, exist_ok=True)

原本是运行:

复制代码
    python src/train.py experiment=semantic/s3dis datamodule.fold=5 logger=csv

但是由于我电脑的gpu内存不够,所以切换为cpu运行了

复制代码
    python src/train.py experiment=semantic/s3dis datamodule.fold=5 logger=csv trainer.max_epochs=10 datamodule.dataloader.batch_size=1 trainer.accelerator=cpu trainer.devices=1

参考了官网解决内存不足的问题后,用下面的代码可以开始训练!

复制代码
    python src/train.py experiment=semantic/s3dis datamodule.fold=5 logger=csv datamodule.dataloader.batch_size=1 datamodule.sample_graph_k=8 datamodule.sample_graph_r=0.5 datamodule.sample_point_max=300 datamodule.max_num_nodes=5000 datamodule.max_num_edges=20000 callbacks.gradient_accumulator.scheduling='{0: 4}' trainer.max_epochs=10

评估:

复制代码
    python src/eval.py experiment=semantic/s3dis datamodule.fold=5 ckpt_path=/home/msi/code/Largescale_PointCloud_Semantic/superpoint_transformer/logs/train/runs/2025-01-09_11-00-32/checkpoints/epoch_009.ckpt

全部评论 (0)

还没有任何评论哟~