Anomaly Detection에 대해 공부할 때 비지도학습 기반 연구에 흥미를 느꼈고, 그 과정에서 AutoEncoder(AE)와 VAE에 대해서 공부하게 되었습니다. 두 모델은 이름은 비슷하지만 실제로는 다른 개념에서 출발했다고 합니다. 간단히 AE에 대해 알아보고 그 후 VAE에 대해 정리해보도록 하겠습니다.
엄청나게 유명한 이활석님의 오토인코더의 모든것 강의를 통해 많이 배웠다.
AE의 concept
AutoEncoder는 일반적으로 나비넥타이 모양으로 표현하는데 (모래시계), 입출력의 차원이 같고 가운데의 병목(bottle neck)이 있다는 점이 모델의 주요한 개념이기 때문인 것 같습니다.
물론 다양하게 적용될 수 있지만, 가장 기본적인 AE의 목표는 차원 축소 (Dimension Reduction) 입니다. 적은 차원으로도 손실없이 입력 데이터의 분포를 잘 표현할 수 있도록 데이터 분포 (매니폴드, manifold) 의 핵심적인 특징을 학습할 수 있도록 하는 것입니다. 이 개념은 주성분분석 (Principal Component Analysis, PCA)와 상당히 유사한데, 실제로 선형 AE의 경우 PCA와 동일한 subspace를 span한다고 알려져있습니다.
위의 링크를 해석해보자면, PCA와 AE는 W 자체는 다를 수 있지만 (eigen vector, weight) 결과는 동일하다. 이런 결과가 나오는 이유는, PCA를 계산하는 SVD (특이값 분해, Singular Vector Decomposition)를 생각해보면, 분해된 eigen vector 간 직교해야한다는 조건이 있는데 AE는 해당 조건이 없다는 점이다. 따라서 학습된 weight의 값 자체는 다를 수 있지만 AE의 weight도 SVD를 거치면 같은 값을 가진다는 것이 논문 (Plaut, E.,From Principal Subspaces to Principal Components with Linear Autoencoders, Arxiv.org:1804.10253)에서 증명되었다.
입력 데이터 \(x\)를 적은차원으로 줄였다가 다시 원 차원으로 매핑한 reconstructed \(x\) 인 \(x’\)과 차이를 줄이도록 학습시킵니다. MSE (Mean Squared Error)로 나타낸 loss function은 다음과 같습니다.
\[L = (x - x')^{2}\]VAE의 concept
VAE는 AE와 조금 다르게 생성모델에 초점을 맞추었습니다. (물론 AE도 생성모델으로 볼 수 있습니다.) 즉 원 데이터 분포를 학습하여 그럴듯한 데이터를 생성해내고 싶다는 목표에서 초기값을 편하게 줄 수 있도록 encoder를 함께 학습시킨 것입니다. 따라서 AE가 데이터를 축소하는 encoder가 중요했다면, VAE는 decoder가 중요하다고 볼 수 있습니다.
이름에서 Variational이 붙는 이유는 변분추론 (Variational Inference, VI)을 활용했기 때문입니다. VI란 구하기 어려운 (intractable) posterior의 분포 \( p(z|x) \) 를 잘 알고있는 다른 분포(일반적으로 정규분포)를 이용하여 근사시키는 방식을 말합니다. 따라서 분포 구하는 문제를 모수 추정 문제로 상대적으로 쉽게 접근할 수 있게됩니다.
데이터의 분포를 학습한다는 말은 수식적으로 원 데이터 분포 \( p(x) \)와 유사한 분포 \( p_{\theta}(x) \)를 구하는 것으로 표현할 수 있습니다. \(p_{\theta}(x)\) 가 원 분포와 비슷하게 근사시키려면 데이터의 likelihood를 최대화하면 됩니다.
\[log p_{\theta}(x) = E_{z\sim q_{\Phi}}(z|x)[log p_{\theta}(x)]\]ELBO 전개
VAE는 ELBO라는 목적함수를 갖습니다. 이를 전개하기 위해서 데이터의 likelihood를 최대화한다는 목표를 이용해서 식을 전개해봅시다!
\(p(x)\)는 \(x\)에 대한 분포이므로 \(z\)에 대해서 기댓값을 취해도 같은 값을 갖습니다. 위 식은 Bayes rule에 의해서 다음과 같이 정리할 수 있습니다. (참고] Bayes Rule : \(p(z|x)=\frac{p(x|z)p(z)}{p(x)}\) )
\[\begin{aligned} log p_{\theta}(x) &= \mathbb{E}_{z\sim q_{\Phi}}(z|x)[log \frac{ p_{\theta}(x|z) p_{\theta}(z) }{ p_{\theta}(z|x) }] \\ &= \mathbb{E}_{z\sim q_{\Phi}}(z|x)[log \frac{ p_{\theta}(x|z) p_{\theta}(z) q_{\Phi}(z|x) }{ p_{\theta}(z|x) q_{\Phi}(z|x) }] \\ &= \mathbb{E}_{z}[log p_{\theta}(x|z)] - \mathbb{E}_{z}[ log \frac{ q_{\Phi}(z|x) }{ p_{\theta}(z) }] + \mathbb{E}_{z}[ log \frac{ q_{\Phi}(z|x) }{ p_{\theta}(z|x) }] \end{aligned}\]위의 식을 KL-Divergence로 정리하면,
\[log p_{\theta}(x) = \mathbb{E}_{z}[log p_{\theta}(x|z)] - D_{KL}( q_{\Phi}(z|x) \| p_{\theta}(z) ) + D_{KL}( q_{\Phi}(z|x) \| p_{\theta}(z|x) )]\]이렇게 3가지 텀으로 나타낼 수 있습니다.
갑자기 식의 전개를 위해 \(q_{\Phi}(z|x)\) 텀이 등장하긴 했지만… 이는 데이터에서 latent vector z를 mapping하는 decoder로 이해할 수 있습니다.
각 텀을 자세히 살펴보면 먼저 \( \mathbb{E}{z}[log p{\theta}(x|z)] \)는 likelihood로 z를 기반으로 decoder가 reconstruct한 결과가 x일 가능도를 의미합니다.
두 번째 \(D_{KL}( q_{\Phi}(z|x) | p_{\theta}(z)) \)는 \(q_{\Phi} (z|x) \)와 \(p_{\theta}(z)\)의 분포 차이를 의미하고, 결국 prior와 encoder의 차이를 의미합니다.
세 번째 \(D_{KL}(q_{\Phi}(z|x) | p_{\theta}(z|x))\)도 분포간 차이를 의미하는데, 여기서 \(p_{\theta}(z|x)\)는 intractable한 분포이기 때문에 계산이 불가능합니다.
하지만 KL-Divergence의 특성상 양의 값을 가진다는 것을 알 수 있고 (\(D_{KL}(q_{\Phi}(z|x)|p_{\theta}(z|x))\geq0\), 최종적으로 \(log p_{\theta}(x)\)의 정확한 값은 아니지만 lower bound 즉 하한 값을 구할 수 있습니다.
\[log p_{\theta}(x)\geq \mathbb{E}_{z}[log p_{\theta}(x|z)]-D_{KL}(q_{\Phi}(z|x)\|p_{\theta}(z))\]이 식이 VAE의 목적함수인 ELBO (Evidence Lowerbound) 입니다! (짝짝짝)
데이터의 likelihood를 최대화 한다는 목표는 결국 ELBO를 최대화 하는 것으로 해석할 수 있는데, 이는 decoder의 likelihood를 최대화하는 것과 encoder를 prior에 근사하도록 하여 만족시킬 수 있습니다.
ELBO 구현하기
위의 수식을 이용해서 실제 모델을 학습시키기 위해서는 몇가지 추가적으로 알아야 할 개념들이 있습니다.
KL Divergence with Normal dist.
먼저 KL은 수식자체는 어려워보이지만, 분포를 정규분포로 가정하면 사실 간단하게 정리할 수 있습니다. KL Divergence의 위키피디아에도 다음의 내용이 있습니다.
decoder를 정규분포로 가정하고, prior를 평균 0 분산 1을 갖는 표준 정규분포로 이용하면 (\( q_{\Phi}(z|x) \sim N(\mu, \sigma) \), \(p_{\theta}(z)\sim N(\symbf{0},I) \)),
\[D_{KL}( q_{\Phi}(z|x_{i}) \| p_{\theta}(z) ) = \frac{1}{2} \sum_{j=1}^{J} (\sigma_{i,j}^{2} + \mu_{i,j}^{2} -1 -ln(\sigma_{i,j}^{2}))\]Reparameterization trick
이제 \(\mathbb{E}{z}[log p{\theta}(x|z)]\)텀을 정규분포로 정리해보면,
\[\mathbb{E}_{z}[log p_{\theta}(x|z)] = \int\limits q_{\Phi}(z|x)log p_{\theta}(x|z) \mathrm{d}z\]\(x\)를 통해 얻은 \(z\)의 likelihood의 평균을 의미합니다.
이 값을 구하기 위해서 Montecarlo 방식을 사용해서 \(L\)번 샘플링한 후 \(\frac{1}{L}\) 하는 것을 생각해 볼 수 있는데
이 때 문제가 되는 부분이 \(z\)가 encoder 분포에서 샘플링된다는 점입니다.
Gradient Descent를 통해 optimize하기 위해서는 미분이 필요한데 sampling된 값을 이용하게 되면 gradient를 구할 수 없게 됩니다.
이 점을 해결하기 위해서 Reparameterization trick 을 이용합니다.
\[z \sim N(\mu, \sigma^{2}) \rightarrow z = \mu + \sigma\cdot\epsilon, \epsilon \sim N(\symbf{0}, I)\]모델이 추정한 \(\mu\)와 \(\sigma\)로 구성한 분포에서 샘플링 하는 방식 대신에, 평균을 그대로 이용하되 분산만큼의 크기를 갖는 noise를 추가하는 방식입니다.
이 방식을 이용하면 표현하고자 하는 \(z\)의 분포 자체는 똑같고 backpropagation가 가능해집니다.
이렇게 구한 ELBO를 최대화하도록 encoder와 decoder를 optimize하면 데이터 \(x\)를 잘 표현하는 분포를 학습할 수 있습니다.