loading

NSVF-Neural Sparse Voxel Fields에 대해서


paper review

Published on December 06, 2022 by JunYoung

View synthesis 3D 3D voxel AI Deep learning

8 min READ

NSVF

Neural Sparse Voxel Fields

Abstract

사실적인 형태의 real-world scene을 만들어내는 것은 상당히 어려운 일이다. 이전 세션에서 살펴본 NeRF의 경우, 간단한 구조의 Neural Network을 사용하여 학습되지 않은 방향 및 좌표에서의 scene rendering을 어느 정도 성능 이상으로 증가시켰지만, 여전히 학습이 오래 걸린다는 점, 다량의 데이터 수집(특히 실험 의도에 따라 적절한 camera marching이 제대로 구성되어야 하는 실험적 constraint가 존재한다)이 주요 bottleneck으로 작용한다는 단점이 있다. 또한 다양한 방법의 3D supervision에서 제시한 방법들은 추론 시간을 줄이기 위해 network의 capacity에 대해 많은 여유를 확보하지 못하고, blurry rendering 결과에서 만족하기도 한다. 이처럼 3D scene rendering(generation)은 성능을 향상시키기도 어렵고, 그만큼 데이터 수집이나 적절한 metric을 찾기 곤란한 경우가 많다.

이번 논문에서는 기존 방식보다 rendering 성능을 높이며(high quality) 그와 동시에 속도도 증가시킨(fast) NSVF(Neural Sparse Voxel Fields)를 제시한다. 뒤에서도 설명하겠지만 논문 제목에서 알 수 있듯이 Voxel 기반의 학습법을 제시했으며, sparse voxel octree(물체가 있을법한 장소에 대해서만 rendering 및 학습을 진행)함으로써 학습 시간 단축과 샘플링 퀄리티를 dense하게 가져갈 수 있다는 장점을 보여준다. 또한 explicit한 3D representation을 사용함으로써 scene editing 및 scene composition 등에 사용될 수 있는 가능성도 보여준다.

Introduction

컴퓨터 그래픽 분야에서 scene rendering, realistic rendering이 흔히 활용될 수 있는 형태로는 AR, VR 뿐만 아니라 영화 사업이나 방송에서 활용될 수 있는 비쥬얼 이펙트가 될 수도 있고 연구 분야로는 데이터 생성에 큰 기여를 할 수 있다. 그러나 실제로 활용될 수 있을 정도의 고퀄리티 샘플은 얻기가 힘들다는 challenge가 있다. 이는 실제 scene에 대한 3D representation을 얻기 힘들 뿐만 아니라(LiDAR와 같은 센서는 너무 비싸다) 이를 해결하고자 연구한 IBR(Image Based) 접근법은 결과에 대한 조작이 어려우며(scene의 다양성이 떨어짐), 획득이 간편함에 따라 퀄리티는 보장할 수 없다. 이러한 한계점 때문에 최근의 연구들은 딥러닝을 활용, embedding space에서 가상의 geometry와 appearance를 학습하게 된다. 이러한 연구들은 training을 위해 3D geometric model인 voxel grid, textured mesh를 활용하기도 하며, multi-plane image(depth 정보가 있는 multi-channel이라고 보면 됨), point cloud 등등과 함께 활용되기도 한다. 이러한 explicit geometric representation을 사용하는것보다, neural implicit을 사용하는 방식은 보다 부드럽고 연속적이며(representation은 computing 환경에서 가상으로 생성한 synthesized geometry이므로 discrete하다), 신호처리 관점에서는 high spatial resolution, free-aliasing이라는 장점이 있다. 그러나 실제로 학습 과정에서는 network가 충분한 파라미터를 갖지 못해(learning capacity 부족) 그만큼 성능을 내지 못하는 것이 알려졌고, scene geometry에서 camera ray의 교차점을 찾기 힘들다는 점이 문제로 발생한다.

NSVF 논문에서도 마찬가지로 implicit function을 기반으로 한 Neural Sparse Voxel Fields를 제시한다. 물론 여기서의 implicit field는 sparse voxel이기 때문에 3D geometry가 포함된 것처럼 생각될 수 있겠지만, sparse voxel은 학습 과정에서의 sampling을 위한 임베딩 공간 상에서 가상으로 정의한 부분에 해당된다. 기존 NeRF에서는 각 포인트 및 방향 자체가 MLP에서의 단서(key feature)로 활용되었다면, Voxel에서는 각 point를 대표하는 정육면체의 8개의 꼭짓점(vertices라 부른다) 좌표가 요약된 형태의 feature vector가 사용된다. Query point의 대표성으로 사용되는 형태는 다르지만, 결론적으로는 NeRF에서의 방식과 동일하다는 것이 수식적으로 증명되는데, 이는 뒤에서 한번 더 언급하도록 하겠다.

