https://arxiv.org/abs/2304.00690

 

3D Semantic Segmentation in the Wild: Learning Generalized Models for Adverse-Condition Point Clouds

Robust point cloud parsing under all-weather conditions is crucial to level-5 autonomy in autonomous driving. However, how to learn a universal 3D semantic segmentation (3DSS) model is largely neglected as most existing benchmarks are dominated by point cl

arxiv.org

 

 

🤔 Main Contribution

1. SemanticSTF

21개의 Semantic category에 대한 고품질 point별 annotation을 제공하는 대규모 악천후 point cloud Benchmark.


2. PointDR

향후 전천후조건에서 3DSS연구 및 Benchmark에 활용가능한 point cloud domain randomization의 baseline

3. Leveraging SemanticSTF

SemanticSTF를 활용해 아래 2가지 까다로운 작업에서 활용.

① Domain Adaptive 3DSS: DA를 3DSS에 적용한 첫 사례.

② Domain Generalization 3DSS

cf) Leveraging = 효과적으로 활용하다 (leverage는 지렛대를 활용하다라는 의미로 효과적으로 활용함을 의미함..)

 

 

[Summary]:

① Level-5 자율주행을 위해 악조건 point cloud에서의 일반화모델(= Robust한 전천후 3DSS모델) 학습이 목표.

이를 위해 악천후 날씨에서의 Robust point cloud parsing을 위한 밀도높은 3DSS point-wise annotation Dataset이 필요.

→ SemanticSTF Benchmark를 제공.

 

Robust한 전천후 3DSS모델가 필요한데, 2가지 문제점이 존재함. (perturbation invariant해야함.)

  Problem 1) LiDAR point cloud는 sparse, incomplete, 기하학적 변형 및 의미론적 모호성의 영향을 받음.
  Problem 2) 눈보라, 빛방울 등으로 인해 악천후에서 더 많은 Noise가 도입됨

 

③ Sol) PointDR: Domain Randomization Technique의 한 방식.

 목표 1) 다양한 기상조건에서 동일한 범주의 point를 안정적으로 표현
 목표 2) 범주간의 구별가능한 강력한 3D Representation을 학습.

 

④ PointDR설계방식:

i) Geometry Style Randomization: 다양한 공간 증강하에 point cloud의 기하학적 분포를 확장.
ii) Embedding Aggregation: 무작위로 증강된 point cloud의 encoded embedding을 집계하기 위해 contrastive learning을 도입.

 

 

 

 

🤔 논문 읽기! by. Andrew Ng.

① Title / Abstract / Figure 및 Experiment 1~2개

∙ Title:

3D Semantic Segmentation in the Wild: Learning Generalized Models for Adverse-Condition Point Clouds

3D Semantic Segmentation을 활용.
악조건 point cloud에서의 일반화모델 학습이 목표인 것을 알 수 있음.





∙ Abstract:

[개념] Robust Point Cloud Parsing:

전천후 환경에서 level-5의 자율주행에 매우 중요함.

[선행 연구]

다만, 기존 Benchmark는 정상날씨에서 포착된 Point Cloud였음.

 

[본 연구]:

1. SemanticSTF Dataset

Robust Point Cloud Parsing을 위해 밀도높은 point-level(= point-wise) annotation 및 악천후의 3DSS를 연구하기 위한 SemanticSTF Dataset을 제안.

① Domain Adaptive 3DSS: 정상날씨 data → 악천후 data

② Domain Generalizable 3DSS: 정상에서 전천후 3DSS모델을 학습, 악천후에 적용

 

2. [PointDR]: Domain Randomization Techique  

① Geometry Style Randomization: point cloud의 기하학적 스타일을 다른방식으로 random화.

② Embedding Aggregation: 위의 embedding을 모으고, 궁극적으로 일반화가능한 모델을 도출함.

∴ 다양한 악천후에서 효과적인 3DSS!



cf) Background & 용어설명.

∙ 3DSS: 3D Semantic Segmentation

 Point Cloud: sensor등으로 물체의 표면을 측정해 x, y, z로 물체의 앞뒤,좌우,위아래 (최소 3차원)의 point로 나타내는 것.
