PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space 논문 리뷰

Heejun Park
21 min readJul 20, 2023

--

내일 랩미팅인데 아직 발표 준비를 못해서, 지난주 PointNet 리뷰 때 썸네일을 재활용 했습니다.😅

안녕하세요! 박희준입니다. 오늘은 PointNet++ 논문 리뷰를 진행하겠습니다. PointNet++은 2017년도 Neural Information Processing Systems (NIPS) 학회에 나온 나온 논문입니다. Impact Score는 2023년 기준 33.49를 자랑하는 명성 높은 학회입니다. PointNet++은 PointNet의 저자가 PointNet 다음으로 작성한 논문입니다. PointNet++의 많은 내용이 PointNet을 기반으로 하므로, PointNet을 아직 안 읽었다면, 아래 PointNet 논문 리뷰를 참고해주세요!

리뷰 영상을 보고 싶다면 아래의 영상을 봐주세요! 참고로 영상에서는 PointNet++의 모든 내용을 자세하게 담고 있지는 않습니다. 그래서 바쁜 분들에게 아래 영상을 추천 드립니다.

그럼 리뷰 시작하겠습니다! 👆

우선 목차에 대해 소개하겠습니다.

  1. PointNet의 문제점
  2. PointNet++ 소개
  3. PointNet++의 구조
  4. Robust Feature Learning under Non-Uniform Sampling Density
  5. Point Feature Propagation for Set Segmentation
  6. 실험 결과
  7. 결론 및 느낀 점
  8. 출처

1. PointNet의 문제점

PointNet++을 얘기하기 앞서 PointNet 얘기를 빠뜨릴 수 없죠. PointNet++은 PointNet의 단점을 보완하는 방향으로 연구가 진행되었습니다.

위 그림은 PointNet 네트워크의 구조입니다. PointNet은 3D Point Cloud 데이터의 Global Feature를 Fully Connected Layer들과 Max Pooling Layer를 사용하여 추출합니다. (앞으로 Fully Connected를 줄여서 FC라고 부르겠습니다.) 위 그림의 빨간색 박스로 표시한 부분이 하나의 Fully Connected Layer인데, 아래의 그림처럼 작동합니다. n x 3 크기의 입력 행렬이 있을 때, 각 행이 한 번에 한 번씩 FC Layer를 거칩니다. 그러면서 차원은 3에서 64로 늘어납니다. 이때, 출력 결과인 64 차원의 Feature는 각 점에 대한 활성화 정도를 의미합니다.

위 FC Layer를 거치면서 n x 64 크기의 행렬로 변환이 되고, 한 번 더 FC Layer를 거치면서 n x 1024 크기의 행렬이 출력됩니다. 그리고 n x 1024 크기의 행렬은 열 단위로 Max Pooling을 거치면서 1024 차원 벡터로 변환이 됩니다. 그리고 1024 차원 벡터는 FC Layer를 한 번 더 거치면서 Classification 결과가 출력됩니다.

지금까지 말로 설명한 내용을 아래의 식처럼 작성할 수 있습니다. h, γ는 FC Layer를 뜻하고 Max는 Max Pooling Layer를 의미합니다.

하지만, PointNet에는 문제 점이 있습니다. 각각의 Point가 h라는 FC Layer에 독립적으로 적용되므로, Point Cloud 데이터의 Local Structure를 효과적으로 추출하지 못한다는 단점이 존재합니다.

Local Structure를 추출하는 것은 생각보다 중요합니다. CNN을 예로 들겠습니다. CNN은 계층적인 구조를 통해 Local + Global Feature를 모두 담고 있는 출력물을 생성합니다. Global 정보 뿐만 아니라, Local 정보 역시 갖고 있게 되면, 처음 보는 이미지에 대해서도 예측을 더 잘할 수 있게 됩니다. 논문에서는 이런 특성을 Generalizability라고 하는데, 번역하면 ‘일반화 가능성’ 정도 되겠습니다.

2. PointNet++ 소개

Point Cloud 데이터의 Local Feature를 추출하기 위해, 계층적 구조를 갖는 인공 신경망인 PointNet++을 소개하겠습니다! 🥳

