AI/컴퓨터비전(CV)

[CV 논문] Auto-Encoding Variational Bayes

CSE 2026. 3. 5. 16:45

 

 

아래 글에서 이 블로그에서 리뷰한 논문들의 흐름과 분야별 분류를 한 눈에 볼 수 있다.

읽은 논문들 정리

 

읽은 논문들 정리

[목차]지속적으로 업데이트 중, 번호는 모델발전 순서가 아닌 읽은 순서에 따라 정렬.1. Computer Vision 분야 논문Classification 모델들의 발전Detection 모델들의 발전Segmentation3D 처리2. Natural Language Process

april2901.tistory.com

 


이 논문은 좀 수학적인 내용이 많고 직관적이지 않기 때문에 예시를 통해 간단히 먼저 이해해보는 것이 좋을 것 같다.

 

ai에게 글씨를 쓰라고 요청하는 상황을 생각해보자.

글씨에는 여러 속성이 있다.

글씨 크기, 글씨 굵기, 글씨의 색, 글씨의 곡선 부분의 곡률 등 수많은 속성이 있을 것이다.

글씨 크기처럼 명시적으로 측정하고 숫자로 그 특성의 정도를 나타낼 수 있는 속성도 있지만 숫자로 표현은 고사하고 말로도 표현하기 힘든 속성들도 있다.

 

여기서 두 가지 표현이 나온다.

이런 특성들을 모아놓은 변수($z$)와 그 특성을 통해 그려진 결과값(글씨), $x$이다.

예를 들면 $z=(1,3,4,2,...)$일 때 1은 글씨의 색, 3은 글씨의 크기 등이 되고 그 결과가 $x$일 것이다.

이 $z$안에는 둥글둥글한 느낌 처럼 계량되지 않는 속성도 있다.

 

이 고차원 벡터 $z$는 고차원 공간의 한 점으로 생각할 수 있다.

이 공간을 잠재 공간(latent space)라고 부른다.

이제 ai를 학습시켜야 한다.

'공간의 이쪽 부분에 있는 점(특성 정보)을 사용해 글씨를 그리니 날카로운 필체가 나오네?'와 같은 인식이 학습을 진행하면서 생기게 된다.

 

<인코더와 디코더>

두 가지 장치가 있다.

각각 인코더(encoder)와 디코더(decoder)이다.

 

encoder : 글씨를 보고 특성을 나타내는 점이 공간상 어디쯤에 있을지 예측하는 장치이다.

decoder : 반대로 점을 보고 글씨를 그리는 장치이다.

 

<학습 방식>

간단히 설명하면,

먼저 인코더가 글씨를 보고 점의 좌표를 뽑아낸다.

이 좌표를 보고 디코더는 다시 글씨를 그린다.

원본과 디코더의 그림의 차이를 통해 학습한다.

 

이때 인코더, 디코더 둘다 학습이 된다.

인코더는 특징을 더 잘 뽑도록 학습이 되고,

디코더는 좌표를 더 잘 해석하도록 학습이 된다.

 

이 때 아무 조건이 없으면 인코더가 글씨가 아주 약간만 달라도 각 글씨의 점을 잠재공간상의 아주 먼 곳들에 멀리 박아놓을 수 있다.

즉 완전히 동일하지 않은 글씨는 완전히 새로운 글씨로 취급해버리는 것인데

이렇다면 그 사이의 지점들에 대해 문제가 발생한다.

그래서 인코더에게 각 글씨들의 점을 뽑을 때 특정 분포(정규분포)의 범위 안에 놓이도록 규칙을 설정한다.

 

이제 전반적인 내용을 쉽게 풀어서 이해해보았으니 세부 수식과 이론을 살펴보자.


Figure 1 설명

논문에서 가장 처음 나오는 그림인 아래 figure 1을 살펴보자.

위에서 얘기했듯 $z$는 공간의 점, $x$는 결과(글씨)이다.

$\phi , \theta$는 가중치이다.

 


실선의 의미

실선은 데이터($x$)가 만들어지는 과정을 의미한다.

자세히 알아보자.

 

위에서 점을 특정 분포의 범위 안에 놓이도록 한다고 했다.

따라서 글씨를 만들 점도 당연히 해당 범위 안에 있을 것이다.

$p_{\theta}(z)$는 어떤 분포에 $z$값을 넣었을 때 높이(밀도)를 얘기한다.

아래 같은 그림에서 중간에 가까운 값을 넣을 수록 높이는 높다.

주의할 점은 확률은 아니라는 것이다.

확률분포에서 특정 값을 넣으면 확률은 0이다.

 

 

 

