데이터분석 그 이상을 전지전능히 다룰 수 있는 데이터 사이언티스트 과정
#인공지능 

NeRF: 2D 이미지를 3D로 바꿔준다고요?

요즘 인공지능 분야에서 핫한 분야가 무엇일까요? 아마도 NERF가 아닐까 싶습니다. NeRF(Neural radiance Fields)는 2D 이미지를 3D로 변환해주는 모델입니다. 이번 콘텐츠에서는 NeRF에 대해 알아보겠습니다.

2022-11-11 | 박은지

요즘 인공지능 분야에서 핫한 분야는 무엇일까요? 다양한 분야가 있겠지만 그 중 하나는 아마도 NERF가 아닐까 싶습니다. NeRF(Neural radiance Fields)는 2D 이미지를 3D로 변환해주는 모델입니다. 우선 아래의 영상을 한 번 보시죠.

  • 동영상 출처: https://www.matthewtancik.com/nerf

위의 영상은 카메라로 찍은 영상이 아닙니다. NeRF를 이용하여 2D 이미지를 3D로 변환한 것인데요, 이미지가 영상처럼 변한다니 신기하지 않나요? 이번 콘텐츠에서는 2020년 소개된 후에 많은 연구자와 대중으로부터 큰 관심을 받은 NeRF가 무엇인지 간략하게 설명하려고 합니다.

NeRF란?

쉽게 설명하면 NeRF는 “2D 이미지를 3D로 변환해준다”라고 말할 수 있지만 엄밀하게 정의하면 NeRF는 물체를 찍은 여러 장의 이미지를 입력 받아 새로운 시점에서의 물체 이미지를 만들어내는(View synthesis) 모델입니다.

NeRF는 n개 시점에서의 불연속적인 2D 이미지를 입력 받아 이미지가 연속적으로 구성될 수 있도록 임의의 시점에서의 새로운 이미지를 만들어 냅니다. 예를 들어 한 물체의 앞, 뒤, 좌, 우와 같이 일부 방향에서 찍은 이미지 몇 장을 입력 받으면 NeRF는 나머지 시점에서의 이미지들을 생성하고, 그 이미지들을 모두 합치면 물체를 3D로 보는 것과 같은 효과가 나타나는 것이죠.

아래 이미지와 같이 드럼의 여러 방향에서의 이미지 여러 개를 넣어주면 NeRF는 입력으로 넣어주지 않은 방향에서의 새로운 드럼 이미지를 생성하여 줍니다. .

NeRF 개요