아이디어는 간단합니다. 겹치는 집합으로 Point들을 분할합니다. (논문에서는 Nested Partitioning을 사용한다고 나옵니다.) 이해를 돕기 위해 아래 그림을 봐주세요. 왼쪽에 Point Cloud가 있을 때, 오른쪽 그림과 같이 동그란 집합으로 Point들을 분할하겠다는 아이디어입니다.

동그라미 영역으로 분할을 하고나서, 각 영역으로부터 Local Feature가 추출 됩니다. 이렇게 영역을 분할하는 Layer가 계층적 구조로 여러개 쌓여있습니다. 그리고 PointNet++의 계층적 구조를 따르며 Local Feature는 더 큰 영역의 Local Feature를 담게 됩니다. 이런 과정은 하나의 영역이 (동그라미) 모든 Point Cloud를 담을 때까지 반복됩니다. 더 자세한 내용은 뒤에서 설명하겠습니다.

Point Cloud를 분할했다면, 각 영역으로부터 공통된 구조를 학습해야 합니다. 요기서 말하는 공통된 구조란, 제 생각에 네모, 세모, 동그라미, 선 등과 같이 3D Point Cloud 구조에서 흔히 보이는 특징을 말하는 것 같습니다. 이런 공통된 구조를 학습하기 위해 PointNet의 구조가 사용됩니다. PointNet은 순서가 없는 Point Cloud 점들을 학습하는 데 매우 유용하게 사용될 수 있는 네트워크입니다. 학습이 어떻게 이루어지는지는 뒤에서 자세하게 소개하겠습니다.

근데, Point Cloud를 분할하기 위해서는 하나의 구의 (Partition) 중심점과 (Centroid) 구의 크기를 (Scale) 결정해야 합니다. 중심점을 구하기 위해서는 Farthest Point Sampling (FPS) 알고리즘이 사용됩니다. FPS를 사용하면 아래 그림의 왼쪽과 같은 결과를 얻을 수 있습니다. 오른쪽에 있는 Random Point Sample 알고리즘에 비해 FPS 알고리즘을 사용한 결과의 밀도가 더 고른 것을 확인할 수 있습니다. FPS 알고리즘을 사용하면 원하는 수의 Point Cloud로 Down-sampling이 가능합니다. Down-sampling이란 신호처리 분야에서 데이터의 개수를 줄이는 과정을 의미합니다.

분할하고 싶은 영역의 Centroid는 FPS로 구합니다. 그럼 이제, 영역의 크기를 구하는 일이 남았죠? 이건 CNN에서 Kernel Size와 비슷한 개념입니다. VGG네트워크에서는 Kerel Size를 3으로 매우 작게 해서 엄청나게 좋은 성능의 Object Classification 결과를 얻을 수 있었습니다. 하지만, Point Cloud는 데이터의 데이터는 희소하므로 영역의 크기를 항상 작게 하면 안 됩니다. 즉, PointNet++에서 영역의 크기를 결정하는 것은 하나의 Hyperparameter가 됩니다. 이 내용과 관련해서는 뒤에서 더 자세하게 소개하겠습니다.

그리고 PointNet++에서는 Feature를 학습하기 위해 여러 계층의 영역의 데이터를 더해서 사용합니다. 이때, 어떤 계층에서 가져온 데이터에 얼만큼의 가중치를 줄지는 학습 됩니다. 자세한 내용도 뒤에서 설명하겠습니다.

3. PointNet++의 구조

위 그림은 PointNet++의 구조입니다. Local Feature 정보를 더 잘 추출하기 위해 PointNet과는 많이 다른 구조를 갖습니다. PointNet은 하나의 Max Pooling Layer를 사용해서 모든 Point Cloud의 정보를 종합했습니다. PointNet++의 구조는 점진적으로 더 큰 영역의 Local Feature 정보를 추출할 수 있는 계층적 구조를 갖습니다.