학습 과정에서 scene 정보가 희박한 voxel grid는 puning되고, 남은 tree node들에 대해서 추가적인 sampling을 통해 디테일한 구조를 잡아가고, 이러한 구조 속에서의 representation을 학습, 최종적으로는 디테일한 부분을 보다 효율적으로 학습하는 방법을 제시한다. 실제로 NeRF 모델에 비해 10배 가량 빠른 성능을 보인다.

Neural rendering with implicit fields

Implicit function을 학습 가능한 neural network인 $F_\theta$ 에 대해서 $F_\theta : (p, v) \rightarrow (c, \omega)$ 라 두면, 핀홀 카메라의 포지션 $p_0 \in R^3$ 에 따라 render color $C$ 를 다음과 같이 표현할 수 있다.

[ C(p_0,~v) = \int^{+\infty}_0 \omega(p(z)) \cdot c(p(z),~v)dz ]

,where $\int^{+\infty}_0 \omega(p(z))dz = 1$ 각 노테이션에 대해 간단하게 짚자면, $v$ 는 바라본 방향에 대한 정보, $p(z)$ 는 카메라의 원점부터 시작하여 ray를 따르는 방향으로 뻗은 벡터에 해당된다. 즉,

[ p(z) = p_0+z\cdot v ]

이고, 물론 공간 상에서 이 벡터 전부가 물체와 intersection하는 representation이 되진 않으므로 weight가 곱해져서 적분되는 형태로 나타나는 것이다. Weight의 경우 물체의 density, 혹은 ray가 그 지점까지 도달할 동안 아무런 물체와도 마주치지 않을 확률 등으로 해석된다. 따라서 weight는 방향 벡터($v$)에 대해 무관한 함수로 표현되며 color는 non-Lambertian surface(reflection)의 경우에 대해 고려해야 하기 때문에 방향 벡터에 대해 유관한 함수로 표현된다. 이는 실제로 학습 네트워크 구조에서도 반영되는 것을 확인할 수 있다.

Surface rendering

표면을 렌더링하는 것은 앞서 렌더링한 것과 다르게 ray와 물체의 겉면이 만나는 부분을 찾아내는 것이기 때문에 weight가 총합 1로 렌더링되는 것이 아닌 디렉델타 function으로 표현된다.

[ \omega(p(z)) = \delta(p(z)-p(z^*)) ]

where $p(z^*)$ is the intersection of the camera ray with the scene geometry

Volume rendering

volume을 렌더링하는 것은 앞서 말한 개념이랑 거의 동일하다. NeRF에서는 샘플링을 통해 렌더링하는데, 다음과 같은 식을 보도록 하자.

[ C(p_0,~v) \simeq \sum_{i = 1}^{N} (\prod_{j = 1}^{i-1} \alpha(z_j,~\Delta_j)) \cdot (1-\alpha(z_i,~\Delta_i))\cdot c(p(z_i),~v) ]

식에서의 alpha는 $\alpha(z_i,~\Delta_i) = exp(-\sigma(p(z_i) \cdot \Delta_i))$, 그리고 $\Delta_i = z_{i+1}-z_i$(sampling 간격) 을 의미한다.

Limitations

표면을 렌더링하는 것은 여러 view에 대해 학습된 color가 일정하게끔 학습되므로 렌더링이 흐려지는 문제가 발생한다. 부피를 렌더링하는 것은 표면을 렌더링하는 것보다 많은 정보가 필요하므로 높은 성능을 위해서는 dense sampling이 필요하다는 한계가 있다. 실제로 속도가 많이 느리다(NeRF는 $800 \times 800$ 크기의 이미지를 렌더링하기 위해 30초 가량이 소모된다).

Definition

그래서 결국 이 논문에서 소개하고자 하는 NSVF가 정확하게 어떤 의미로 적용되는 것일까? 이를 보기 위해서 먼저 Voxel bounded implicit field를 보도록 하자.

Voxel-bounded implicit fields

