目录
2.中间卷积层(Convolution middle layers)
论文地址:https://arxiv.org/abs/1711.06396
代码地址:GitHub - RPFey/voxelnet_pytorch: modification of voxelnet
一、论文动机
1.传统的点云特征手工提取具有很大的局限性,不能适应点云检测场景的多变性。
2.pointnet和++都是处理的小规模数量点云,一般都是几千个点左右。而lidar点云一般都是几万级别的。
二、论文方法
1.提出了一种端到端的点云检测框架,直接在稀疏点云上运行,避免了手动特征工程的信息瓶颈
2.提出了VFE体素特征编码网络,可以有效的提取体素特征
3.引入RPN区域提议网络,用于高效的目标检测
具体来说,VoxelNet 将点云划分为等间距的 3D 体素,通过堆叠 VFE 层对每个体素进行编码,然后 3D 卷积进一步聚合这些局部体素的特征,将三维特征的点云转换为高维特征表示。最后, 使用RPN产生检测结果。这种高效的算法受益于稀疏点结构和体素网格上的高效并行处理。
三、网络结构

1.Feature Learning Network
1.1Voxel划分
将点云在空间上划分为许多体素,设定体素的长宽高,并对点云裁剪,太边缘的不要,因为很稀疏没啥用。论文中划分后为[352,400,10]个voxel
1.2Grouping(将每个点分配给对应的Voxel)和Sampling(voxel中点云的采样)
体素化后,有好多网格里面没有点,有些点又过多,这时我们对非空的voxel进行降采样,每个里面随机采样T个点,不足的用0补充。因此在grouping之后,得到的数据为[N,T,C],N为非空体素的个数,T为每个体素里面采样的点,C为特征。论文里T为35,C为7, [xi , yi , zi , ri, xi_offset,yi_offset,zi_offset],先求出每个体素里面35个点的均值,每个点xyz都减去均值,得到xyz偏移。
1.3VFE堆叠
将每个voxel中的点通过全连接层转换为高维空间(每个全连接层包括FC,RELU,BN),维度也从(N,35,7)变成了(N,35,C1),然后maxpooling得到voxel的聚合特征,将聚合特征拼接到每个高维点云特征中,得到(N,35,2*C1),我们将这个过程称之为VFE模块。原论文中有两个VFE模块,得到(N,35,32),(N,35,128),得到这个特征之后需要再进行一个FC来融合点特征和聚合特征,这个FC保持输入输出维度不变,还是(N,35,128),再maxpooling一下,得到(N,128)
1.4稀疏特征表示
前面的操作都是对非空体素的操作,这些voxel仅仅对应3D空间中很小一部分,现在将那些非空的体素还原到3D空间中,得到一个稀疏的4D张量(128,10,400,352)
2.中间卷积层(Convolution middle layers)
得到稀疏张量之后,我们使用三维卷积来聚合voxel之间的局部关系,扩大感受野获取更丰富的形状信息,方便RPN预测。论文里使用了三个三维卷积(cin,cout,K,S,P)
Conv3D(128, 64, 3, (2,1,1), (1,1,1)),
Conv3D(64, 64, 3, (1,1,1), (0,1,1)),
Conv3D(64, 64, 3, (2,1,1), (1,1,1))
最终得到的张量为 (64,2,400,352),将数据整理成RPN网络需要的特征体,reshape成(64*2,400,352),这样维度就变成了C,Y,X,不考虑Z的原因是kitti的3D空间在高度上没有堆叠,这样也减少了网络后期RPN的设计难度和anchor数量。
3.RPN层

这里每一层卷积都是二维的卷积操作,每个卷积后面都接一个BN和RELU层。最终的预测结果只针对一类,两个角度的预测,所以是(B,2,200,176)和(B,14,200,176),anchor沿着xy间隔放置。
四、损失函数及其余创新点
4.1损失函数
正负样本匹配:在BEV视角进行2D IOU匹配,大于0.6为正样本,小于0.45为负样本,中间不计。分类损失正负样本都记,使用交叉熵损失函数,回归损失只记正样本的,使用smoothL1函数。
4.2点云的数据增强
1.由于标注的时候一个GTbox已经标注出来了有哪些点,所以可以同时移动或者旋转这些点来创造大量的变化数据,移动后还要进行碰撞检测,删掉碰撞的那些GT。
2.对所有的GTbox进行放大或者缩小,放大缩小尺度在[0.95,1.05]之间,引入缩放可以使得网络在检测不同大小物体上有更好的泛化性能。
3.对所有的GT box进行随机的旋转操作,角度在[-45,45]均匀分布中抽取,旋转物体的偏航角可以模拟其转了一个弯。
4.3高效实现堆叠VFE