PointNet++의 구조는 Set Abstract Layer들로 구성됩니다. 각 Layer를 거치면서 더 적은 수의 점들이 출력됩니다. Set Abstract Layer의 입력으로는 N x (d + C) 행렬이 들어갑니다. 이때, N은 점들의 개수, d는 3차원 공간의 좌표, C는 Feature 정보를 의미합니다. Set Abstract Layer는 총 3개의 작은 Layer로 나뉘는데, 자세하게 설명하겠습니다.

3.1 Sampling Layer

Sampling Layer에서는 FPS 알고리즘을 사용해서 n개의 입력된 점 중에서 n’개의 점들을 샘플링합니다.

{x1, x2, …. , xn} -> {x1, x2, …. , xn’}

3.2 Grouping Layer

Grouping Layer로 입력되는 데이터는 두 가지입니다.

  1. N x (d + C)
  2. N’ x d

그리고 출력은 N’ x K x (d + C) 행렬입니다. K는 Centroid가 속하는 영역에 포함되는 점들의 개수를 의미합니다. 아래 그림에서 빨간색 원은 하나의 영역을 의미하고, 하늘색 점은 Centroid, 노란색 점은 영역안에 속한 다른 점을 의미합니다. 아래의 경우 K는 7입니다.

이때, 저 영역의 크기를 정하는 두 가지 방식이 존재합니다.

첫 번째 방식은 Ball Query 방식입니다. 반지름 크기를 정하고, Centroid 기준 반지름에 속하는 점들을 하나의 집합으로 간주하는 방식입니다. 아래 그림과 같습니다. radius를 10으로 잡은 거는 예시입니다.

두 번째 방식은 kNN입니다. k Nearest Neighbor 알고리즘을 사용한 방식이며, 그림은 아래와 같습니다. k를 5로 설정한 것은 예시입니다.

고정된 크기의 영역을 사용할 때 Point Cloud의 Local Structure 정보를 추출하기 더 용이합니다. 그래서 두 방식 중에서 Ball Query 방식이 사용되었습니다.

3.3 PointNet Layer

PointNet Layer의 입력값은 N’ x K x (d + C)입니다. 한 영역 안에 속한 K개의 점들의 좌표를 xi, 그리고 Centroid의 좌표를 kj라고 하겠습니다. 그러면 xi = xi - xj가 되면서 xi들은 xj 기준 상대 좌표로 변환됩니다. 예를 들어 x1 = (21, 20, 22), xj = (1, 1, 1)일 때, 아래의 과정을 거칩니다.

(20, 19, 21) = x1 - xj

모든 좌표가 Centroid 기준, 상대 좌표로 변환이 되고 Local Feature 정보를 구하기 위해서 PointNet 네트워크를 거칩니다. 이때 각각의 점들은 Fully Connected Layer를 독립적으로 거치게 됩니다. 그리고 출력된 Local Feature는 Max Pooling, Average Pooling 또는 Concatenation을 거치면서 N’ x (d + C’) 크기의 행렬로 출력됩니다. 이때 Centroid의 Local Feature 정보가 C에서 C’으로 늘어나게 된것을 확인할 수 있습니다.

4. Robust Feature Learning under Non-Uniform Sampling Density

갑자기 영어가 나와서 당황하셨죠? ‘밀도가 고르지 않은 상황에서의 강건한 Feature 학습’으로 번역이 되는데요. Point Cloud 데이터의 밀도는 고르지 않습니다. 밀도가 높은 Point Cloud을 학습한 네트워크는 밀도가 낮은 Point Cloud을 추론하는 데 어려움을 겪을 수 있습니다.

이러한 점을 극복하기 위해 논문에서는 Density Adaptive Layer를 소개합니다. 번역하면 ‘밀도 적응층’입니다. 밀도 적응층은 여러 Scale의 영역에서 Feature를 합치는 Layer입니다. 이때 해당 영역의 밀도에 따라서 여러 Scale의 Feature에 가중치를 달리 줍니다.

논문에서 두 가지 종류의 Density Adaptive Layer를 소개합니다. 뭔지 자세하게 소개하겠습니다.

4.1 Multi-Scale Grouping (MSG)

