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
