Readme閱讀
代碼文件內(nèi)容
- X-conv及PointCNN架構(gòu):pointcnn.py
- 分類任務(wù)超參數(shù):pointcnn_cls.py
- 分割任務(wù)相關(guān):pointcnn_seg.py
關(guān)于 X-Conv 和 X-DeConv 的參數(shù)
- 以shapenet_x8_2048_fps.py 文件的代碼為例
xconv_param_name = ('K', 'D', 'P', 'C', 'links')
xconv_params = [dict(zip(xconv_param_name, xconv_param)) for xconv_param in
[(8, 1, -1, 32 * x, []),
(12, 2, 768, 32 * x, []),
(16, 2, 384, 64 * x, []),
(16, 6, 128, 128 * x, [])]]
xdconv_param_name = ('K', 'D', 'pts_layer_idx', 'qrs_layer_idx')
xdconv_params = [dict(zip(xdconv_param_name, xdconv_param)) for xdconv_param in
[(16, 6, 3, 2),
(12, 6, 2, 1),
(8, 6, 1, 0),
(8, 4, 0, 0)]]
xconv_params
- K:近鄰數(shù)
- D:膨脹率
- P:輸出代表點的數(shù)量(-1表示輸出輸入中的所有點)
- C:輸出通道數(shù)(深度)
- links:DesNet風(fēng)格的連接(元組形式妆丘,表示該層輸入包含倒數(shù)X層的輸出)
xdconv_params
- K锄俄,D:與上同
- pts_layer_idx :指定某層X-conv的輸出作為X-dconv的輸入
- qrs_layer_idx :指定某層X-conv的輸出與X-dconv輸出混合
PointCNN.py
X-conv結(jié)構(gòu)
def xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts, is_training, with_X_transformation, depth_multiplier,sorting_method=None, with_global=False):
函數(shù)參數(shù)
- pts:points
- fts:features
- qrs:queries
- K:近鄰數(shù)
- D:膨脹率
- P:點數(shù)目
- C:通道數(shù)(深度)
- with_X_transformation:是否需要X變換
_, indices_dilated = pf.knn_indices_general(qrs, pts, K * D, True)
indices = indices_dilated[:, :, ::D, :]
def knn_indices_general(queries, points, k, sort=True, unique=True):
queries_shape = tf.shape(queries)
batch_size = queries_shape[0]
point_num = queries_shape[1]
D = batch_distance_matrix_general(queries, points)
if unique:
prepare_for_unique_top_k(D, points)
distances, point_indices = tf.nn.top_k(-D, k=k, sorted=sort) # (N, P, K)
batch_indices = tf.tile(tf.reshape(tf.range(batch_size), (-1, 1, 1, 1)), (1, point_num, k, 1))
indices = tf.concat([batch_indices, tf.expand_dims(point_indices, axis=3)], axis=3)
return -distances, indices
def batch_distance_matrix_general(A, B):
r_A = tf.reduce_sum(A * A, axis=2, keep_dims=True)
r_B = tf.reduce_sum(B * B, axis=2, keep_dims=True)
m = tf.matmul(A, tf.transpose(B, perm=(0, 2, 1)))
D = r_A - 2 * m + tf.transpose(r_B, perm=(0, 2, 1))
return D
def prepare_for_unique_top_k(D, A):
indices_duplicated = tf.py_func(find_duplicate_columns, [A], tf.int32)
D += tf.reduce_max(D)*tf.cast(indices_duplicated, tf.float32)
- 涉及維度變化,不太理解
nn_pts = tf.gather_nd(pts, indices, name=tag + 'nn_pts') # (N, P, K, 3)
nn_pts_center = tf.expand_dims(qrs, axis=2, name=tag + 'nn_pts_center') # (N, P, 1, 3)
nn_pts_local = tf.subtract(nn_pts, nn_pts_center, name=tag + 'nn_pts_local') # (N, P, K, 3)
- 得到相對坐標(biāo)矩陣(第一步)
- nn_pts_local應(yīng)對應(yīng)于公式中P'
nn_fts_from_pts_0 = pf.dense(nn_pts_local, C_pts_fts, tag + 'nn_fts_from_pts_0', is_training)
nn_fts_from_pts = pf.dense(nn_fts_from_pts_0, C_pts_fts, tag + 'nn_fts_from_pts', is_training)
if fts is None:
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')
處理特征
- 從點云坐標(biāo)中提取特征(第二步)
- 將提取的特征和原有特征合并(第三步)
if with_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')
###################################################################
else:
fts_X = nn_fts_input
X變換矩陣
- 一層卷積+兩層深度可分卷積(不理解)
- 卷積核為(1勺拣,k)奶赠,將(N,P,K,3)提升至(N,P,K,K)(第四步)
- 將得到的X變換矩陣與特征矩陣相乘,得到可以直接與卷積核卷積的特征(第五步)
PointCNN架構(gòu)
train_val_cls.py
- 數(shù)據(jù)預(yù)處理(切片药有,亂序)
- 訓(xùn)練輪數(shù)毅戈,batch_size
- 數(shù)據(jù)增強
- tensorboard
-
準(zhǔn)確率與loss
- acc:總準(zhǔn)確率
- macc:每類平均準(zhǔn)確率