【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。
参考书籍:《人工智能点云处理及深度学习算法》
本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“https://blog.csdn.net/suiyingy/article/details/124017716”。配套书籍《人工智能点云处理及深度学习算法》提供更加全面和系统的解析。
1 模型结构
DGCNN发表于TOG 2019《Dynamic Graph CNN for Learning on Point Clouds》,论文地址为“https://arxiv.org/abs/1801.07829”。从论文题目上来看,模型似乎采用了图神经网络(GCN)。DGCNN中的图实际上是指运用点与点之间相对特征来进行点云特征提取,提取方式仍然采用的是卷积网络。因而,模型并没有采用图神经网络。
DGCNN的创新点在于点云特征提取时不仅考虑点自身的特征,而且融合了周围点云的相对特征。周围点云相对特征通过EdgeConv卷积来实现。相比于PointNet++模型而言,该模型进一步关注了点云的局部特征,使点云特征提取更加丰富有效,从而提高算法复杂度。DGCNN发布时在点云分割、分类任务中取得了最优水平。
DGCNN模型的总体结构如下图所示,其主要思路与PointNet++基本一致,包括了最大池化和全局特征拼接等步骤。两者区别在于DGCNN在MLP提取点云特征时使用了周围点云的相对特征。
图DGCNN模型结构
2 EdgeConv卷积
EdgeConv卷积结构如下图所示,重点用于提取边(edge)特征。PointNet中分组点云特征通过对输入特征分别进行MLP操作得到。EdgeConv输入增加了对点云相对于中心点的特征,从而使得输入特征的局部信息更加丰富。
图 EdgeConv
EdgeConv卷积过程如下:
- 尽量点云分组:采用最近邻方法(KNN)搜索最近的K个点作为相邻点。如果输入点云特征中包含空间坐标信息,那么KNN是采用坐标距离作为相邻点选择依据,否则以全部特征距离作为选择依据。假设输入点云维度为Cin x npoint,那么分组后点云特征维度为Cin x npoint x K。
- 中心相对特征提取:将分组内点云特征减去分组中心点特征,得到点云相对中心特征,维度为Cin x npoint x K。
- 特征拼接:点云原始输入特征与中心相对特征进行拼接,得到(2 x Cin)x npoint x K维度特征。
- MLP特征提取:MLP层第一个卷积的输入通道数为2 x Cin,最后一层卷积输出通道数量为Cout,那么上述拼接特征经过MLP操作后得到Cout x npoint x K维度特征。
- 最大池化:Cout x npoint x K维度特征经最大池化后输出Cout x npoint维度特征。最大池化将分组内特征融入进中心点中,同时解决了分组内点云无序性问题。
- 深层特征提取:连续EdgeConv串联起来实现深层特征提取,可类比连续传统卷积操作。
3 主干网络
DGCNN模型主干网络结构采用了3个连续的EdgeConv卷积模块提取不同深度特征,并采用特征拼接实现不同深度特征的融合。模型输入点云维度为4096x9,9个属性维度介绍请参考PointNet++章节。
3.1 EdgeConv1
第一个EdgeConv卷积模块的输入维度为4096x9,后三维特征为空间坐标,因而采用距离KNN的方式来选择最近邻点。分组最近邻点数量为20。分组后点云特征维度为9x4096x20,与中心点作差得到维度同样为9x4096x20的中心相对特征。两者拼接后得到18x4096x20维度特征,经过MLP卷积Conv2d(18, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)、Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)及最大池化后输出64x4096维度特征。
关键程序解析如下所示:
idx = self.groupers[i](new_points[..., -3:].contiguous(), new_points[..., -3:].contiguous())[-1]#根据距离KNN筛选K个最近邻点,N x K,4096x20
grouped_results = grouping_operation(new_points_trans, idx) # (B, C, N) -> (B, C, N, K)#分组,9x4096x20
grouped_results -= new_points_trans.unsqueeze(-1)#与中心点特征的差值,C x N x K,9x4096x20
new_points = new_points_trans.unsqueeze(-1).repeat(1, 1, 1, grouped_results.shape[-1])#中心点特征,9x4096x20
new_points = torch.cat([grouped_results, new_points], dim=1)#特征拼接,(2 x C)x N x K,18x4096x20
# (B, mlp[-1], N, K)
new_points = self.mlps[i](new_points)#64x4096x20
# (B, mlp[-1], N)
new_points = self._pool_features(new_points)#最大池化,64x4096
#MLP
DGCNNGFModule(
(groupers): ModuleList(
(0): QueryAndGroup()
)
(mlps): ModuleList(
(0): Sequential(
(layer0): ConvModule(
(conv): Conv2d(18, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(activate): LeakyReLU(negative_slope=0.2, inplace=True)
)
(layer1): ConvModule(
(conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(activate): LeakyReLU(negative_slope=0.2, inplace=True)
)
)
)
)
3.2 EdgeConv2
第二个EdgeConv卷积模块的输入是第一个EdgeConv的输出,维度为4096x64,特征不含点云坐标,因而采用全部特征KNN的方式来选择最近邻点。分组最近邻点数量为20。分组后点云特征维度为64x4096x20,与中心点作差得到维度同样为64x4096x20的中心相对特征。两者拼接后得到128x4096x20维度特征,经过MLP卷积Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)、Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)及最大池化后输出64x4096维度特征。
3.3 EdgeConv3
第三个EdgeConv卷积模块的输入是第二个EdgeConv的输出,维度为4096x64,特征不含点云坐标,因而采用全部特征KNN的方式来选择最近邻点。分组最近邻点数量为20。分组后点云特征维度为64x4096x20,与中心点作差得到维度同样为64x4096x20的中心相对特征。两者拼接后得到128x4096x20维度特征,经过MLP卷积Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)及最大池化后输出64x4096维度特征。
三个EdgeConv卷积模块均输出64x4096三个维度特征。DGCNN主干网络最终输出特征gf_points,包括原始点云特征和EdgeConv特征,特征维度分别为4096x9、4096x64、4096x64、4096x64。
3.4 特征融合与结果预测
三个EdgeConv特征进行拼接得到192x4096维度特征,经过卷积Conv1d(192, 1024, kernel_size=(1,), stride=(1,), bias=False)和最大池化后得到1024维全局特征。由于示例程序仅包含语义分割任务,因而全局特征不包含来自分类网络的全局特征,即少了模型结构中的Categorical vector部分。
全局特征与三个EdgeConv特征再次拼接得到1216x496维度特征。该特征作为点云语义特征,相当于为每个输入点提取到1216维特征,并用该特征来预测语义类别。
点云语义特征(1216x4096)经过卷积: Conv1d(1216, 512, kernel_size=(1,), stride=(1,), bias=False)、Conv1d(512, 256, kernel_size=(1,), stride=(1,), bias=False)和Conv1d(256, 13, kernel_size=(1,), stride=(1,))得到13x4096维预测结果。每个点分别对13个类别进行预测。
关键示例程序及参数配置如下所示。
#特征融,Point feature aggregation module
fa_points = self.FA_module(gf_points)
new_points = torch.cat(points[1:], dim=-1)#4096x64x3,4096x192,不同网络深度特征进行拼接融合
new_points = new_points.transpose(1, 2).contiguous() # (B, C, N),192x4096
new_points = self.mlps(new_points)#1024x4096
new_fa_points = new_points.max(dim=-1, keepdim=True)[0]#最大池化,1024x1
new_fa_points = new_fa_points.repeat(1, 1, new_points.shape[-1])#1024x4096,全局特征
new_points = torch.cat([new_fa_points, new_points_copy], dim=1)#全局特征与局部特征拼接,1216x4096
fp_points = self.FP_module(fa_points)#4096x512
fp_points = fp_points.transpose(1, 2).contiguous()#512x4096
output = self.pre_seg_conv(fp_points)#256x4096
output = self.cls_seg(output)#13x4096
DGCNNHead(
(loss_decode): CrossEntropyLoss(avg_non_ignore=False)
(conv_seg): Conv1d(256, 13, kernel_size=(1,), stride=(1,))
(dropout): Dropout(p=0.5, inplace=False)
(FP_module): DGCNNFPModule(
(mlps): Sequential(
(layer0): ConvModule(
(conv): Conv1d(1216, 512, kernel_size=(1,), stride=(1,), bias=False)
(bn): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(activate): LeakyReLU(negative_slope=0.2, inplace=True)
)
3.5 损失函数
DGCNN模型损失函数仅包含语义分割损失,损失函数类型为CrossEntropyLoss,语义预测损失函数为CrossEntropyLoss,其输入为13x4096维预测结果和4096个语义标签pts_semantic_mask。
3.6 顶层结构
DGCNv模型顶层结构主要包括以下两部分:
- 主干网络特征提取,采用三个EdgeConv卷积模块提取三组不同尺度特征,见第(3)部分。
- 语义分割结果预测,包括特征融合、语义预测和语义分割损失函数计算,见第(4)部分。
def forward_train(self, points, img_metas, pts_semantic_mask):
points_cat = torch.stack(points)#输入点云坐标及属性 4096x9
pts_semantic_mask_cat = torch.stack(pts_semantic_mask) #输入点云语义类别标签,即每个点所属类别
# extract features using backbone
x = self.extract_feat(points_cat)
losses = dict()
loss_decode = self._decode_head_forward_train(x, img_metas, pts_semantic_mask_cat)
losses.update(loss_decode)
return losses
4 模型训练
DGCNN模型官方程序地址为“https://github.com/zhangjian94cn/dgcnn”,而本节基于mmdetection3d框架中的实现程序进行介绍,其输入数据集为S3DIS。模型训练命令为“python tools/train.py configs/dgcnn/dgcnn_32x4_cosine_100e_s3dis_seg-3d-13class-area1.py”。运行训练命令可得到如图所示训练结果。
5【python三维深度学习】python三维点云从基础到深度学习_python3d点云从基础到深度学习-CSDN博客
【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。
更多python与C++技巧、三维算法、深度学习算法总结、大模型请关注我的博客,欢迎讨论与交流:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。Python三维领域专业书籍推荐:《人工智能点云处理及深度学习算法》。
本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“https://blog.csdn.net/suiyingy/article/details/124017716”。配套书籍《人工智能点云处理及深度学习算法》提供更加全面和系统的解析。