다음과 같이 가정해보자. 특정 방향에서 바라본 scene의 모습에서 공간 상의 non-empty part를 각각 특정 크기의 voxel로 대표하고, 이러한 K개의 voxel를 하나의 set로 생각해보자.

$V = {V_1,~\cdots,~V_K}$ 이와 같이 표현되는 voxel representation에 대해서 scene은 여러 개의 voxel-bounded implicit function을 통해 예측되는함수로 표현 가능하다. 각 voxel에 대한 다변수 함수라고 생각하면 된다.

[ F_\theta(p, v) = F_\theta^i(g_i(p), v), \forall p \in V_i ]

즉, 각 point가 포함되는 voxel에 대한 parametric estimation으로 표현된다. 그렇다면 각 3D point $p$ 에 대한 color 및 density, 그리고 해당 point에 대한 representation에 대해 함수를 분리할 수 있다.

[ g_i(p) = \zeta(\chi(\tilde{g_i}(p_1^*), \cdots, \tilde{g_i}(p_8^*))) ]

point가 속한 vertex의 8개의 vertices를 input으로 각 vertex에는 $\tilde{g_i}$ 를 통해 feature vector를 저장한다. 추가로 $\chi(\cdot)$ 함수는 trilinear interpolation이고 $\zeta(\cdot)$ 는 positional encoding이다 positional encoding은 한정된 차원에서의 manifold의 학습이 어렵다는 측면에서 고차원으로 끌어올려주기 위해 NeRF에서도 사용했던 방법이다.

이러한 식으로 표현되는 NSVF에서, 결론적으로는 만약 vertex를 활용하지 않고 point 자체가 함수에 사용된다면 이는 특별한 케이스인 NeRF가 된다. 즉,

[ g_i(p) = \zeta(\chi(\tilde{g_i}(p_1^*), \cdots, \tilde{g_i}(p_8^*))) ]

[ = \zeta(p) ]

이면 그냥 원래의 NeRF와 동일하다. 그리고 $\tilde{g_i}(p) : p \rightarrow (c, \sigma), \zeta(\cdot)$ 이며 $F_\theta^i$가 그냥 identity function이라면 해당 모델은 단순히 explicit voxel에 color 및 density를 담는 NV(Neural Volumes)와 같은 식이다.

Volume rendering

NSVF는 voxel에 포함된 scene의 어떠한 점에 대해서도 color 및 density를 예측한다. NeRF와 같이 전체 space에 대한 implicit representation을 렌더링하는 것과 다르게, NSVF를 렌더링하는 것은 빈 부분에 대한 고려가 들어가지 않으므로 훨씬 효율적이다. Rendering은 두 step으로 분리되어 진행된다.

  1. Ray와 Voxel의 intersection을 찾는다.
  2. Voxel 내부에서의 ray-marching을 진행한다.

Ray-voxel intersection

먼저, AABB(Axis-Aligned Bounding Box) intersection을 적용한다. 이는 좌표계에 축을 맞춘 bounding box(voxel)와 ray에 대해서 voxel의 6개의 face(면)들과의 ray origin 사이 거리를 측정한다. 이러한 AABB 체크 방식은 hierarchical octree structure를 가지는 NSVF와 같은 task에서 잘 적용된다. 실제 실험을 통해 약 10k~100k의 sparse voxel를 통해 충분히 complex scene rendering 을 최적화할 수 있음이 보였다.

Ray Marching inside Voxels

[ C(p_0,~v) \simeq \sum_{i = 1}^{N} (\prod_{j = 1}^{i-1} \alpha(z_j,~\Delta_j)) \cdot (1-\alpha(z_i,~\Delta_i))\cdot c(p(z_i),~v) ]

위와 같은 volume rendering 식을 통해 $C(p_0, v)$를 샘플링한다. Ray가 모든 object를 놓치는 경우를 배제하기 위해서, background term인 $c_{bg}$를 붙여 사용한다.

Transparency $A(p_0,~v) = \prod^N_{i=1} \alpha(z_i, \Delta_i)$와 $C_{bg}$는 background에 대해 학습이 가능한 RGB value가 된다. 앞서 논의했던 것과 같이, 전체 공간에 대해서 rendering하는 것은 실제로 물체가 있는 영역에 대한 sampling이 부족하기 때문에 시간적으로도 비효율적이고 resolution이 높지 않다는 단점이 있다. 따라서 NeRF에서는 이를 coarse network와 fine network로 분리해서 학습하는데,

