Density Estimation Using Real NVP
Density Estimation Using Real NVP
Introduction
이 논문은 거의 전에 살펴본 NICE 논문의 내용과 거~의 비슷해서, 이빠이 생략할 것이다.
음.. NICE 에서는 Additive coupling layers 를 통해 레이어의 Jacobian 행렬식을 빠르게 $1$ 이라는 값으로 계산할 수 있었고, 역함수 또한 야무지게 쉽게 구할 수 있었다.
그러나 모든 레이어에서의 Jacobian 행렬식의 값이 $1$ 이었기 때문에, 잠재 공간의 각 차원에 대해 개별적으로 분산을 조정하기 위해 마지막 레이어로 $S$ 라는 스케일링 대각행렬을 추가하여 이를 조정했었다.
이 논문에서는! 크게 보자면 Affine coupling layers 를 대신 사용하여, 각 레이어에서 공간을 더 역동적으로 변형하도록 하고, 추가로 멀티스케일 아키텍처라는걸 제시해서 더 많은 레이어를 쌓을 수 있게 하였는데, 이러한 real NVP 에 대해서 짧게만 알아보자.
Coupling Layers
real NVP는 그냥 기존 NICE 의 업그레이드 버전이다. 마찬가지로 change of variable rule 을 써서, $p_{X}(x)$ 의 값을 $p_{Z}(z)$ 와 매핑 함수 $f: X \to Z$ 의 Jacobian 행렬식을 통해 계산하는데, ..자세히는 NICE 블로그 글에 있다…
아무튼 여기선 NICE 의 additive coupling layers 를 affine coupling layers 로 대체한다.
어.. $D$ 차원의 입력 $x$ 에 대해서, affine coupling layer 의 출력은 다음과 같다.
\[\begin{align} y_{1:d} &= x_{1:d} \\ y_{d+1:D} &= x_{d+1:D} \odot \exp(s(x_{1:d})) + t(x_{1:d}) \end{align}\]NICE와 마찬가지로 $x$ 를 두 구간으로 나눈 후, 하나는 그대로, 나머지는 affine 함수를 통해 변환시키는데, 여기서 $s,t: \mathbb{R}^{d} \to \mathbb{R}^{D-d}$ 는 임의의 함수이고, $\odot$ 은 행렬 요소별 곱셈을 의미한다.
그래서 아무튼 이렇게 하면 이러한 변환의 Jacobian은 다음과 같다.
\[\begin{align} \frac{\partial y}{\partial x} &= \begin{bmatrix} \mathbb{I}_{d} & 0 \\ \frac{\partial y_{d+1:D}}{\partial x_{1:d}} & \text{diag}(\exp(s(x_{1:d}))) \end{bmatrix} \\ \det\left(\frac{\partial y}{\partial x}\right) &= \exp\left(\sum_{j} s(x_{1:d})_{j}\right) \end{align}\]여기서 $\text{diag}(\exp(s(x_{1:d})))$ 는 대각 성분이 $\exp(s(x_{1:d}))$ 인 대각 행렬이다.
jacobian 행렬식이 삼뽕하게 계산되는 것을 볼 수 있다. 더군다나 NICE와 마찬가지로 임의의 함수 $s,t$ 가 jacobian 행렬식 계산에 아무런 영향도 끼치지 않으므로, 이 두 함수가 우리가 구현할 모델들이 되겠다. NICE 에서는 그냥 MLP 위주로 구현했는데, 여기선 Rectified CNN 으로 구현했다고 한다. .. 그냥 아이디어 위주로만 공부할꺼라 모델을 어떻게 구현했는지는 생략하겠다..
다시 돌아와서, jacobian 행렬식뿐만 아니라, 역함수도 다음과 같이 간단하게 구해진다.
\[\begin{align} x_{1:d} &= y_{1:d} \\ x_{d+1:D} &= (y_{d+1:D} - t(y_{1:d})) \odot \exp(-s(y_{1:d})) \end{align}\]그리고 NICE 에서와 마찬가지로, 위 식을 보면 $(1:d)$ 차원의 데이터는 계속 아무런 변화없이 그대로 매핑되기 때문에, 이 과정을 $(d+1:D)$ 구간을 기준으로도 수행하여 번갈아가며 해야 모든 구간이 영향을 받아야 한다.
그래서 논문 저자 형님이 아주 상냥하게 다음과 같이 하면 된다고 제시를 해줬다.
Mask를 의미하는 0과 1의 값만을 가지는 임의의 $b$ 에 대해서, $y$ 는 다음과 같이 계산된다.
\[y = b \odot x + (1-b) \odot (x \odot \exp(s(b \odot x)) + t(b \odot x))\]그래서 이 mask를 어떻게 설정하느냐, 간단히 반으로 나눠서 하는게 아니라, 논문에서는 두 가지 방법을 제시하여 사용한다.
하나는 체스 보드 처럼, 체크보드 형태로 마스크를 적용하는 것인데, 데이터의 각 요소들의 인덱스 합이 짝수면 $1$ 아니면 $0$ 이런식으로 부여했다고 한다.
다른 하나는 채널 별로 마스크를 부여하는 것이다. 보통 채널을 반반 나눠서 앞 절반은 $1$, 나머지 절반은 $0$ 이런식으로.
설명이 되게 간단한데, 미안하다. 근데 딱히 또 설명할게 없다..
Multi-scale architecture
아무튼 이제 Affine coupling layers 를 통해 각 레이어에서 NICE 이 비해 더 유연하게? 공간을 변형했음을 봤는데, 앞서서 멀티스케일 아키텍쳐를 사용해서 이 레이어층을 더 깊게 쌓을 수 있게! 했다고 한다. 그걸 어떻게 했는지 알아보자.
그래서 그게 뭐냐, 스퀴징(Squeezing) 연산을 사용하는 것이다. 이거는 기존 $h \times w \times c$ 텐서의 이미지 형태 데이터에, $h,w$ 차원을 절반씩 줄이고, 그만큼 채널을 키우는 것이다. 즉, $h \times w \times c \to \frac{h}{2} \times \frac{w}{2} \times 4c$ 요런 식으로,
아무튼 이제 멀티 스케일 아키텍처란 무엇이냐, 다음과 같은 구조를 말한다.
\[\begin{align} h^{(0)} &= x \\ (z^{(i+1)}, h^{(i+1)}) &= f^{(i+1)}(h^{(i)}) \\ z^{L} &= f^{(L)}(h^{(L-1)}) \\ z &= (z^{(1)}, ..., z^{L}) \end{align}\]여기서 식 8의 과정을 총 $L-1$ 번 반복한다. 이 각 단계을 스케일이라고 하는데, 식을 보면, 뭐.. $l < L$ 의 매핑 함수 $f^{(l)}$ 을 결과를 절반으로 나눠서, $z^{(l)}, h^{(l)}$ 로 놔두고, $h^{(l)}$ 만을 다음 스케일에서 사용한다. 요 안쓰는 $z^{(l)}$ 는 따로 모아두었다가 마지막 최종 잠재공간에 concat 되어 사용되는 것을 볼 수 있다. 즉, 각 스케일을 지날 때마다 $f^{(L)}$ 에 입력되는 $h^{(l-1)}$ 의 크기가 절반씩 줄어드는데, 이로인한 병목을 없애기 위해, 그때마다 해당 스케일의 $s,t$ 모델의 은닉층의 채널을 2배로 늘려 학습했다.
여기서 각 $f^{(l)}$ 는 어떻게 수행되냐, 우리가 앞서 살펴본 체크보드 마스크, 채널별 마스크, 스퀴징 연산을 모두 사용한다. 여러개의 레이어로 구성되어 있는데, 처음 3개의 coupling layer 에서는 체크보드 마스크를 적용하여 수행하고, 그 후, 스퀴징 연산을 수행한 뒤, 채널별 마스크를 적용하여 3개 이상의 coupling layer 를 수행한다. 이 과정이 하나의 $f^{(l)}$ 를 구성한다.
아무튼 이렇게 수행함으로써, 해상도가 컸던 앞쪽 스케일에서 나온 $z^{(l)}$ 와, 마지막 부근에서 해상도가 다 줄어든 스케일에서 나온 $z^{(l)}$ 가 담고 있는 정보가 다르다는 것이다.
앞쪽 스케일에서의 $z$ 는 해상도가 큰 상태다 보니 세세한 디테일의 특징들을 가지고 있고, 뒤쪽 스케일에서의 $z$ 는 해상도가 그만큼 줄어들어, 그만큼 전체적이고 추상적인 특징을 가지게 된다. 즉, 우리가 학습한 잠재공간을 분석할 수 있다는 것이다.
추가로 각 스케일을 지날 때마다 입력 텐서의 크기가 계속 줄어들기에, 노빠꾸로 $D$ 차원 입력 텐서를 가지는 거대한 모델을 사용한 NICE 와 비교하여 좀 더 메모리상으로도, 계산 속도로도 더 낫다는 것이다. 즉, 이를 통해 더! 큰 모델을 만들 수 있다는 것이다!!!
찌라시시
…글이 많이 짧은데, 그냥 핵심 아이디어만 다루려다 보니 그런거다. ..진짜로. 딱히 뭐 설명할게 별로 없다.
