向きを勾配法で最適化したいときにどうするか(NeRF)

 NeRFのうち、いくつかの手法はカメラPoseについても勾配が繋がっているので、それを勾配法で最適化したくなるのは自然な気持ちである。

 しかし、理屈として勾配が繋がっているのはわかるが、実装的にはどうするんじゃいという話がすぐにはわからない。特に、向きの部分を表現する3x3行列が、向きであるためには直交性を満たしていないといけないので、そういう制約を持たせながら最適化をしなければならない。そのあたり各種論文がどうやっていそうなのかを簡単に調べた。

iNeRF

 これのセル6あたりでカメラPoseを最適化している。かなり素朴に4x4行列を定義して、特に向きの制約が入っていないままに最適化しているように見える。

Block-NeRF

 公式実装がないので論文から

The learned pose correction consists of a position offset and a 3 × 3 residual rotation matrix, which is added to the identity matrix and normalized before being applied to ensure it is orthogonal. The pose corrections are initialized to 0 and their element-wise l2 norm is regularized during training. This regularization is scaled by 105 at the start of training and linearly decays to 10^−1 after 5000 iterations. This allows the network to learn initial geometry prior to applying pose offsets.

とのこと。つまり

  1. 単位行列に学習可能変動分を足す
  2. 正規化する
  3. もとのPoseにかける

という手順に読み取れる。正規化手法がどうなっているのかはよくわからない。そこで勾配途切れないようなもので実装しないといけなさそう。

BARF

 ちゃんと実装を読み解いたわけではないので自信ないが

で使っているPoseが大事で、それは

というように、Lie代数を考えているらしい。これがなにかというと、Wikipediaを読むと

らしい。

NeRF--

 こちらもLie代数

 BARFと若干違うのは、

  • BARFでは係数を求める際に、テイラー展開を真面目に10項目くらいまで計算して求めている
  • NeRF--では係数を求める際に、ノルムが0になるときの0除算を避けるために1e-15を足して、係数は式通りのものを利用している

所感

 最後のNeRF--が一番綺麗な実装になっているのではないかと感じたので、それで良いのではないか。