NeRF: Neural Rendering 的革命性方法(二)


Posted by pomelyu on 2021-01-31

這篇包含論文的細節以及實作上的一些問題。

從上一篇我們已經知道 NeRF 作的事情就是把環境的光場存入類神經網路,當我們想生成某個相機位置的圖片時,只要使用類似光線追蹤(ray tracing)的方式,從每個像素打出一道方向是 $\mathbf{d}$ 光,沿途收集每個位置 $\mathbf{x}$ 的光場密度 $\sigma$ 和顏色 $\mathbf{c}$ ,加總後就可以了。

網路架構:

圖中的 $\gamma({.})$ 代表 positional encoding,會在稍候說明。注意到取樣點 $\mathbf{d}$ 在網路一開頭就被引入,方向 $\mathbf{d}$ 卻是在生成光場密度 $\sigma$ 後才引入,這是因為光場的密度表達的是物體形狀,無論相機從哪個方向看過去都不會有影響;但是顏色受到不同觀看角度影響,例如鏡子的表面會反射,因此不同角度看向鏡子,就會反射出不同的環境,因此顏色同時受到形狀和光線的影響,會在網路最後輸出。

Positional Encoding

這是這篇論文非常關鍵的一步,作者的網站也有比較少了 positional encoding 後的結果會平滑許多。因為這篇的網路非常的單純,只有幾層的 MLP 而已,可以想見難以利用高頻的訊號,因此想到可以直接利用 sin, cos 函數來讓輸入的資訊高頻化,方便網路利用。這個手法最早由 On the spectral bias of neural networks 提出:

注意到 $\gamma({\mathbf{r}})$ 的 n=10,而 $\gamma({\mathbf{d}})$ 的 n=3,在「位置」的訊號比起「方向」輸入更高的頻率,這也是合理的,因為期望中對於一個固定的取樣點,視角少許的變化不會對顏色產生太大的變化[1]。而同一個方向不同的取樣點代表的可能會取到不同的物體或是表面,應當賦予比較高的頻率。

另外原作者的實作上,$\gamma({p})$ 還包含了直接的輸入 $p$,與論文中有所不同。其他有可能得到相同效果的方法還有 SIREN,這個以 sin 函數作為 activation 的方式。

Hierarchical volume sampling

NeRF 使用的渲染(rendering)方式,因為需要對空間取樣,實際上大部分的空間都是沒有物體的,因此平均的對空間取樣是非常沒有效率的作法。因此作者提出了 Hierarchical volume sampling 的架構,也就是在同時使用 coarse 和 fine 兩個 NeRF ,先用平均的方式採樣,從 coarse 網路預測採樣點的光場密度,再根據預測的密度重新採樣,密度高的地方採樣多,接著從 fine 網路預測出最終結果。訓練時同時訓練兩個網路,因此損失函數會變成

$\mathbf{C_c}$ 和 $\mathbf{C_f}$ 分別代表 coarse 和 fine 網路的輸出。作者實作上的重新採樣是從 coarse 網路得到的結果產生密度的累積分布函數(cdf, cumulative distribution function),接著在密度上平均取樣,找出對應的座標位置作為 fine 的取樣點。

訓練資料 & 網路訓練

訓練資料分為兩種,一個是由 Blender 產生的合成資料,一個是從作者前一篇論文 Local Light Field Fusion 來的 LLFF dataset,兩者大約都在百張影像的數量級。訓練資料中最麻煩的是相機位置必須是已知的,這樣才能計算每道光的方向和取樣點的位置;另一方面,相機模型的視錐體(view frustum)也需要知道,這樣才能知道取樣點的取樣範圍。這在合成資料上不成問題,但是真實的資料就必須仰賴 structure-from-motion 等方式求得,作者使用 COLAMP 這個工具,可以求得上述的參數,實際的使用方式可以參考作者在 LLFF 上的說明。

由於訓練是以一道道光作為單位,因此可以有很大的 batch size,論文中,作者取 batch size 4096,coarse 和 fine 的取樣點分別為 64, 128,用 NVIDIA V100 訓練 1-2 天可以收斂。自己實際上操作,可以更進一步減少 RAM 的消耗,batch size 到 8192 約需要 5G RAM,使用 NVIDIA 2080Ti 大約 6 hr 就可以收斂,這個網路的硬體訓練需求可說是平易近人。值得注意的是,訓練的 batch size 和 RAM 的消耗與圖片的大小無關,因此可以輕易的訓練高解析度的圖片,這是 NeRF 的一大優勢。

結果比較

這篇的主要比較對象是作者的前一篇論文 LLFF、Facebook 的 Neural Volume,以及 Stanford 的 SRN。前兩篇光場相關,LLFF 將場景拆成不同深度的光場,在根據不同視角去作混合; Neural Volume 將光場用一個 voxel 表示,一樣用 ray-marhcing 的方式從光場取樣累加。SRN 將環境表示成不透明的表面,然後用 LSTM 的方式作 ray-marching 得到特徵值,最後再由特徵值轉換成影像的像素值。

上圖可以看出 NeRF 驚人的威力,細節可以清楚的重現。同樣在 unbound(場景的深度範會很大) 的結果也很好。

其他實作部分

密度權重的計算方式

這一段可以參考作者的實作,以及為何這部份是這樣定義。論文中的公式是

實作卻是

取樣座標系和取樣方法的選擇

嘗試自己拍一些照片來訓練網路,會發現不是每次都可以那麼成功,主要的問題有兩點 1. 相機的位置和參數是否正確 2. 取樣的座標選擇和方法。第一點如果用 COLAMP 幾乎沒有什麼問題,只是背景需要有足夠多的特徵以供演算法運行。而第二點,作者在實作上有提供不同的選項。

NDC(normalized device coordinates)

如果拍攝場景的深度範圍固定,例如桌上放著一個物體,圍繞物體拍攝一圈,照片中只有物體和桌面。這樣可以明確定義出相機 clipping volume 的近、遠平面,取樣會比較有效。反之若是場景中的深度範圍分布很廣,像是 LLFF dataset 中的圖片,都是如下圖拍攝,這樣子在深度上平均取樣就會沒有效率,而且會出現需要積分到無窮遠的情形,因此作者利用 NDC 座標系,將 view frustum 正規化到 [-1, 1] 之間,這部份的討論可以參考作者的說明

即使作者已經將無窮遠的位置正規化到 1,NDC 座標系似乎還是無法解決所有的問題,因此 NeRF++[1] 的作者提出另一個方案,分別為前景和背景用兩個座標系來表示,得到不錯的改進。

參考

  • [1] NeRF++: Analyzing and Improving Neural Radiance Fields

#Deep Learning #Computer Graphics #Neural Rendering #Radiance Field







Related Posts

[Day 02] 工廠模式,策略模式,裝飾者模式

[Day 02] 工廠模式,策略模式,裝飾者模式

使用 Matter.js 2D 物理引擎製作動畫

使用 Matter.js 2D 物理引擎製作動畫

人性較量Day05~工人智慧與人工智慧

人性較量Day05~工人智慧與人工智慧


Comments