입력값을 학습한 NeRF는 새로운 방향에서의 물체의 이미지를 생성합니다.  (출처: NeRF 논문(https://arxiv.org/pdf/2003.08934.pdf))

 

NeRF는 2020년 NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis라는 논문에 의해 소개되었습니다. 이 논문은 ECCV 2020 Oral – Best Paper Honorable Mention으로 선정될 정도로 사람들에게 뜨거운 관심을 받았습니다. 아래의 그래프에서 볼 수 있듯 NeRF에 대한 관심은 지금도 점점 많아지고 있습니다.

NeRF paper 추이

NeRF paper 추이 (출처:https://paperswithcode.com/method/nerf)

 

NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis 소개

사실 현재까지 다양한 NeRF 모델이 소개되었지만, 처음에 나온 NeRF를 알아야 발전된 NeRF를 이해하기 쉽기 때문에 먼저 NeRF를 처음 소개한 논문, NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis의 핵심 아이디어를 간단하게 소개하도록 하겠습니다.

NeRF의 입력값과 예측값

NeRF는 물체의 위치 정보(spatial location)인 (x, y, z)와 물체가 바라보는 방향(viewing direction, 카메라의 한 점과 각도)인 (θ, Φ)를 포함한 5차원 데이터를 입력으로 받아 RGB 값과 물체의 밀도(density)를 예측하는 완전 연결 계층(fully-connected network, FC)을 학습합니다. 여기서 물체의 밀도는 투명도의 역수로, 밀도가 커지면 물체가 불투명해지고(뒤에 있는 것들이 잘 보이지 않음), 밀도가 작아지면 물체가 투명해 집니다.

NeRF의 입력과 출력

NeRF의 입력과 출력(출처: https://www.matthewtancik.com/nerf)

NeRF의 학습 과정

1. MLP로 학습

NeRF는 MLP(multi-layer perceptron)로 학습하는데, 총 9개의 FC와 활성화 함수 ReLU를 사용합니다. 먼저 물체의 위치 정보인 (x, y, z)만 8개의 FC를 통과시켜 물체의 밀도(density)를 예측하고, 기존의 위치 정보와 물체를 바라보는 방향 값을 합쳐 9번째 FC를 통과시켜 RGB를 예측합니다. 이는 보는 각도에 따라 색이나 반사율이 다르다는 비 램버시안 효과(Non-Lambertian Effect) 때문입니다. 물체의 밀도는 각도와 상관 없이 동일해야 하므로 처음 8개의 FC에서는 위치 정보만으로 학습하도록 하였고, 색(RGB)은 물체를 보는 방향에서 따라 달라지므로 물체는 보는 방향 값을 마지막 FC에 입력으로 넣어주었습니다.

NeRF MLP

NeRF MLP(출처: https://arxiv.org/pdf/2003.08934.pdf)

 

2. Volume Rendering

Volume Rendering은 NeRF에서 만들어낸 것은 아니고, Image Rendering 분야에서 이미 사용하고 있던 개념입니다. 간단하게 설명하면 MLP에서 얻은 RBG값과 Density 값을 합쳐 하나의 픽셀로 변환하는 것입니다. 이 과정을 진행하기 전에 알아야 할 개념이 하나 있습니다.

Ray

ray

ray(출처: https://www.slideshare.net/HyeongminLee3/pr302-nerf-representing-scenes-as-neural-radiance-fields-for-view-synthesis)

Ray는 카메라의 초점 위치(o)에서 어떤 방향(d)으로 t만큼 이동한 점들의 집합으로, 위의 이미지에서의 선(빨간 선, 파란 선)입니다. 이 선들이 모여 projection된 이미지를 생성합니다. 즉 하나의 Ray는 하나의 픽셀 값을 정하고, 이 픽셀들이 모여 projection된 이미지가 되는 거죠.

또한 카메라의 초점 위치(o)와 보는 방향(veiwing direction, d)이 정해지면 ray 위의 좌표는 o+td를 통해 계산할 수 있습니다.

NeRF 구조

NeRF(출처: https://www.matthewtancik.com/nerf)

 

그런데 한 가지 알아야 할 것은 픽셀 값에 영향을 미치는 것은 그 물체의 밀도 뿐이 아니라 ray 위의 모든 점도 포함된다는 것입니다. 이해하기 쉽지 않죠? 아래의 이미지를 통해 이해해 봅시다.

weighted sum

밀도와 weighted sum

밀도와 weighted sum (출처: https://woochan-autobiography.tistory.com/933#3.1. Ray)

 

카메라로 A(소)를 찍으려고 할 때, B라는 물체가 A의 앞에 있다고 생각해 보죠. 카메라가 A를 찍을 때 영향을 미치는 요소가 무엇이 있을까요?

 

  1. A의 밀도

 A의 밀도가 높다면(투명도가 낮음) A는 선명하게 찍히고 밀도가 낮다면(투명도가 높음) A는 흐릿하게 찍힐 것입니다.

       2. B의 밀도

B의 밀도(Density)가 높으면(투명도가 낮음) A가 잘 보이지 않을 것이고, B의 밀도가 낮으면(투명도가 높음) A는 잘 보일 것입니다.

즉 A와 B의 밀도에 따라 A는 카메라에 선명하게 찍힐 수도, 흐릿하게 찍힐 수도 있습니다.

다시 ray 이야기로 돌아가 보죠. ray 위의 모든 점은 B와 같은 역할을 합니다. 결국 한 ray 위에 있는 모든 점의 밀도에 따라 이미지의 픽셀 값이 커질 수도, 작아질 수도 있는 거죠. 이를 표현하기 위해 논문의 저자들은 찍으려는 물체와 ray 위에 있는 모든 점의 RGB값의 weighted sum을 하였습니다. 한 점의 밀도가 크면 그 점의 weight를 적게 주고, 밀도가 작으면 그 점의 weight를 높게 준 것입니다.

위의 이야기를 정리한 것이 아래의 식(1)입니다.

 

weighted sum이 적용된 식

weighted sum이 적용된 식(출처: https://aigong.tistory.com/409)

 

  • r: ray. o+td
  • C(r): 이미지 픽셀의 RGB 값
  • t: 보고 있는 곳, weighted sum을 할 위치
  • t_n, t_f: ray가 물체를 통과할 때의 시작 점과 끝 점
  • T(t): transmittance, t보다 앞에 있는 점들의 밀도 합. 보고 싶은 물체 앞에 있는 점들의 밀도를 적분하고 – 부호를 주었습니다. – 부호는 이 값이 크면 보고 싶은 물체가 이 점들에 의해 가려진다는 의미를 보여줍니다.
  • σ(r(t)): t 지점에서의 밀도. 밀도가 클수록 선명해집니다.
  • c(r(t), d): t 지점의 RGB 값. 실제 RGB의 weighted sum

이미지의 한 픽셀 값은 RGB 값과 밀도 값의 기댓값으로 계산할 수 있고, 여기에 transmittance라는 개념을 더해줍니다.

Stratified sampling approach

ray는 직선입니다. 직선 위에는 무한한 점이 있죠. 무한한 점에 대해 위의 식을 대입하여 계산한다면 얼마나 많은 시간과 자원이 들까요? 그래서 ray 위에서 몇 개의 점을 샘플링하여 뽑아내야 합니다. 그러나 ray에서 무작위로 점을 뽑아낸다면 어떤 경우는 한 부분에서만 많은 점이 뽑히고, 다른 부분에서는 한 점도 뽑히지 않을 수 있습니다. 그래서 저자들은 ray를 n 등분하고 각 등분한 곳에서 모든 확률이 균일한 분포를 이루도록 점을 뽑습니다. 이렇게 하면 sampling되는 점이 달라지므로 연속적인 값에 대해 학습할 수 있다고 해요. 이를 표현한 식은 아래와 같습니다.

Stratified sampling 식

Stratified sampling 식(출처: https://arxiv.org/pdf/2003.08934.pdf)

 

샘플링하여 불연속한 점에 대해서는 위에서 설명한 weighted sum을 한 식(1)이 아래의 식으로 변합니다. (“Optical models for direct volume rendering“)을 참고하면 간단하게 아래의 식으로 변다고 해요.) 이 식의 밀도 값(o)과 RGB값(c)를 네트워크를 통해 학습하면 되는 거죠.

 

불연속한 점에서의 NeRF 함수

불연속한 점에서의 NeRF 함수(출처: https://arxiv.org/pdf/2003.08934.pdf)

Hierarchical volume sampling – Coarse network & Fine network

stratified sampling을 하면 ray 중 물체가 존재하는 점이 뽑힐 수도 있고, 아무 것도 없는 점이 뽑히는 경우가 생깁니다. 아무 것도 없는 점에서보다는 물체가 존재하는 점이나 부분에서 추가 학습을 하면 효과가 더 좋지 않을까요? 이런 아이디어로부터 저자들은 Hierarchical volume sampling을 고안해 냅니다. 즉 ray 전체에서 sampling하여 학습을 하고(Coarse network), 학습된 결과에서 밀도 값이 크게 나온 부분만 골라 그 부분에서 다시 sampling하여 추가 학습을 합니다(Fine network). 이 두 개의 network를 합해 최종 결과물을 얻습니다.

network 학습을 할 때 보통 loss를 구하여 backpropagation을 하죠. NeRF에서도 마찬가지의 과정을 거칩니다. 보통 지도 학습 모델 학습에서는 학습 데이터로 학습하고 테스트 데이터로 예측을 하지만 NeRF는 데이터 중 일부를 학습하여 바로 새로운 시점에서의 이미지를 생성(inference)하고, 나머지 데이터(ground truth)와 비교합니다. 생성한 이미지와 나머지 데이터 사이의 로스(loss)를 비교하여 백프로파게이션을 하여 학습을 진행하게 됩니다.

Hierarchical volume sampling

Hierarchical volume sampling(출처: https://www.matthewtancik.com/nerf)

 

그리고 새로운 이미지가 들어올 때마다 입력 이미지에 대해 새롭게 학습하여 이미지를 렌더링합니다.

Positional Encoding

마지막으로 설명할 것은 Positional Encoding입니다.

  • 주의: 자연어 처리에서 사용하는 Positional Encoding과는 다릅니다.

NeRF에서의 Positional Encoding은 high frequency 영역까지 학습할 수 있도록 하는 것입니다. NeRF의 입력값은 5D low dimension입니다. 따라서 정보가 부족하여 제대로 학습이 되지 않습니다. 그래서 아래의 식을 통해 입력값이 high frequency 정보까지 잘 표현할 수 있도록 하였다고 합니다.

positional encoding 식

positional encoding 식(출처: https://arxiv.org/pdf/2003.08934.pdf)

 

식에서 L은 차원 수이고, 3D 위치 정보에서는 10개를 사용하여 차원을 60개로 늘려주고 보는 방향(viewing direction)에서는 4개를 사용하여 차원을 24개로 늘려 주었다고 합니다.

NeRF MLP

NeRF의 결과물

이로 인한 결과는 짜잔!

NeRF 결과 비교

NeRF 결과 비교(출처: https://arxiv.org/pdf/2003.08934.pdf)

맨 왼쪽과 같은 이미지를 입력으로 넣어주면 NeRF는 오른쪽의 결과물(NeRF(ours))을 보여줍니다. 실제 사진(Ground Truth)과 거의 비슷하죠? 다른 모델보다 훨씬 성능이 좋은 것은 당연하고요!

기존의 입력 이미지와 NeRF로 새로 생성한 이미지를 합치면 아래와 같이 멋진 결과물도 볼 수 있습니다.

  • 동영상 출처: https://www.matthewtancik.com/nerf

정말 신기하지 않나요?

NeRF 코드

저자의 코드

NeRF의 코드는 저자가 깃헙을 통해 공개하였고, NeRF를 직접 돌려볼 수 있도록 하였습니다. NeRF의 코드가 궁금하신 분들은 직접 저자의 깃헙에 가서 코드를 살펴보고 직접 실행시켜보세요.

  • 참고: NeRF 저자들은 코랩으로 작은 NeRF를 돌려볼 수 있게 하였지만 tensorflow 1으로 작성하였기 때문에 현재 코랩에서 돌아가지는 않습니다.

케라스 튜토리얼

케라스에서는 NeRF를 작게 만들어보는 튜토리얼을 제공하고 있습니다. 에폭 수가 20으로 작기 때문에 이미지가 선명하지는 않지만 NeRF의 작동 원리를 코드와 설명을 통해 알 수 있는 좋은 자료이니, 케라스의 NeRF 튜토리얼을 학습해 보는 것도 좋을 것 같습니다.

 


 

이번 콘텐츠에서는 NeRF가 무엇인지에 대해 살펴보았습니다. 더 정확하고 자세한 내용을 알고 싶다면 논문을 직접 보시는 것을 추천드립니다.

신기하고 멋진 결과물을 보여준 NeRF지만 NeRF에도 많은 단점이 있습니다. 다음 콘텐츠에서는 NeRF의 단점을 살펴보고 그 단점을 해결한 몇 가지 모델을 소개하려고 합니다. 그럼 다음 시간에 만나요!

참고자료