즉, 비행시간으로 이동거리와 등록된 센서와 표적간 각도정보를 결합해 3D모양을 포착, 표면의 3D좌표를 계산하는 방식.

 Perturbation Invariance: 섭동불변 = 시스템이 외부 변동에 대해 얼마나 민감한지를 나타내는 것.
즉, "perturbation invariant" = "외부변동에 민감하지 않음" 을 의미.

 All Weather: 전천후 날씨를 의미.


[Adverse Weather]: --> 지면유형을 식별하기 어렵게해 무효영역이 상당부분 포함됨.
- Snow: 두꺼운 눈 덮인 범위가 물체 변형으로 이어질 수 있음.
- Rain: 지상의 물에서 Laser Signal의 "정반사"를 유발할 수 있음.

- Dense Fog: LiDAR 센서의 작동범위를 크게 감소시킴.
- Light Fog: 보통날씨와 유사한 특성을 가짐.

 

 

 

 

 

 

 

 

∙ Introduction:

선행연구들: 거의 다 정상날씨 or Detection Benchmark로 point-wise annotation이 없었음.
point-wise annotation은 매우 어려운 작업: 무효영역이 상당부분 포함되게됨.
 i) 3D view change
ii) point cloud와 사람간의 인식차이
iii) point sparsity
iv) sweeping occlusion

Contribution 1. SemanticSTF

이를 위해 SemanticSTF를 제공→자율주행에 자주 발생하는 4가지 악천후(짙은/옅은안개, 눈, 비)조건으로 포착.
아래 그림처럼 21개의 Semantic Category에 대한 point-wise annotations를 제공.
SemanticSTF는 악천후조건에서 3DSS와 Robust point cloud parsing을 위한 Benchmark를 제공.

[활용방안]: 기상에 강한 3DSS연구에 활용가능.
 i) 정상날씨 Data → 악천후 Data로의 DA 3DSS
ii) 정상날씨에서 전천후조건에 대해 학습하는 DG 3DSS모델.


Contribution 2. PointDR

Robust한 전천후 3DSS가 필요 --> 2가지 문제점이 존재함.
  Problem 1) LiDAR point cloud는 sparse, incomplete, 기하학적 변형 및 의미론적 모호성의 영향을 받음.
  Problem 2) 눈보라, 빛방울 등으로 인해 악천후에서 더 많은 Noise가 도입됨
이를 위해 아래와 같은 해결책을 도입함

[How to Solve? & Make Robust All Weather 3DSS] -> Domain Randomization Technique
sol) [PointDR]: 전천후 3DSS연구 및 Benchmarking을 위한 새로운 Framework.
 목표 1) 다양한 기상조건에서 동일한 범주의 point를 안정적으로 표현
 목표 2) 범주간의 구별가능한 강력한 3D Representation을 학습.

[PointDR 설계방식]
i) Geometry Style Randomization: 다양한 공간 증강하에 point cloud의 기하학적 분포를 확장.
ii) Embedding Aggregation: 무작위로 증강된 point cloud의 encoded embedding을 집계하기 위해 contrastive learning을 도입.



∙ Conclusion:

본논문: SemanticSTF(악천후조건 = 짙은∙옅은안개, 눈, 비)에서 LiDAR Point Cloud와 Annotation으로 Semantic Segmentation을 위한 대규모 Benchmark Dataset을 소개.

PointDR의 설계: Domain Randomization Technique
 - 목표: 
   i) 정상날씨 point cloud를 사용해
  ii) 악천후 point cloud에서 잘 작동할 수 있는
 iii) Domain Generalizable 3DSS Model을 훈련하는 것.

- 설계방식: 
  i) Geometry Style Randomization
 ii) Embedding Aggregation
→ 다양한 새로운 point cloud domain에서 "잘 일반화 되는" "섭동불변표현"을 공동으로 학습.



∙ Related Works

3D Semantic Segmentation

선행연구:
 - CNN기반, projection-based method
 - MLP기반 신경망
 - 3D Voxel CNN기반 신경망
 - Hybrid 신경망

기존의 3DSS신경망:
주로 정상날씨 point cloud대상으로 평가.
SemanticSTF: 해당 간극(정상,악천후)을 메우고, 전천후 3DSS의 연구 및 평가를 위한 견고한 baseline을 제공함.