위에 그림은 MSG를 작동 방식을 그린 내용입니다. 다양한 Scale의 Feature가 연결되어 Multi-Scale Feature를 구성하는 방식입니다. 모델을 학습 단계에서 각 Scale에 Feature에 얼만큼의 가중치를 줘서 Multi-Scale Feature를 만들지 학습하게 됩니다. 그러기 위해서 Random Input Dropout 개념을 사용합니다. θ라는 Dropout 비율을 정합니다. 이때 θ는 아래의 부등식을 만족해야합니다.

0 ≤ θ ≤ 0.95

θ의 최대값을 0.95로 설정하는 것은, 1로 하면 Point Cloud의 모든 점들이 Dropout 될 위험이 있기 때문입니다. Random Input Dropout을 사용하므로써, PointNet++ 네트워크가 희소성 비율이 (Various Sparsity) 다양한 데이터셋을 학습할 수 있게 합니다. 또한, 밀도가 다양한 (Various Uniformity) 데이터셋을 학습할 수도 있습니다. 이걸 그림으로 설명하겠습니다.

Original Set에서 Dropout 비율을 달리 줘서 Various Sparsity와 Various Uniformity를 갖는 부분 집합을 만들 수 있는데요. 이렇게 다양한 데이터 셋으로 학습한 네트워크 강건해질 수 있습니다. 마치 Data Augmentation과 유사하다고 느꼈습니다. 그리고 너무나 당연한 얘기지만, 추론할 때는 Dropout을 사용하지 않습니다!

4.2 Multi-Resolution Grouping (MRG)

이전에 설명한 MSG 방식은 계산적으로 비용이 많이 듭니다. 특히, 첫 Set Abstraction Layer에서는 점들의 개수가 가장 많으므로 MSG를 수행하는 데 시간이 오래 걸립니다. 그래서 저자는 계산적으로 비용이 덜 더는 MRG 방식을 제안합니다. 그림은 아래와 같습니다.

MRG는 레벨 Li에서 두 개의 벡터가 연결되는 방식입니다. 첫 번째 벡터는 레벨 Li-1의 Subregion에서 추출된 여러개의 Feature를 ‘종합’한 결과물입니다. 제가 종합이라는 표현을 사용했는데, 논문에서는 ‘Summarize’라는 단어를 사용합니다. 두 번째 벡터는 레벨 Li-1에 속한 모든 점들로부터 Feature를 추출한 벡터입니다.

만약, Local Region에 있는 점들의 밀도가 낮다면, 두 번째 벡터에 가중치를 더 줘야합니다. 왜냐구요? 밀도가 낮다는 건, 정보가 부족하다는 것입니다. 그런 Local Region에 속한 Subregion들로부터 추출한 Feature는 사용하기 별로겠죠? 반대로 Local Region에 점들의 밀도가 높다면, 첫 번째 벡터에 더 많은 가중치를 줘야합니다. 왜냐하면, Subregion들에서 추출된 Feature의 정보는 Local Region의 미세한 정보를 담고 있기 때문이죠.

5. Point Feature Propagation for Set Segmentation

위 소제목의 뜻은 ‘Set Segmentation을 위한 점들의 Feature 전파’입니다. PointNet++에서는 Point Cloud 데이터가 Set Abstraction Layer를 거치면서 줄게 됩니다. 근데 Segmentation 작업의 결과는 입력된 모든 점들에 대해서 특정 클래스에 대한 레이블을 붙여줘야합니다. 즉, Set Abstraction Layer를 통해 없어진 점들을 복구하는 방법이 필요합니다.

단순한 방법으로는, Set Abstraction Layer에서 모든 점들을 Centroid로 지정하는 방법입니다. 하지만 이 방법은 계산량이 너무 많아집니다. 그래서 저자는 부분 샘플한 Feature로 원래의 점들을 복원하는 방법을 제안합니다. 이게 무슨 말이냐? 아래 그림을 참고해주세요. 아이디어는 단순합니다. 세 개의 점들의 Feature를 사용해서 파란색 위치에 있었던 점을 복원하겠다는 겁니다.

아래 그림에서 보이는 것 과 같이 복구 과정은 총 3개의 단계로 나뉩니다. 각 단계에 대한 설명을 자세하게 해보도록 하겠습니다.