따라서 해당 $z$를 바탕으로 어떤 글씨 $x$가 만들어질 확률은 아래와 같다.

$p_\theta(x|z)$

이 과정이 디코더가 하는 일이다.


점선의 의미

점선은 반대로 데이터($x$)를 보고 원인을 찾아가는 것을 의미한다.

$q_\phi(z|x)$

실제 이미지 $x$를 입력받아서 그 안의 특성 $z$를 추측하는 분포이다. 즉 인코더이다.

 

우리가 진짜 알고 싶은 것은 정답 분포, $p_\theta(z|x)$이지만, 이는 계산 불가능하다.

데이터 $x$가 나타날 확률을 구하려면 모든 $z$에 대해 적분을 해야하는데 신경망이 들어간 구조에서는 수학적으로 불가능하기 때문이다.

따라서 우리가 최대한 정답과 가깝게 맞추려고하는 가짜 정답 $q$를 도입한 것이다.


The variational bound

$p_\theta(x^{(i)})$에 대해 생각해보자.

이 식의 의미는 우리의 디코더 모델($p_\theta$)이 어떤 글씨($x*{(i)}$)를 받았을 때, 이 글씨를 똑같이 그릴 수 있는 확률이다.

따라서 이 값이 큰 것이 좋을 것이다.

위에서 설명한 이유로 인해 이를 계산할 수 없기 때문에 식을 변형한다.

 

일단 $x$의 확률은 모든 $z$에 대해 $z,x$가 동시에 일어날 확률을 더한 것이다.

$$\log p_\theta(x) = \log \int p_\theta(x, z) dz$$

위 아래에 동일한 값을 곱해 식을 변형한다.

$$\log p_\theta(x) = \log \int q_\phi(z|x) \frac{p_\theta(x, z)}{q_\phi(z|x)} dz$$

 

이산적인 변수에서 평균을 구할 때 변량의 값과 그 값이 나올 확률을 곱해서 더하는 것처럼,

$\int q(z) f(z) dz$의 뜻은 "분포 $q$를 따르는 변수 $z$에 대한 $f(z)$의 기댓값($\mathbb{E}$)"이다.

 

따라서 위의 식을 

$$\log p(x) = \log \mathbb{E}_{q(z|x)} \left[ \frac{p(x, z)}{q(z|x)} \right]$$로 바꿀 수 있다.

 

여기서 한가지 내용이 또 필요하다.

로그 함수는 위로 볼록하므로 두 값의 평균을 로그에 넣은 것이,

이 두 값 각각의 로그 값의 평균보다 크다.

아래 그림을 참고하면 좋다.

출처 : https://datalabbit.tistory.com/159

식으로 쓰면 아래와 같다.

$$\log \mathbb{E}[\dots] \geq \mathbb{E}[\log (\dots)]$$

 

위에서 계산했던 식을 이에 대입하면 

$$\log p(x) \geq \mathbb{E}_{q(z|x)} \left[ \log \frac{p(x, z)}{q(z|x)} \right]$$가 된다.

 

굳이 이렇게 복잡하게 바꾼 이유는 $p(x)$는 위에서 얘기했듯 계산이 안되고,

인코더 식 ($q$)를 사용해서 $z$만 몇 개 샘플링 해 평균을 내면 바로 식이 계산이 되기 때문이다.

 

이 식에서 우변을 ELBO(변분 하한)라고 부른다.

우리의 목적은 이 값을 최대한 끌어올려 우리가 직접 구할 수 없는 $p$에 최대한 가까운 하한을 만드는 것이다.

 

여기서 ELBO를 조금 더 바꿔보자.

$\mathbb{E}_{q(z|x)} \left[ \log \frac{p(x, z)}{q(z|x)} \right]$를 먼저 아래처럼 바꾼다.

$$\mathbb{E}_{q(z|x)} \left[ \log \frac{p(x|z)p(z)}{q(z|x)} \right]$$

 

로그의 성질을 사용해 식을 분리한다.

$$\mathbb{E}_{q(z|x)} [ \log p(x|z) ] + \mathbb{E}_{q(z|x)} \left[ \log \frac{p(z)}{q(z|x)} \right]$$

 

여기서 로그는 마이너스를 붙이고 로그 안의 분자 분모를 바꿀 수 있으므로 아래처럼 표현하면,

이 식은 KL Divergence의 식과 같아진다.

$$-\mathbb{E}_{q(z|x)} \left[ \log \frac{q(z|x)}{p(z)} \right] = -D_{KL}(q(z|x) || p(z))$$

 

KL Divergence는 두 확률분포의 차이를 계산하는데 사용되는 함수이다.

조금 더 자세한 설명은 아래 링크를 참고하기 바란다.