Vision Recognition under Adverse Conditions

최근: 2D는 많으나 3D, 특히 point cloud학습은 포괄적 Benchmark의 부재로 충분한 탐구X
최근 제안된 STF, CADC같은 Dataset은 악천후 LiDAR point cloud를 포함하긴하나
Bbox같은 Detection task에 중점. --> point별 Annotation을 제공X
∴ 악천후 LiDAR point cloud로 이뤄진 첫 대규모 Dataset!

 

Domain Generalization

목표: Tgt Data가 모델학습중에 접근불가한 Src Domain Generalizable Model을 학습하는것.
(이때, Src의 경우, 단일 혹은 여러 관련성있는 서로다른 Source임.)

최근: Vector Field를 통해 point cloud를 변형, 3D Detection의 DA를 연구함.
본 논문은 3DSS의 DA를 탐구한 첫 시도!


Unsupervised Domain Adaptation

Label이 지정된 Src Domain에서 학습한 지식을 활용 → Label이 없는 Tgt Domain에 전달하는 방법.
이는 Src Domain의 지식을 Tgt Domain으로 확장하는 방법임.
최근: DA 3D-LiDAR Segmentation이 point별 Annotation으로 점점 주목을 받음.

 

 

 

 

 

 

 

 

 

 

 

 

③ Main Method, Math , etc 이해안되는 것  → Skim or Skip

∙ Main Method: SemanticSTF Dataset

이때, train/val/test 모두 다양한 악천후에 대한 LiDAR스캔의 비율이 거의 동일함.

또한, 식별이 불가능하거나 20개 클래스에 속하지 않거나 ignore(무시된 것)인 point는 invalid로 label을 지정함.
이때, invalid는 training&evaluation에 활용되지 않음.


∙ SemanticSTF의 Class Imbalance

road, sidewalk, building, vegetation, terrain 클래스는 발생빈도가 높지만
motor, motorcyclist, bicyclist 클래스는 명백히 발생빈도가 낮음.

[이런 Class Imbalance의 발생이유는?]

① 주로 교통장면에서 다양한 객체크기와 객체 카테고리의 불균형한 분포.

② 이는 기존의 많은 Benchmark에서도 매우 일반적임.




[Dataset 예시]:

∙ Main Method: PointDR

∙ Point Cloud Domain Randomization

전천후조건에서 DG를 살펴보자.
정상날씨 point cloud에서 일반화가능한 segmentation 모델훈련시 도움이 되는 Domain Randomization기법PointDR을 설계.

[Domain Generalization의 목표]:



∙ PointDR의 설계: Domain Randomization Technique

[목표]: 정상날씨 point cloud를 사용 → 악천후 point cloud에서 잘 작동할 수 있는 DG-3DSS모델 훈련하는 것.
[설계방식]: 2가지 보완설계로 구성: Geometry Style Randomization & Embedding Aggregation:
다양한 새로운 point cloud domain에서 잘 일반화되는 perturbation-invariant representation을 공동으로 학습.

 


 

∙ Loss Function



 

 

 

 

cf) Experiments

 

 

 

 

 

 

🤔 SemanticSTF 논문 구현 testing

1. 배운점.

처음에는 내가 임의대로 아래 깃헙 링크를 바탕으로 파일을 구성했었음:
00~08파일만 SemanticKITTI파일에 넣었었음.



2. 교수님 Feedback

Github만으로 내가 임의로 판단하지 말 것.
정확하게 Data Statistics(데이터 통계)를 파악하고, 실험을 진행해야함!!
Data Statistics란, 아래와 같이 논문에 나타나야함.

SemanticKITTI Dataset





3. How? 정확하게 Data가 구축되어있는지 파악?

train data만 00~08로 존재한다고? 좀 이상한데? valid는 없나?
위를 보고, 아! train.py구조를 먼저 확인해 봐야겠구나! 생각할 것!!

dataset을 split해서 사용하는걸 보니 train, val로 쪼개는것 같은데...
dataset구조를 확인해봐야할것 같다!

아! dataset을 보니까 train과 test(= valid)로 쪼개는구나!
근데, get_kitti도 있으니까 그 함수도 확인해보자.