5.1 Distance Based Interpolation

첫 번째 단계입니다. PointNet++의 계층적 구조에서 (위 그림의 왼쪽 부분) Nl-1의 점들의 수가 Set Abstraction Layer를 거치면서 Nl개로 줄어었습니다. 즉, 아래의 부등식을 만족합니다.

Nl < Nl-1

이제는 Nl개의 점들을 사용해서 Nl-1개의 점들을 역으로 복구하는 과정을 그림으로 설명하겠습니다! 아래 그림은 PointNet++의 계층적 구조의 Set Abstraction Layer 중 하나입니다. N1개의 점들이 입력되어 최종적으로 N2개의 점들이 출력됩니다. (N1 > N2)

이제는 역으로 N2개의 점들로 N1개의 점을 복구하려고 합니다. 복구한 결과가 아래의 그림입니다.

이때, 복구하려는 점 기준으로 가장 가까운 3개의 점을 사용하게 되는데요. 아래 그림을 봐주세요. 3개의 점이 있습니다. 그리고 파란색 점을 복구하려고 합니다. 이때, 파란색 점과 노란색 점들과의 거리를 구합니다. 총 3개의 거리가 계산되는데요. 계산한 거리에 역수를 취한 것을 wi(x)이라고 합니다. 예를 들어 w1(x)는 첫 번째 점과 파란점 사이의 거리의 역수.

자 이제 아래의 식을 봐주세요. 아래의 식은 Inverse Distance Weighting Interpolation 알고리즘을 수식으로 정리한 내용입니다. 아래 식에서 p는 2로 두 점 간의 거리를 구할 때 사용되며, k는 3으로 3개의 점을 의미합니다. 지금까지 아래 식의 오른쪽의 결과인 wi(x)를 구하는 방법에 대해 얘기했었죠? 이제 아래 식의 왼쪽을 구하면 됩니다. 요기서 fi는 i번째 점의 Feature 벡터를 의미합니다.

이해되셨죠?! 제가 그림을 갖고 정말 설명을 잘합니다. 그래서 Inverse Distance Weighting Interpolation 알고리즘으로 구한 건 다음과 같습니다. 구하고 싶은 점과 (파란점) 다른 점들의 (노란점들) 거리에 반비례하게 가중치를 준 다음에, 구하고 싶은 점의 Feature를 복구한 것입니다.

5.2 Skip Link Concatenation with Features from Set Abstraction Layer

이름이 길죠? ResNet의 Skip Connection과 비슷합니다. ResNet의 Skip Connection이 뭔지 모른다고요? 괜찮습니다. 위 그림을 봐주세요. 빨간색 점선 박스로 표시한 Set Abstraction Layer에 입력되는 점의 개수가 N1개입니다. 그리고 각 점들은 (d + C1) 차원의 Feature를 갖고 있습니다. 이걸 Skip Link를 사용해서 오른쪽 빨간색 점선 박스로 표시된 (d + C2) 차원의 Feature에 이어줄 겁니다. 즉, 아래의 식처럼 되는 것이죠.

N₁ x (d + C₂) + N₁ x (d + C₁) = N₁ x (d + C₁ + C₂)

5.3 Pass Through Unit Pointnet

위에 소제목을 번역하면, ‘Unit PointNet을 거친다’입니다. 방금까지 N₁ x (d + C₁ + C₂)를 구했죠? 이걸 N₁ x (d + C₃)로 변환하는 작업입니다. 쉽게 얘기해서, 각 점들의 Feature의 차원 수를 (d + C₁ + C₂)에서 (d + C₃)로 줄이는 과정이라고 보면 됩니다. Unit PointNet은 Fully Connected Layer로 구성되어 있고, Batch Normalization과 ReLU 활성화 함수가 적용됩니다. 자세한 구조는 논문의 뒷편에 있는 Supplementary Section B.1을 참고하세요.

설명이 드디어 끝났습니다. 원래 Point Cloud의 개수인 N이 모두 복구될 때까지 5.1, 5.2, 5.3 과정이 반복됩니다.