KL Divergence 설명

 

그래서 ELBO($\mathcal{L}$)는 아래처럼 쓸 수 있다.

$$ \mathcal{L} = {\mathbb{E}_{q(z|x)} [ \log p(x|z) ]} {- D_{KL}(q(z|x) || p(z))}_{}$$

첫 번째 항은 인코더가 뽑은 $z$를 넣었을 때 디코더가 원래 $x$를 얼마나 잘 그리는지를 측정하고,

두 번째 항은 인코더의 분포($q$)가 우리가 정한 기준($p(z)$)와 얼마나 닮았는지 측정한다.

 

 

ELBO에 파라미터까지 넣어서 식을 써보면, 

$$\mathcal{L}(\theta, \phi; x^{(i)}) = \mathbb{E}_{q_\phi(z|x^{(i)})} \left[ \log \frac{p_\theta(x^{(i)}, z)}{q_\phi(z|x^{(i)})} \right]$$가 된다.

방금 과정대로 식을 쪼개서 정리하면 아래와 같다.

$\mathbb{E}_{q_\phi(z|x^{(i)})} [ \log p_\theta(x^{(i)}) ]+ \mathbb{E}_{q_\phi(z|x^{(i)})} \left[ \log \frac{p_\theta(z|x^{(i)})}{q_\phi(z|x^{(i)})} \right]$

 

이때 두번째 항은 방금 과정처럼 KL Divergence로 바꾸고, 첫 째항의 [ ]안에 $z$가 없기 때문에 평균 기호를 없애면,

$\mathcal{L} = \log p_\theta(x^{(i)}) - D_{KL}(q_\phi(z|x^{(i)}) || p_\theta(z|x^{(i)}))$

이다.

 

이항을 하면 논문의 2.2파트의 (1)식이 나오게 된다.

$$\log p_\theta(x^{(i)}) = D_{KL}(q_\phi(z|x^{(i)}) || p_\theta(z|x^{(i)})) + \mathcal{L}(\theta, \phi; x^{(i)})$$

 

의미를 살펴보자.

전체 성능은 우리가 계산할 수 있는 값(ELBO)와 우리가 모르는 오차(KL)의 합이라는 의미이다.

ELBO는 인코더와 디코더를 통해 계산할 수 있고, KL은 계산이 불가능하지만 수학적으로 KL Divergence는 0 이상이라는 점은 안다.

이 항상 0이상이라는 속성 덕분에 ELBO는 실제 성능의 하한선이 되고 이를 최대한 키우는 것이 목표이다.

$$\log p_\theta(x^{(i)}) = D_{KL}(q_\phi(z|x^{(i)}) || p_\theta(z|x^{(i)})) + \mathcal{L}(\theta, \phi; x^{(i)}) \geq \mathcal{L}(\theta, \phi; x^{(i)}) $$

그러나 이론은 이렇지만 실제로 적용하려하면 문제가 있다.

 

 

$$\mathcal{L}(\theta, \phi; x^{(i)}) = \mathbb{E}_{q_\phi(z|x^{(i)})} \left[ \log p_\theta(x^{(i)}, z) - \log q_\phi(z|x^{(i)}) \right]$$

위의 과정을 통해 나온 식을 다시 쓰면 아래와 같다.

$$\mathcal{L} = -D_{KL}(q_\phi(z|x^{(i)})||p_\theta(z)) + \mathbb{E}_{q_\phi} [\log p_\theta(x^{(i)}|z)]$$

근데 $q_{\phi}$가  $\mathbb{E}_{q_\phi}$에 붙어있다.

이 의미는 샘플을 뽑는 방식에 $\phi$가 관여한다는 것이다.

이 '샘플링'은 미분을 계산할 수 없기 때문에 문제가 있다.


재매개변수화

이 $z$를 뽑는 샘플링 과정은 확률 분포 $q_\phi(z|x)$에서 직접 $z$를 뽑기 때문에 $\phi$에 대한 미분이 불가능하다.

따라서 무작위성을 나타내는 변수 하나를 추가해 $z \sim q_\phi(z|x)$를 결정론적 함수 $z = g_\phi(\epsilon, x)$로 나타낸다.

이 $\epsilon$이 무작위성을 나타내는 변수이고, $\phi$와 독립적이다.

이 값은 고정된 분포 $p(\epsilon)$을 따른다$g_\phi(\cdot)$: $\phi$에 의해 파라미터화된 벡터 함수이다.

이렇게 하면 몬테카를로 추정치가 $\phi$에 대해 미분가능 해진다.

 

말이 어려우니 간단한 예시를 보자.

$z \sim \mathcal{N}(\mu, \sigma^2)$ 이 있다고 하면,