이제, 마지막으로 core.datasets의 SemanticKITTI클래스를 살펴보면 최종 확인이 가능할 것이다.

import os

import numpy as np
from torchsparse import SparseTensor
from torchsparse.utils.collate import sparse_collate_fn
from torchsparse.utils.quantize import sparse_quantize
from torchpack.utils.logging import logger

__all__ = ['SemanticKITTI']

label_name_mapping = {
    0: 'unlabeled',
    1: 'outlier',
    10: 'car',
    11: 'bicycle',
    13: 'bus',
    15: 'motorcycle',
    16: 'on-rails',
    18: 'truck',
    20: 'other-vehicle',
    30: 'person',
    31: 'bicyclist',
    32: 'motorcyclist',
    40: 'road',
    44: 'parking',
    48: 'sidewalk',
    49: 'other-ground',
    50: 'building',
    51: 'fence',
    52: 'other-structure',
    60: 'lane-marking',
    70: 'vegetation',
    71: 'trunk',
    72: 'terrain',
    80: 'pole',
    81: 'traffic-sign',
    99: 'other-object',
    252: 'moving-car',
    253: 'moving-bicyclist',
    254: 'moving-person',
    255: 'moving-motorcyclist',
    256: 'moving-on-rails',
    257: 'moving-bus',
    258: 'moving-truck',
    259: 'moving-other-vehicle'
}

kept_labels = [
    'road', 'sidewalk', 'parking', 'other-ground', 'building', 'car', 'truck',
    'bicycle', 'motorcycle', 'other-vehicle', 'vegetation', 'trunk', 'terrain',
    'person', 'bicyclist', 'motorcyclist', 'fence', 'pole', 'traffic-sign'
]


class SemanticKITTI(dict):

    def __init__(self, root, voxel_size, num_points, **kwargs):
        submit_to_server = kwargs.get('submit', False)
        sample_stride = kwargs.get('sample_stride', 1)
        google_mode = kwargs.get('google_mode', False)

        logger.info("SKT")

        if submit_to_server:
            super().__init__({
                'train':
                    SemanticKITTIInternal(root,
                                          voxel_size,
                                          num_points,
                                          sample_stride=1,
                                          split='train',
                                          submit=True),
                'test':
                    SemanticKITTIInternal(root,
                                          voxel_size,
                                          num_points,
                                          sample_stride=1,
                                          split='test')
            })
        else:
            super().__init__({
                'train':
                    SemanticKITTIInternal(root,
                                          voxel_size,
                                          num_points,
                                          sample_stride=1,
                                          split='train',
                                          google_mode=google_mode),
                'test':
                    SemanticKITTIInternal(root,
                                          voxel_size,
                                          num_points,
                                          sample_stride=sample_stride,
                                          split='val')
            })


class SemanticKITTIInternal:

    def __init__(self,
                 root,
                 voxel_size,
                 num_points,
                 split,
                 sample_stride=1,
                 submit=False,
                 google_mode=True):
        if submit:
            trainval = True
        else:
            trainval = False
        self.root = root
        self.split = split
        self.voxel_size = voxel_size
        self.num_points = num_points
        self.sample_stride = sample_stride
        self.google_mode = google_mode
        self.seqs = []
        if split == 'train':
            self.seqs = [
                '00', '01', '02', '03', '04', '05', '06', '07', '09', '10'
            ]
            if self.google_mode or trainval:
                self.seqs.append('08')
        elif self.split == 'val':
            self.seqs = ['08']
        elif self.split == 'test':
            self.seqs = [
                '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21'
            ]
...

해당 코드를 보면, 00~07, 09, 10은 train으로
08은 valid로, 11~21은 SemanticKITTI처럼 test로 사용하는 것을 확인할 수 있었다.
따라서 최종적으로 나의 SemanticSTF파일 dataset구조를 아래와 같이 설정할 수 있었다.

 

 

② Domain Generalization 3DSS

cf) Leveraging = 효과적으로 활용하다 (leverage는 지렛대를 활용하다라는 의미로 효과적으로 활용함을 의미함..)

 

'짧.논.리(Short.Paper.Review) > Image Processing' 카테고리의 다른 글

[SemanticSTF]  (0) 2024.12.16

+ Recent posts