PointCNN原理是什么

PointCNN原理是什么

这篇文章主要介绍了PointCNN原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PointCNN原理是什么文章都会有所收获,下面我们一起来看看吧。

PointCNN的动机是这样的:

图中,小写字母f表示该点的特征,脚标相同的f表示对应点的特征也相同,作者告诉我们,图里有两个问题存在:

首先,假设一种情形,图ii和图iii是两种物体,但是,我们按照一定顺序排列,得到特征序列(fa,fb,fc,fd),碰巧这两个物体的特征还都一样,所以,这两种原本不同的物体,就被判定为同一种物体了。其次,另一种情形,图iii和图iv,从形状来看,本来是同一种物体,但是由于顺序选取不恰当,图iii的特征序列是(fa,fb,fc,fd),而图iv是(fc,fa,fb,fd),这就不好意思了,你俩不一样。

作者就觉得,这两种问题不解决,点云识别就做不好。所以,他想了个办法,训练一种变换,经过变换之后,让ii和iii的特征不同,让iii和iv的特征相同。这种变换怎么得到呢?用深度网络训练。作者将其命名为X-transformation。

接着,作者又再想了,图像处理领域的卷积操作,是对领域进行的,那在点云里,也可以使用这种思路啊,只要先找好领域就行了。最后就是这么实现的。

代码解释

下面是代码部分:


P.S.作者的Github维护的很好,经常更新,而且对读者的答疑也很及时,大赞。



看过代码的同学都知道,作者的核心思想X变换在代码pointcnn.py的xconv中,根据算法流程,可以把这部分代码划分成‘特征提取’和‘X矩阵训练’两块。下面分开来说。


用于提取邻域特征的只有两个dense层(也叫fc层/MLP),很简单地将尺度为(P,K,C)的邻域结构升维到了(P,K,C’)。


# Prepare featuresto be transformed
nn_fts_from_pts_0 =pf.dense(nn_pts_local_bn, C_pts_fts, tag + 'nn_fts_from_pts_0',is_training)#fc1, (N, P, K, C_pts_fts) nn_fts_from_pts =pf.dense(nn_fts_from_pts_0, C_pts_fts, tag + 'nn_fts_from_pt',is_training)#fc2, features, f_delta if fts isNone: nn_fts_input = nn_fts_from_pts else: nn_fts_from_prev = tf.gather_nd(fts,indices, name=tag + 'nn_fts_from_prev') nn_fts_input = tf.concat([nn_fts_from_pts,nn_fts_from_prev], axis=-1, name=tag + 'nn_fts_input')

接下来作者没有使用pointnet中的maxpooling,这一点论文中也提到了,因为作者认为训练出一个X变换来能达到更好的效果。


而关于X变换,居然有三层,第一层是卷积层,让人很吃惊,卷积核是1*k的,也就是在邻域维度上,直接把k个邻域点汇聚到一个点上,且用了K×K个卷积层,把特征维度升高到k*k,维度从(P,K,C)变成了(P,1,K×K);


ifwith_X_transformation:########################X-transformation#########################X_0=pf.conv2d(nn_pts_local,K*K,tag+'X_0',is_training,(1,K))X_0_KK=tf.reshape(X_0,(N,P,K,K),name=tag+'X_0_KK')X_1=pf.depthwise_conv2d(X_0_KK,K,tag+'X_1',is_training,(1,K))X_1_KK=tf.reshape(X_1,(N,P,K,K),name=tag+'X_1_KK')X_2=pf.depthwise_conv2d(X_1_KK,K,tag+'X_2',is_training,(1,K),activation=None)X_2_KK=tf.reshape(X_2,(N,P,K,K),name=tag+'X_2_KK')fts_X=tf.matmul(X_2_KK,nn_fts_input,name=tag+'fts_X')


紧接着,作者用了两个dense层,保持了这个结构


X_1 = pf.dense(X_0,K * K, tag + 'X_1', is_training, with_bn=False)#in the center point dimensional,P decrease to 1.

X_2 = pf.dense(X_1,K * K, tag + 'X_2', is_training, with_bn=False, activation=None)#(N, P, 1,K*K)

然后reshape成(P,K,K),这就得到了X-transporm矩阵。


X=tf.reshape(X_2,(N,P,K,K),name=tag+'X')

与上文得到的特征图进行卷积相乘。


fts_X=tf.matmul(X,nn_fts_input,name=tag+'fts_X')

最后是卷积操作,输出通道数为C,(1, K)尺度的卷积核用来把K邻域融合,此处有别于Pointnet++中的池化操作。

fts =pf.separable_conv2d(fts_X, C, tag + 'fts', is_training, (1, K),depth_multiplier=depth_multiplier)#输出(N, P, 1, C)

returntf.squeeze(fts, axis=2, name=tag + 'fts_3d')#输出(N, P, C)

注意这里用的不是普通卷积,而是可分卷积separable_conv2d。

关于“PointCNN原理是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“PointCNN原理是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道。

发布于 2022-01-14 22:30:27
收藏
分享
海报
0 条评论
25
上一篇:GVCNN的​网络结构是怎样的 下一篇:mnist数据集问题怎么解决
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码