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原理是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道。
推荐阅读
-
polyfills怎么按需加载
polyfills怎么按需加载本篇内容主要讲解“polyfills...
-
C#数据类型怎么实现背包、队列和栈
-
C#怎么实现冒泡排序和插入排序算法
C#怎么实现冒泡排序和插入排序算法这篇文章主要讲解了“C#怎么实现...
-
C#如何实现希尔排序
-
C#如何实现归并排序
-
C#怎么使用符号表实现查找算法
-
C#类的静态成员怎么用
C#类的静态成员怎么用这篇“C#类的静态成员怎么用”文章的知识点大...
-
C#的静态函数怎么用
C#的静态函数怎么用这篇文章主要讲解了“C#的静态函数怎么用”,文...
-
C#中的析构函数怎么用
C#中的析构函数怎么用这篇文章主要讲解了“C#中的析构函数怎么用”...
-
怎么用CZGL.ProcessMetrics监控.NET应用