公司动态
SPVNAS 点-体素双向转换全解:point_to_voxel 与 GPU 哈希表加速的底层机制
SPVNAS 点-体素双向转换全解point_to_voxel 与 GPU 哈希表加速的底层机制【免费下载链接】spvnas[ECCV 2020] Searching Efficient 3D Architectures with Sparse Point-Voxel Convolution项目地址: https://gitcode.com/gh_mirrors/sp/spvnasSPVNAS 是 ECCV 2020 提出的高效 3D 深度神经网络通过稀疏点-体素卷积在点云语义分割任务上取得了 SOTA 精度与速度。它的最大亮点在于一条贯穿网络的点-体素双向转换数据流point_to_voxel把点特征汇聚进体素voxel_to_point又把体素特征插值回点云两者都借助 GPU 哈希表实现毫秒级的邻域查找。本文用通俗的方式带你完整看懂这套机制的底层实现。 为什么点云网络需要点-体素双向转换表示方式优点缺点点Point保留原始精确位置结构不规则卷积难以直接加速体素Voxel规整、可稀疏卷积加速下采样后会丢失精细位置信息SPVNAS 的思路是两条腿走路网络前向中同时维护一个体素分支xSparseTensor和一个点分支zPointTensor。体素分支负责高速稀疏卷积点分支负责保留精确坐标两个分支之间通过双向转换函数不断交换特征。上图SPVNAS 在 SemanticKITTI 上的点云语义分割预测结果可视化由 visualize.py 生成每个点都携带经过点-体素双向融合后的类别特征⚡ 核心实现三个函数看懂双向转换全部转换逻辑都集中在 core/models/utils.py 中只有三个公开函数见文件第 13 行的__all__。1️⃣ initial_voxelize第一次点云变体素网络入口处原始点云按初始分辨率默认 0.05m由 configs/semantic_kitti/default.yaml 配置向下取整得到体素坐标同一格内的点特征用scatter_mean平均完成第一次体素化。2️⃣ point_to_voxel点特征如何汇入体素第 71-91 行流程只有四步把点坐标按当前体素步长x.s缩放并向下取整得到点落在哪个体素调用sphashquery在体素哈希表中批量查询得到每个点对应的体素索引用torch_scatter.scatter_mean将点特征平均池化进体素生成新的 SparseTensor 返回。这里有一个关键设计——索引缓存查询结果按体素分辨率存进z._caches.idx_query[x.s]同一分辨率下重复调用时直接命中缓存避免二次建表。3️⃣ voxel_to_point体素特征如何插值回点第 96-127 行反向转换用的是切比雪夫反距离插值Tchebychev Interpolation对每个点以kernel_size2在哈希表中查找周围 26 个体素邻居calc_ti_weights按坐标与体素中心的距离算出插值权重spf.spdevoxelize用权重加权求和得到该点的融合特征。idx_query_devox与weights_devox同样被缓存保证同一尺度只计算一次。 GPU 哈希表sphashquery 的加速原理邻居查询是稀疏点云计算的性能瓶颈。core/models/utils.py 中的sphashquery是加速核心它直接调用torchsparse.backend.GPUHashTable键值表完全驻留在 GPU 显存insert_coords建表、lookup_coords查表全程零 CPU-GPU 数据往返查表以坐标 kernel 尺寸为参数一次性完成天然并行返回-1表示未命中该邻居体素不存在point_to_voxel中用clamp_(0)优雅地把缺失点归入第 0 号体素参与平均避免越界。相比传统的CPU 排序 同步回 GPU查找方式GPU 哈希表让每次转换的开销从毫秒级降到微秒级这是 SPVNAS 能以约 20 GMACs 的低算力拿下 SemanticKITTI 榜首的关键之一参见 model_zoo.py 中的模型与精度对照表。 SPVNAS 前向中的完整数据流打开 core/models/semantic_kitti/spvnas.py 的forward函数可以清晰看到两条分支如何交替配合z PointTensor(x.F, x.C) # 建立点分支 x0 point_to_voxel(x, z) # 点 → 体素 x0 self.stem(x0) # 稀疏卷积 Stem z0 voxel_to_point(x0, z) # 体素 → 点 x1 point_to_voxel(x0, z0) # 再次 点 → 体素进入下采样主干 ... # downsample / upsample 交替进行 z3 voxel_to_point(y4, z2) # 输出端再做一次体素 → 点 out self.classifier(z3.F) # 逐点分类规律非常好记下采样前把点汇聚进体素point_to_voxel卷积后把特征插值回点voxel_to_point。编码器每降一级、解码器每升一级都重复一次该模式使得点云在整个 U-Net 过程中始终保有精确位置信息而卷积计算始终发生在高效的体素分支上。 相关资源与快速上手功能文件点-体素双向转换核心core/models/utils.pySPVNAS 网络定义core/models/semantic_kitti/spvnas.py动态卷积/线性模块core/modules/layers.pySemanticKITTI 训练配置configs/semantic_kitti/default.yaml训练 / 评估 / 可视化入口train.py · evaluate.py · visualize.py快速上手只需三步克隆仓库git clone https://gitcode.com/gh_mirrors/sp/spvnas按 README.md 的Prerequisites章节用 conda 安装 PyTorch 与 torchsparse单卡评估示例torchpack dist-run -np 1 python evaluate.py configs/semantic_kitti/default.yaml --name SemanticKITTI_val_SPVNAS65GMACs。✅ 小结SPVNAS 用point_to_voxelscatter 平均池化与voxel_to_point切比雪夫反距离插值实现点-体素双向特征流动兼顾速度精度性能核心是GPUHashTable哈希表查表 按分辨率的索引缓存让邻域查找完全跑在 GPU 上想深入源码从 core/models/utils.py 的 127 行代码入手配合 core/models/semantic_kitti/spvnas.py 的forward逐行对照即可完整掌握这套 ECCV 2020 架构的设计精髓。【免费下载链接】spvnas[ECCV 2020] Searching Efficient 3D Architectures with Sparse Point-Voxel Convolution项目地址: https://gitcode.com/gh_mirrors/sp/spvnas创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考