[ \hat{C}c(\rm{r}) = \sum{i=1}^N \it{w}_i\rm{c}_i,~\it{w}_i = T_i(1-\exp(-\sigma_i \delta_i))\rm{c}_i ]

이도 결국 단일 네트워크로 학습이 불가능하고 두 네트워크가 서로 직렬로 구성되어 학습 속도 및 추론 속도의 저하를 불러온다는 문제가 있다. 이와는 다르게 NSVF에서는 두 번째 sampling 과정이 필요하지 않을 뿐더러 같은 evaluation cost를 가지면서도 관심 있는 영역에서의 샘플링이 가능하기 때문에 훨씬 효율적이다.

Early termination

NSVF는 불투명한 물체, solid한 물체 모두 잘 표현할 수 있다. 그러나 solid surface의 경우, 사실상 겉으로 보이는 부분에 대한 voxel만 처리하면 되고 내부의 불필요한 accumulation은 시간만 잡아먹게 된다(accumulated transparency $A(p_0,~v) = 0$). 따라서 해당 실험에서는 $\epsilon = 0..01$이라는 threshold를 두고, 만약 이보다 transparency가 작아진다면 rendering process를 조기에 끝내는 방식을 사용, 품질 저하 없이 속도를 증가시킬 수 있었다.

Training

식을 보면 알 수 있듯이, $C_{bg}$ term 이외에는 NeRF와 동일한 형태를 사용, 모든 rendering process가 미분이 가능하기 때문에 reference image와의 정량적인 cost function을 정의할 수 있다.

[ L = \sum_{(p_0,~v) \in R} \parallel C(p_0,~v)-C^*(p_0,~v) \parallel_2^2 + \lambda \cdot \Omega(A(p_0,~v)) ]

R은 batch sampled ray를 의미하고, $C^*$은 camera ray의 GT color를, $\Omega(\cdot)$는 beta-distribution regularizer이다. Beta regularizer는 간단하게 0~1 사이의 변수에 대한 정규화를 진행하는 함수라고 보면 된다.

Voxel initialization

부피 V를 가지는 초기 bounding box를 가로, 세로, 높이 각각 10등분한 sub voxel 들로 초기화 한다. 이 과정이 결국 coarse sampling이라고 보면 되는데, 여기서부터 Self-pruning, rendering 등등 거치면서 세부화된다. Self pruning은 말 그대로 non essential한 voxel들을 가지치기, 없애는 작업이 되고, density probabilty가 특정 threshold보다 크다면(해당 위치에서 ray가 물체와 만날 확률을 의미한다고 NeRF에서 해석), 이 부분의 voxel은 아예 computation에서 제외하는 것이다.

[ V_i \text{ is pruned if} \min_{j = 1, \cdots, G} exp(-\sigma(g_i(p_j))) > \gamma,~p_j \in V_i,~V_i \in \nu ]

${p_j}^G_{j = 1}$는 voxel $V_i$ 내부에서 uniformly sampled된 point에 해당된다(실험에서는 voxel 내부에서 가로, 세로, 높이 각각 16등분한 $G = 16^3$ 사용). Threshold인 $\gamma = 0.5$를 모든 실험 환경에서 사용했다고 한다.

Progressive training

사실 이 부분에서 조금 띠용했던 건, 시작부터 NeRF에서의 hierarchical network를 비판했으면서 여기서도 iteration을 돌면서 detail한 부분을 학습해나간다는 것이다. 솔직히 속도가 빨라진 것은 pruning 영향이 크고, 성능 향상은 cost를 동일하게 가져가면서 sampling을 보다 dense하게 할 수 있다는 장점이 있는 것 같은데, 아무리 봐도 이 부분은 NeRF의 방식과 거의 유사하다고 생각된다.

그림에서 보이는 것과 같이, 한 번 iteration을 돌고 나면 각 voxel을 axis 기준으로 2등분($2^3$)하여 sub-voxel에 대해 다시 pruning 및 이것저것 진행된다. 물론 세분화되기 때문에 중간 vertex에는 feature가 없다는 문제가 있지만 이를 간단하게 trilinear interpolation을 통해 해결한다. Trilinear interpolation은 bilinear interpolation이랑 같은 원리인데 축이 하나만 더 추가된 것이다.

A n o t h e r p o s t i n c a t e g o r y