Paper/Neural rendering

[NeRF] NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis

침닦는수건 2023. 2. 21. 23:11
반응형

NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis

내 맘대로 Introduction

NeRF는 나온지 2년 밖에 되지 않았지만 이제 비전 공부했다는 사람 중에 모르는 사람없을 정도로 유명해졌다. 오히려 모르면 안된다는 소리가 나올 정도로 엄청난 논문이고 개인적으로 GAN이 처음 등장했을 때보다 훨씬 큰 충격을 가한 논문이라고 생각한다.

내가 말하는 NeRF는 간단히 말하면 "어떤 대상의 여러 2D 이미지만 갖고 그 대상의 무한한 2D 이미지를 얻는 기술"이다. 정확히는 어떤 대상을 특정 각도로 촬영한 이미지로 네트워크를 하나 학습 시켜서 임의의 각도에서 촬영한 이미지를 생성해내는 기술이다.

NeRF가 대단한 이유는 기존에 이러한 물체의 continuous rendering은 3D 모델이 존재해야만 가능한 것으로 여겨졌다. 그래서 고해상도의 3D 모델이 있어야 임의의 각도에서의 고해상도 물체 이미지를 얻을 수 있었다. 이 기술이 등장함으로써 그러한 제약에서 벗어날 수 있게 된 것이 파격적이었다.

또 하나는 이미지를 얻기 위한 과정에서 추정하는 중간 산물을 이용해 3D geometry도 얻을 수 있다. 즉, 기존 photogrammetry pipeline을 이용하여 SfM, MVS, poisson surface reconstruction을 거쳐 만들던 3D geometry를 전혀 다른 방식으로 생성할 수 있다는 관점이 발견된 것이다. Reconstruction 부문은 전통적인 수학 모델을 사용하는 photogrammetry가 그래도 아직 딥러닝에 뒤쳐지지 않았다고 평가받는 부문인데 NeRF로 인해 그 간극이 좁혀질 수 있음이 보여졌다.

마지막으로 내가 꼽는 가장 대단한 이유는, 바로 딥러닝의 패러다임을 바꾼 것이다. 지금까지 딥러닝에서 overfitting은 나쁜 것으로 꼽힌다. 그래서 각종 domain 데이터를 모아 학습시키고 generalization이 잘되는 네트워크를 만드는 것이 정답으로 여겨졌다. 하지만 NeRF는 다르다. NeRF는 만약 네트워크가 극도로 한가지에만 overfitting되도록 하면 어떻게 될까? 라고 질문하는 듯하다. 네트워크가 단 한 개의 물체 정보만 극도로 습득하여 물체==네트워크가 되도록 한 것이다. 네트워크를 기존에는 하나의 함수로 보았다면, NeRF가 보여준 새로운 패러다임의 네트워크는 하나의 컨테이너로 보는 셈이다. 이러한 관점의 변환으로 새로운 딥러닝 활용의 지평을 연 것이 가장 대단한 점이 아닐까 싶다.

핵심 내용

Neural radiance field

NeRF는 고작 간단하고 얕은 MLP다. (그래서 더 대단한 것이다.) 그리고 그 MLP는 대상 물체가 존재하는 공간 상 임의의 3D 좌표 x, y, z와 대상 물체를 어디서 바라보고 있는지 카메라 각도 θ, φ를 입력으로 받고, 해당 좌표의 위치가 갖고 있는 색깔(R, G, B)과 불투명도 (volume density, σ)를 출력으로 하는게 전부다. 단순히 위치 받고 색깔 내뿜는 네트워크다.

NeRF에서 중요한 것은 이 단순한 MLP를 어떻게 학습시키고, 어떻게 활용하는 가다.

Training core

이해를 돕기 위해 위 그림은 나누어 다시 그려보면 다음과 같다.

MLP를 학습시킬 때 입력으로 들어가는 3D point들은, (카메라 각도 θ, φ에서) 주어진 이미지 상에서 ray를 하나 만들고 그 ray 선상에 있는 point들로 이루어진다. 물체가 존재하는 공간 상에서 무작위로 뽑는 것이 아니라 한 ray, 즉 직선 상에 정렬된 point들을 뽑는 것이다.

이후에 MLP를 통과시켜 각각의 RGB와 volume density를 얻고 이를 volume density를 이용한 weighted accumulation 컨셉으로 누적해서 합친 뒤, ray가 이미지와 만나는 지점의 pixel 색깔과 비교하는 식으로 학습한다.

잘 이해가 되지 않는 다면 아래 영상의 1분까지를 보고 오면 이해가 잘 될 것이다.

https://www.youtube.com/watch?v=JuH79E8rdKc&t=54s



ray를 따라 weighted accumulation을 함으로써 pixel color를 만들어내는 것은 렌더링 파이프라인에서 흔하게 사용되는 컨셉으로 이를 그대로 가져온 것이라고 볼 수 있다. 실제로 ray 상에 있는 값들이 합쳐져 이미지에 맺힌다.

이런 학습 과정을 여러 시점(여러 카메라 각도)에서 수없이 반복할 경우, 네트워크는 물체가 존재하는 공간이 어떤 색으로, 어떤 밀도로 가득차 있는지 점점 학습하게 된다. (물체 표면에 가깝다면 색상과 밀도가 뚜렷하게, 허공이라면 색상과 밀도가 희미하게 학습하게 된다.) 3차원 supervision없이 3차원을 배울 수 있게 되는 것이다.