由于每个voxel中包含的点个数不一样,所以作者将所有点云数据转换成了一种密集的数据结构,使得后面堆叠VFE可以在所有点和voxel的特征上平行处理。
1、首先创建一个K*T*7的张量(voxel input feature buffer)用来存储每个点或者中间的voxel特征数据,K是最大的非空voxel数量,T是每个voxel中最大的点数,7是每个点的编码特征。所有的点都是被随机处理的。
2、遍历整个点云数据,如果一个点对应的voxel在voxel coordinate buffer中,并且与之对应的voxel input feature buffer中点的数量少于T个,直接将这个点插入其中,否则直接抛弃。如果一个点对应的voxel不在voxel coordinate buffer中,需要在voxel coordinate buffer中直接使用这个voxel的坐标初始化这个voxel,并储存这个点到voxel input feature buffer中。这整个操作都是用哈希表完成,因此时间复杂度都是O(1)。整个Voxel Input Feature Buffer和voxel coordinate buffer的创建只需要遍历一次点云数据就可以,时间复杂度只有O(N),同时为了进一步提高内存和计算资源,对voxel中点的数量少于m数量的voxel直接忽略该voxel的创建。
3、在创建完Voxel Input Feature Buffer和voxel coordinate buffer后Stacked Voxel Feature Encoding就可以直接在点的基础上或者voxel的基础上进行平行计算。再经过VFE模块的concat操作后,就将之前为空的点的特征置0,保证了voxel的特征和点的特征的一致性。最后,使用存储在voxel coordinate buffer的内容恢复出稀疏的4D张量数据,完成后续的中间特征提取和RPN层。
五、代码阅读
数据预处理:先使用crop.py程序把图像坐标之外的点云剪裁掉便于后期可视化验证,在运行crop.py之前,需要先在training和testing文件夹下新建crop文件夹,运行完的数据存在里面。
根据标签数据构建3D框,在KITTIDatset里面,加载标签数据得到gt_box3d_corner(N,8,3), gt_box3d(N,7)
加载点云数据同时进行data_augment,然后utils.get_filtered_lidar筛选出指定空间范围内的点云和真实检测框顶点的坐标。self.preprocess(lidar)点云体素化返回体素特征voxel_features(Nx35x7)和体素坐标voxel_coords(Nx3),这两个送入网络得到预测输出,然后真实框和锚框送入dataset.cal_target计算真实偏移。然后求这两者的损失
5.1网络结构
import torch.nn as nn
import torch.nn.functional as F
import torch
from torch.autograd import Variable
from config import config as cfg
# conv2d + bn + relu
class Conv2d(nn.Module):
def __init__(self,in_channels,out_channels,k,s,p, activation=True, batch_norm=True):
super(Conv2d, self).__init__()
self.conv = nn.Conv2d(in_channels,out_channels,kernel_size=k,stride=s,padding=p)
if batch_norm:
self.bn = nn.BatchNorm2d(out_channels)
else:
self.bn = None
self.activation = activation
def forward(self,x):
x = self.conv(x)
if self.bn is not None:
x=self.bn(x)
if self.activation:
return F.relu(x,inplace=True)
else:
return x
# conv3d + bn + relu
class Conv3d(nn.Module):
def __init__(self, in_channels, out_channels, k, s, p, batch_norm=True):
super(Conv3d, self).__init__()
self.conv = nn.Conv3d(in_channels, out_channels, kernel_size=k, stride=s, padding=p)
if batch_norm:
self.bn = nn.BatchNorm3d(out_channels)
else:
self.bn = None
def forward(self, x):
x = self.conv(x)

本文详细介绍了VoxelNet,一种用于3D点云目标检测的深度学习框架。VoxelNet利用体素化和堆叠的VFE层提取特征,结合RPN网络进行目标检测。网络结构包括特征学习网络、中间卷积层和RPN层,损失函数基于分类和回归任务。此外,还讨论了数据增强策略和高效实现的堆叠VFE方法。代码实现部分展示了网络结构和损失函数的具体细节。
1万+

被折叠的 条评论
为什么被折叠?