6. 실험 결과

6.1 MNIST Digit Classification

상상도 못한 실험입니다. 2D 데이터인 MNIST를 PointNet++로 분류했습니다. MNIST에서 총 512개의 Point Cloud를 추출해서 실험했다고 합니다. Error Rate을 보면 PointNet++이 0.51로 표에서는 2등을 기록했습니다.

6.2 ModelNet40 Shape Classification

ModelNet40이라는 3D Mesh 데이터셋으로 실험한 내용입니다. Mesh 데이터의 표면으로부터 총 1024개의 Point Cloud를 추출해서 PointNet++을 학습했습니다. 성능이 가장 좋게 나온 것은 PointNet++과 법선 벡터를 활용한 모델입니다. 법선 벡터가 어떻게 사용되었느지는 잘 이해가 안 갑니다.

6.3 Robustness to Sampling Density Variation

SSG (Single Scale Grouping), MSG (Multi-Scale Grouping), MRG (Multi-Resolution Grouping), DP (Dropout)에 대한 Ablation 실험이라고 보면 되겠습니다. 위 그림에서 왼쪽 사진은 임의로 점들을 제거해 나갈 때 의자의 모습 변화입니다. 위 그림에서 오른쪽 그래프는 임의로 Point를 제거했을 때의 성능에 변화를 보여줍니다. SSG만을 사용했을 때는 성능이 좋지 못합니다. 하지만 DP로 다양한 밀도의 Point Cloud 부분 집합으로 학습했을 때는 좋은 결과를 보여줍니다. PointNet+DP, MSG+DP, MRG+DP는 점들이 1024개에서 128개로 줄었을 때도 85%에 가까운 성능을 보여줍니다. 즉, DP는 좋다!

6.4 Point Set Segmentation for Semantic Scene Labeling

Semantic Segmentation 결과입니다. 파란색 막대는 ScanNet 데이터를 사용한 실험 결과입니다. 그리고 노란색 막대는 밀도가 고르지 못한 ScanNet 데이터셋을 갖고 진행한 실험 결과입니다. 실제로 LiDAR 센서를 갖고 3D 스캔을 하면 Point Cloud 데이터의 밀도가 고르지 않습니다. 그래서 이런 실험은 정말 좋은 실험인 것 같습니다. PointNet++(MSG+DP)를 사용할 때 가장 좋은 성능이 나옵니다. 아래 그림은 PointNet, PointNet++의 추론 결과와 Ground Truth를 Visualization한 그림입니다.

PointNet++이 Ground Truth와 매우 유사합니다.

7. 결론 및 느낀 점

7.1 결론

  • PointNet++은 Point Cloud 데이터를 처리할 수 있는 강력한 Neural Network입니다.
  • 다양한 3D 벤치마크 데이터셋에서 State-of-the-art 성능을 보였습니다.
  • 미래에는, 속도를 올리는 방향으로 연구를 진행할 것이라고 저자는 얘기합니다.

7.2 느낀 점

  • 논문을 읽는 게 너무 어려웠습니다. 쉽게 풀어서 설명해주면 좋을텐데, 모든 말을 참 어렵게 설명했습니다.
  • Ablation 실험을 할 때 쫌 더 다양한 실험 결과를 보여줬었으면 좋았을 것 같습니다. 얘를 들어서, Section 6.3에서 MSG와 MRG만 학습해서 보여준 실험 결과가 있었다면 좋았을 것 같습니다.
  • 저 역시, PointNet과 PointNet++의 추론 속도를 높일 수 있는 방안에 대해서 생각을 해보겠습니다.

8. 출처

  • PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space, Charles R. Qi et al., 2017–06–07
  • PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation 논문 리뷰, 박희준, 2023–07–14
  • [paper review] PointNet++ 논문 리뷰, 소소한 개발자의 끄적거림, 2022–12–01
  • Furthest Point Sampling, Mini-batch AI, 2021–08–07

--

--

Heejun Park

3D Vision Enthusiast @ KAIST Visual Intelligence Lab. Here's a link to my GitHub page https://github.com/parkie0517