점 클라우드 딥러닝 시리즈 2 - PointNet/PointCNN 코드 비교(변환 매트릭스 부분)

PointNet과 PointCNN은 문장부터 코드까지 비슷한 점이 많은데 둘을 비교해 보면 우리가 이해하는 데 도움이 될 수도 있다.
PointNet에서 maxpooling과 T-net을 사용한 것으로 알려져 있다. 저자의 글에서 관건적인 역할을 하는 것은 maxpooling이다. T-net이 성능 향상에 기여하는 역할도 있다. (두 개의 T-net에 Regularization이 2.1%포인트 기여했다) 그런데 이상하게도 PointNet++의 코드에서 T-net을 볼 수 없다.
그러나 이와 비슷한 PointCNN에는 X변환 행렬이 있지만 X변환은 PointCNN의 역할에 매우 중요하다. 왜냐하면 이것은 maxpooling도 소용없기 때문이다.다음에 우리는 둘을 비교할 것이다.
먼저 PointNet의 T-net 코드가 있습니다.
 
def feature_transform_net(inputs, is_training, bn_decay=None, K=64):
    """ Feature Transform Net, input is BxNx1xK
        Return:
            Transformation matrix of size KxK """
    batch_size = inputs.get_shape()[0].value
    num_point = inputs.get_shape()[1].value

    net = tf_util.conv2d(inputs, 64, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='tconv1', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 128, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='tconv2', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 1024, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='tconv3', bn_decay=bn_decay)
    net = tf_util.max_pool2d(net, [num_point,1],#     [num_point,1]
                             padding='VALID', scope='tmaxpool')

    net = tf.reshape(net, [batch_size, -1])#    
    net = tf_util.fully_connected(net, 512, bn=True, is_training=is_training,
                                  scope='tfc1', bn_decay=bn_decay)
    net = tf_util.fully_connected(net, 256, bn=True, is_training=is_training,
                                  scope='tfc2', bn_decay=bn_decay)

    with tf.variable_scope('transform_feat') as sc:
        weights = tf.get_variable('weights', [256, K*K],
                                  initializer=tf.constant_initializer(0.0),
                                  dtype=tf.float32)
        biases = tf.get_variable('biases', [K*K],
                                 initializer=tf.constant_initializer(0.0),
                                 dtype=tf.float32)
        biases += tf.constant(np.eye(K).flatten(), dtype=tf.float32)
        transform = tf.matmul(net, weights)
        transform = tf.nn.bias_add(transform, biases)

    transform = tf.reshape(transform, [batch_size, K, K])
    return transform

코드 테마 부분, 앞의 세 개의 conv2d는 차원 상승에 사용되고, 이어서 maxpool2d는 1024개의 점의 특징을 maxpooling으로 만들어 점으로 융합시켰다.그리고 두 fully와...connected는 차원을 256로 낮추고 [256, K*K]의 권치와 곱한 다음에 K*K비트의 편이를 더해서 [batch size, K*K]에 이르면 마지막에 [batch size, K, K]가 형성되고 대공을 이루기가 쉽지 않아요.PointCNN의 X 변환을 살펴보겠습니다.
 
       ######################## X-transformation #########################
        X_0 = pf.conv2d(nn_pts_local_bn, K * K, tag + 'X_0', is_training, (1, K), with_bn=False)
        #kernal size(1, K, 3), kernal num=K*K, so the output size is (N, P, 1, K*K). so this operator is in the neighbor point dimentional.
        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)
        X = tf.reshape(X_2, (N, P, K, K), name=tag + 'X')
        fts_X = tf.matmul(X, nn_fts_input, name=tag + 'fts_X')
        ###################################################################

1층은 권적층이다. 사람을 놀라게 한다. 권적핵은 1*k이다. 즉, 이웃 차원에서 k개의 이웃 점을 한 점에 모으고 K를 사용했다.×K개의 권적층은 특징 차원을 k*k로 높여 차원(P,K,C)에서 (P,1,K로 바뀌었다×K);그리고 작가는 두 개의 dense층을 사용하여 이 구조를 유지했다.마지막으로 reshape성(P,K,K)은 X-transporm 행렬을 얻었다.
 
 
체량과 복잡도를 보면 후자가 이긴다.
 
 
작용 효과로 볼 때 그다지 평가하기 어렵다.PointCNN은 국부적인 특징이 있기 때문에pointnet++사상과 일치한다.그래서 PointCNN의 성능이 PointNet을 능가한다고 해서 X-transporm이 T-net보다 우수하다는 것을 직접적으로 증명할 수는 없다.
코드는 사실 T-net의 전 4층과 X변환의 1층이 하는 일은 차이가 많지 않다. 모두 여러 점의 특징을 한 조의 특징에 융합시켜 변환 행렬을 훈련하는 데 소재를 제공하기 위해서다.그러나 그 다음은 다르다. T-net은 K*K의 weights 권한이 한 그룹뿐이고 PointCNN은 뒤에 두 개의 dense층이 뒤따랐다. 차원이 모두 K*K이고 파라미터가 더 많기 때문에 PointCNN의 훈련 변환 행렬이 더욱 충분할 것으로 추정된다.후기에는 실험을 통해 다음과 같은 것을 검증할 수 있다.
마지막으로 비뚤어진 건물에서 PointNet++의 코드를 테스트할 때 모델Net40의 분류 결과는 90.1 정도를 맴돌았고 논문에서 제시한 90.7에 이르지 못했으며 작가와 메일로 연락해도 좋은 답을 얻지 못했다.그래서 작가 본래의 PointNet++ 코드에 T-net이 있는 건 아닌지 생각했지만github에 넣은 버전은 추가하지 않았습니다.그러나 이는 추측일 뿐 검증이 필요하다.
관련 코드를 첨부한 링크:
PointNet2:https://github.com/charlesq34/pointnet2
PointCNN:https://github.com/yangyanli/PointCNN

좋은 웹페이지 즐겨찾기