$z = \mu + \sigma \epsilon$ ( $\epsilon \sim \mathcal{N}(0, 1)$ )으로 바꾸는 것이다.

이렇게 하면 $z$는 $\mu$와 $\sigma$에 대한 선형 결합이 되므로 역전파 시 그래디언트 계산이 가능하다.

 

논문에서는 어떤 분포 $q_\phi(z|x)$에 대해 $g_\phi(\cdot)$를 선택할 수 있는지 세 가지 방법을 얘기한다.

1. inverse CDF : 확률 변수의 누적분포 함수(CDF)의 역함수를 사용하는 방법.

2. location-scale : 방금 전 본 예시와 같은 방식이다. 평균이 0이고 표준편차가 1인 표준 분포에서 노이즈 $\epsilon$을 뽑는다. 여기에 인코더가 예측한 Scale(척도, $\sigma$)을 곱하고 Location(위치, $\mu$)을 더하면 된다.

3. composition : 복잡한 분포를 여러 변수들의 조합을 만드는 방식이다.


SGVB, AEVB

위 기법을 사용해 식을 아래처럼 바꿀 수 있다.

컴퓨터는 적분을 계산할 수 없으므로 이산적 평균을 사용했다.

$$\mathbb{E}_{q_\phi(z|x^{(i)})} [f(z)] = \mathbb{E}_{p(\epsilon)} [f(g_\phi(\epsilon, x^{(i)}))] \simeq \frac{1}{L} \sum_{l=1}^L f(g_\phi(\epsilon^{(l)}, x^{(i)}))$$

 

이를 ELBO에 적용하면, 

$$\tilde{\mathcal{L}}^A(\theta, \phi; x^{(i)}) = \frac{1}{L} \sum_{l=1}^L \left( \log p_\theta(x^{(i)}, z^{(i,l)}) - \log q_\phi(z^{(i,l)}|x^{(i)}) \right)$$

 

이 식은 모든 항을 샘플링으로 처리한다.

하지만 위에서 본 KL항을 수학적으로 계산해서 효율적으로 식을 계산할 수 있다.

$$\tilde{\mathcal{L}}^B(\theta, \phi; x^{(i)}) = -D_{KL}(q_\phi(z|x^{(i)}) || p_\theta(z)) + \frac{1}{L} \sum_{l=1}^L \log p_\theta(x^{(i)}|z^{(i,l)})$$

첫번째 KL항은 수학식으로 바로 계산되고, 두번째 항은 뽑힌 $z$를 넣었을 때 원래 $x$가 얼마나 잘 복원된는지를 얘기한다.

 


실제 구현

가장 간단한 가정으로 $p_\theta(z) = \mathcal{N}(z; 0, I)$, 잠재 변수 $z$가 평균 0, 분산 1인 표준 정규분포를 따른다고 가정한다.

인코더는 $x$를 입력받아 $z$의 분포 파라미터인 평균과 분산을 뱉는다.

디코더는 $z$를 입력받아 다시 원본 데이터 $x$가 나올 확률분포의 파라미터를 뱉는다.

 

인코더와 $z$가 따르는 분포가 모두 가우시안일 때 KL항은 아래처럼 적분 기호 없이 간단해진다.

$$-D_{KL}(q_\phi(z|x) || p_\theta(z)) = \frac{1}{2} \sum_{j=1}^J (1 + \log(\sigma_j^2) - \mu_j^2 - \sigma_j^2)$$

이 식은 인코더가 만든 평균은 0, 분산은 1에 가깝게 강제하는 역할을 한다.

 

디코더는 데이터 타입에 따라 달라진다.

MNIST처럼 0~1사이의 픽셀값을 가질 때는 디코더는 해당 픽셀이 칠해질 확률(또는 칠해짐의 정도) $p$를 뱉는다.

이 경우 loss는 Binary Cross Entropy를 사용한다.

 

컬러 사진과 같은 경우 각 픽셀이 평균,분산을 가진 정규분포에서 샘플링 되었다고 보는데, 이 때는 평균을 뱉는다.(분산은 상수로 고정 또는 학습할지 정한다)

이 때는 Mean Square Error를 사용한다.

 


흐름 정리

모델을 학습시키고 새로운 데이터를 생성시키는 흐름이다.

학습 시: $x \rightarrow \text{Encoder} \rightarrow z \rightarrow \text{Decoder} \rightarrow x'$

생성 시: $\text{Prior}(\mathcal{N}(0, 1)) \rightarrow z \rightarrow \text{Decoder} \rightarrow x_{new}$

 

잘 보면 생성 시에는 인코더가 필요없는 것을 알 수 있다.