복잡한 수식에서 의미하는 것도 사실 간단히 ray를 따라 3D color들을 누적한다는 뜻이다. 구현 상 수식 (1)과 같이 연속 공간을 가정하는 수식을 사용할 수 없으므로 한 ray 위 모든 지점이 아닌 discrete sampling으로 얻은 몇몇 지점만을 갖고 풀게 된다. 논문에서 제시한 discrete sampling은 uniform하게 뽑는 방법이다.

그럼 최종적으로 위와 같이 정리할 수 있다.

그리고 갖고 있는 데이터 (이미지)의 값 C(r)과 비교하기만 하면 된다. (term이 두 개인 것은 논문에서 coarse와 fine 총 2개 scale을 활용했기 때문이고 원리는 같다.)

Training tips

Coordinate normalization

ray를 따라 x,y,z를 뽑아 준비할 때, 물체가 있는 공간에 ray가 지나가는 구간 위에서 뽑는 것이 당연히 좋다. 아니면 허공만 뽑히기 때문이다. 이 때 물체가 있는 공간이 world 좌표계에서 어디에 있느냐에 따라 x,y,z 값이 천차만별이 될 수 있다. x,y,z가 다양한 값을 가질 수 있다는 의미만 보면 여전히 점일 뿐이니 크게 문제되지 않지만 이 값을 입력으로 받는 네트워크 입장에서는 data range가 문제다. 간단히 말해 같은 물체라도 어디에 위치해 있는지에 따라 -10~-8, -1~1, 98~100 등 전혀 다른 범위의 입력을 받게 된다. 이는 네트워크에게 numerically 성능에 영향을 주는 요소다. 데이터가 -1~1 범위로 normalize가 잘 되어있어야 안정적으로 학습이 가능하다는 것은 밝혀진 이야기다.

따라서 물체를 원점을 중심으로 하는 반지름 1m unit sphere 안으로 scale/translation하여 학습해야 한다. 이 과정에서 x,y,z만 scale/translation하는 것이 아니라 camera pose도 같이 움직여주어야 함을 잊지 말자.

Positional encoding
입력으로 ray 위 x,y,z와 동시에 ray를 만들 때 사용한 카메라 각도 θ, φ를 같이 넣어주는 것을 볼 수 있다. 하지만 periodic, discontinuous(0, 2pi가 같은 의미지만 값이 다름) 한 값이기 때문에 네트워크 입장에서 다루기 까다로운 입력 데이터가 맞다. 따라서 입력 데이터의 질을 높이기 위해 positional encoding이라는 방식으로 θ, φ의 형태를 바꾸어주는게 좋다.

간단히는 sin, cos 내부에 주기를 바꾸어가며 넣어주는 식으로 feature화 한다. (디테일은 positional encoding에 대해 따로 보길 추천한다.)

Ray sampling

논문에서 uniform ray sampling을 했지만, ray 위에서 point를 뽑을 때 효율적으로 뽑을수록 학습 효과가 좋다. 예를 들어, 물체의 표면 근처에서 point를 많이 뽑고 허공에서는 덜 뽑을 경우 물체에 집중해서 학습할 수 있다.

한 예시로 ray를 따라 PDF를 계산하고 PDF를 기반으로 sampling하는 식으로 효율을 높일 수 있다. 다시 말해, 처음에는 대충 uniform sampling 하고 각 위치의 volume density를 본 뒤, volume density가 높은 point 주변에서 2차, 3차 sampling을 추가하여 물체 주변에서 point가 많이 뽑히도록 유도할 수 있을 것이다.

Inference core

학습이 끝난 뒤 어떻게 활용하느냐? 임의의 새로운 시점에서 물체를 바라본 이미지를 생성할 수 있다. 새로운 시점의 카메라 자세 θ, φ를 정하고 여기서 원하는 이미지 해상도만큼 ray를 생성한다. 그리고 각 ray 위에서 무수히 많은 점들을 sampling한 뒤 네트워크를 통과시켜 색깔과 밀도를 얻어낸다. 이를 수식(3)을 따라 누적하여 pixel color를 생성한다. 그러면 최종적으로 이미지를 생성할 수 있다.

말이 어려운데 그냥, 새로운 시점에서 이미지를 얻고 싶다면 위 학습할 때 (ray 만들고, ray 위에서 점 뽑고, 네트워크 통과시켜서 색깔/밀도 뽑고, pixel color랑 비교)하는 과정에서 마지막 pixel color랑 비교하는 것만 없애고 나머지를 똑같이 하면 된다. 네트워크로 한 pixel 한 pixel 색깔을 칠해나가면 되는 것이다.

네트워크가 이미 3차원 공간 안의 색상과 밀도를 전부 다 외우고 있기 때문에 특정 시점 이미지를 쉽게 렌더링할 수 있게 된 것이다.

Inference tips

3D geometry도 얻어낼 수 있다. 물체가 차지하는 공간을 둘러싸는 voxel grid를 하나 생성한다. 그리고 voxel grid의 좌표를 하나씩 네트워크를 통과시켜 volume density를 얻어낸다.

네트워크 구조를 보면 카메라 각도 θ, φ는 후반부에 들어가기 때문에 volume density만 얻고자 할 때는 카메라 포즈를 몰라도 된다. (네트워크 앞부분만 사용하면 되니까)

voxel grid의 모든 voxel에 volume density를 채웠다면 이 voxel grid가 의미하는 것은 해당 공간 자체의 밀도 구름이다.

이 voxel grid에 marching cube 알고리즘을 적용하여 mesh화 하면 3D geometry를 얻을 수 있다. (marching cube 알고리즘은 유명해서 정리가 잘 되어있으니 따로 검색해보길 추천)

Result

위와 같이 학습을 마치고 활용까지 마친다면 학습한 대상 물체에 대해선 정말 고품질의 이미지를 얻을 수 있게 된다.

반응형