본문 바로가기

Deep Learning(강의 및 책)/CS231

Lecture 13. Generative Models

728x90

이번 강의에서는 비지도 학습의 일종인 생성 모델(generative model)에 대해서 배웁니다.

 

총 3가지의 생성 모델(pixel RNN and pixel CNN, Variational Autoencoders(VAE), Generative Adversrial Networks(GAN))에 대해서 배웁니다.

먼저 지도학습과 비지도 학습의 차이에 대해서 설명합니다. 지도 학습에서는 데이터 x, 레이블 y가 있습니다. 지도 학습의 목적은 데이터 x를 레이블 y에 mapping 하는 함수를 배우는 것입니다. 레이블의 형태는 여러 가지가 있습니다. 예를 들어 classification 문제의 경우 이미지가 input이 되고 출력은 클래스 레이블이 됩니다. Object detection 문제에서는 input으로 image, output의 경우 각 객체들의 bounding box가 됩니다. Semantic segmentation에서는 모든 픽셀마다, 각 픽셀이 속하는 카테고리를 결정합니다. Image caption은 output이 한 문장이 됩니다.

비지도 학습의 경우 레이블이 없는 학습 데이터만 가지고 데이터에 숨어있는 기본적인 구조를 학습시키는 방식입니다.

 

비지도 학습의 예로는 군집화(clustering)가 있습니다. 군집화의 목표는 일정 metric을 가지고 유사한 데이터들끼리 group을 만들어주는 것입니다. 대표적인 예로 K-mean clustering이 있습니다.

 

비지도 학습의 또 다른 예로 차원 축소(dimensionality reduction)가 있습니다. 차원 축소 문제에서는 학습 데이터가 가장 많이 퍼져있는 축을 찾아냅니다. 그렇게 찾아낸 축은 데이터에 숨어있는 구조의 일부분이라 할 수 있습니다. 이 방법은 데이터의 차원을 감소시키는 데 사용 가능합니다. 데이터는 축소된 차원에서도 중요한 정보들을 잘 보조해야 합니다. 위 예시를 보면 3차원 데이터를 두 개의 축을 찾아 2차원으로 축소시키는 모습입니다.

 

비지도학습의 또 다른 예는 데이터의 feature representation을 학습하는 것입니다. 전에 배운 분류 문제와 같은 supervised loss를 이용한 feature representation을 배웠는데 이 경우 분류를 위한 레이블이 있고 softmax loss 등을 사용합니다. 그렇게 네트워크를 학습시켜 FC layer의 feature를 데이터의 feature representation으로 사용합니다. 비지도 학습의 경우는 autoencoder가 있는데. AE(AutoEncoder)의 loss는 입력 데이터를 얼마나 잘 재구성했는지를 의미하는데 이를 이용해 feature를 학습시킬 수 있습니다. AE를 사용하면 추가적인 레이블 없이도 feature representation을 학습시킬 수 있습니다.

 

마지막 비지도학습의 예로 분포 추정(density estimation)이 있습니다. 이는 데이터가 가진 기본적인 (underlying) 분포를 추정하는 방법입니다. 위 예시를 보면 1차원 점들이 있습니다. 그리고 이 점들의 분포를 가우시안(gaussian)으로 추정합니다. 그리고 아래를 보면 2차원 데이터에 대한 예시입니다. 2차원 데이터의 분포를 추정한 모습입니다. 점들이 더 많이 밀집되어 있는 곳의 분포가 더 크도록 이들의 분포를 적절히 모델링할 수 있습니다.

 

지도/비지도 학습의 차이점을 요약한 내용입니다. 지도 학습의 경우에는 레이블을 통해 x에서 y로 가능하게 하는 함수를 이용해 mapping을 합니다.

비지도 학습의 경우에는 레이블이 없는 대신 데이터의 숨겨진 구조를 학습합니다. 군집화, 변화의 중심축 혹은 데이터의 밀도 추정 등이 있습니다. 비지도 학습은 데이터에 대한 비용이 아주 적습니다. 레이블이 없기 때문에 데이터를 아주 많이 모을 수 있습니다. 레이블이 있는 데이터보다 데이터를 훨씬 수월하게 수집할 수 있기 때문입니다.

 

생성 모델에 대해서 이제 말을 합니다. 생성모델은 비지도 학습의 일종으로 생성 모델의 목적은 동일한 분포에서 새로운 샘플들을 생성해 내는 것입니다. 데이터가 있고 이 데이터의 분포를 p_data라 하겠습니다. 우리가 하는 것은 p_model을 학습시키는 것입니다. p_model이 p_data와 같은 데이터를 생성하도록 하는 것입니다. 이를 위해서 최대한 p_model을 p_data와 유사하게 만들어야 합니다.

생성 모델에서는 분포 추정(density estimation)을 다뤄야 합니다. 학습 데이터의 근본이 되는 분포를 추정해야 한다는 말입니다. 분포 추정에는 몇 가지 방법이 있습니다. 먼저 생성 모델 p_model의 분포가 어떨지를 명시적(explicitly)으로 정의해주는 방법이 있습니다. 또 다른 방법은 간접적으로 정의해주는 방법인데 이 경우 모델 p_model에서 샘플을 만들어내도록 학습시키는 것은 동일하지만, p_model의 분포를 정의하진 않습니다.

 

그럼 왜 생성 모델을 사용할까? 위 그림들은 생성 모델을 이용해 이미지를 만들어낸 모습입니다. 생성 모델을 이미지에 적용하면 super resolution이나 colorization과 같은 테스크에 적용 가능합니다. colorization에 대한 위 예시를 보면 지갑의 밑그림만 그려 놓으면 생성 모델이 색을 채워주어 지갑이 실제로 어떻게 생겼을지 알 수 있습니다. 또한 생성 모델은 강화 학습을 이용한 시뮬레이션이나 플래닝(planning)을 위한 시계열 데이터 생성에도 이용될 수 있습니다. 생성 모델을 학습하면 latent representation을 추정해 볼 수도 있습니다. 데이터의 잠재적인 특징들(latent features)을 잘 학습시켜 놓으면 추후 다른 테스크에도 아주 유용하게 사용 가능합니다.

 

위 그래프를 보면 생성 모델들의 종류를 볼 수 있습니다. 생성모델은 위와 같이 분류 가능합니다. 명시적/간접적 모델로 구분할 수 있습니다. 그리고 그 밑으로 다양한 서브 카테고리로 쪼갤 수 있습니다.

 

먼저 PixelRNN 그리고 PixelCNN에 대해서 배웁니다.

 

pixelRNN/CNN은 fully visible brief network의 일종입니다. 여기에서는 분포를 명시적으로 정의하고 모델링합니다. 이미지 데이터 x가 있고 x에 대한 확률(likelihood)인 p(x)를 모델링합니다. 이 모델의 경우 chain rule로 likelihood p(x)를 1차원 분포들 간의 곱의 형태로 분해합니다.

분해하면 픽셀 x_i에 대해서 각각 p(x_i | conditions)를 정의할 수 있습니다. condition은 이전의 모든 픽셀 x1 ~ x_(i-1)이 붙게 됩니다. 이미지 내의 모든 픽셀에 대한 joint likelihood는 모든 픽셀의 likelihood의 곱 형태가 됩니다. likelihood p(x)를 정의했으면 이제 모델을 학습시키기 위해 학습 데이터의 likelihood를 최대화시키면 됩니다.

픽셀 값에 대한 분포를 보면 p(x_i given, 이전의 모든 픽셀)입니다. 이 분포는 아주 복잡합니다. 그래서 Neural network를 사용해 이 복잡한 분포에 대해서 표현합니다.

 

PixelRNN은 기본적으로 이 문제를 풀기 위해 고안된 방법입니다. 이 모델은 이미지의 좌상단 코너에 있는 픽셀부터 생성을 시작합니다. 위 그림에 보이는 그리드가 이미지의 픽셀들이라 보면 됩니다. 이 모델은 화살표 방향으로의 연결성을 기반으로 순차적으로 픽셀을 생성해냅니다. 그리고 이러한 방향성을 기반으로 픽셀들 간의 종속성을 RNN을 이용하여 모델링합니다. RNN모델 중에서도 우리가 다룬 LSTM 모델을 이용합니다. 이런 방식으로 대각선 아래 방향으로 계속 내려가면서 픽셀들을 생성해냅니다. 이 모델은 연결성을 기반으로 한 종속성을 가진 채 진행됩니다.

이러한 방법은 잘 동작하지만 순차적인 생성 방식이기 때문에 아주 느립니다 .새로운 이미지를 생성하고자 한다면 여러 번의 feed forward를 거쳐야 합니다. 모든 픽셀이 생성될 때까지 반복적으로 네트워크를 수행해야 합니다.

 

PixelRNN이 등장한 후 PixelCNN이라는 또 다른 모델이 제안되었습니다. PixelCNN의 기본적인 문제 세팅 자체는 PixelRNN과 동일합니다. 왼쪽 코너에서부터 새로운 이미지를 생성합니다. 하지만 PixelCNN은 RNN이 아닌 CNN으로 모델링합니다. 이제는 픽셀을 생성할 때 특정 픽셀만을 고려합니다. 위 그림에서 회색 지역이 이미 생성된 픽셀들인데, 이들 중에서도 특정 영역만을 사용하여 다른 픽셀 값을 생성합니다.

PixelCNN에서는 각 픽셀에서 CNN을 수헹합니다. CNN에서는 출력 값을 가지고 softmax loss를 개선할 수 있습니다. 여기서 레이블은 0 ~ 255가 됩니다. 학습을 통해 likelihood가 최대가 되도록 할 것입니다. 이렇게 픽셀을 생성하는 과정에서 각 픽셀 값은 정답 값(ground truth)을 가지고 있을 것입니다. 이 정답 값은 0 ~ 255 사이의 분류 문제를 풀기 위한 레이블이라고 볼 수 있습니다. 따라서 softmax loss로 학습시킬 수 있습니다. 그리고 이런 학습 과정은 기본적으로 likelihood를 최대화하는 것과 같습니다.

이 방법은 이미지 내의 각 픽셀들의 분포를 알아내는 방법입니다. likelihood를 최대화하도록 잘 학습시켜 입력인 train data를 잘 생성하도록 합니다. 이를 위해 input data를 loss로 사용합니다.

PixelCNN이 pixelRNN보다 더 빠릅니다. train time에서는(모든 픽셀들에 대해서) 학습 데이터의 likelihood를 최대화합니다. 학습 데이터는 이미 우리가 알고 있는 값이기 때문에 학습 과정을 병렬화시킬 수 있습니다. 그래서 좀 더 빠릅니다. 하지만 새로운 이미지를 생성해야 하는 test time의 경우 여전히 코너에서부터 시작해야 하고 이 생성 방법에 대한 새로운 방법은 없었기 때문에 여전히 현재 픽셀을 생성하려면 이전 픽셀부터 순차적으로 처리해야 했습니다. 즉 학습은 빠를 수 있어도 이미지를 생성하는 시간은 여전히 오래 걸렸습니다.

처음 픽셀의 분포를 정하는 것은 매우 중요합니다. 이 값에 따라 모든  분포에 영향을 미칩니다. train time에서 초기 픽셀의 분포 선택은 학습 데이터의 픽셀 값을 가져오면 됩니다. test time에서는 uniform distribution을 사용할 수도 있고, 첫 픽셀만 학습 데이터에서 가져올 수도 있습니다. 초기값만 설정하면 나머지 값들은 알고리즘을 수행해 정해집니다.

 

위 이미지들은 PixelCNN으로 생성한 이미지들입니다. CIFAR-10과 ImageNet으로 학습해 만들어낸 이미지입니다. 결과를 보면 자연스러워 보이지만 여전히 개선해야할 점이 많습니다. 학습 이미지와 분명한 차이점이 존재하고 실제 의미론적인 부분이 명확하지 않음을 알 수 있습니다.

 

PixelRNN/CNN은 likelihood p(x)를 명시적으로 계산하는 방법입니다. 우리가 최적화시킬 수 있는 분포를 명시적으로 정의합니다. 이렇게 분포를 명시적으로 정의하는 경우의 추가적인 장점이 있다면 evaludation metric를 만들 수 있다는 점입니다. 우리가 데이터를 통해 계산할 수 있는 likelihood를 이용하면 생성된 샘플이 얼마나 잘 만들어졌는지를 평가할 수 있습니다. 하지만 큰 단점으로 이미지를 순차적으로 생성하기 때문에 느리다는 점입니다.

 

이번에는 VAE(Variational Autoencoders)에 대한 설명입니다.

 

PixelCNN의 경우 계산이 가능한 확률모델을 기반으로 합니다. 학습 데이터의 likelihood를 직접 최적화하는 방식입니다. VAE의 경우에는 직접 계산이 불가능한(intractable) 확률 모델을 정의합니다. 추가적인 잠재 변수(latent vatiable) z를 모델하는 방식을 이용합니다. VAE에서는 data likelihood px(d)가 적분 형태를 띠고 있습니다. 가능한 모든 z값에 대한 기댓값을 구하는 방식입니다. 하지만 이 식을 직접 최적화시킬 수 없습니다. 대신 이 likelihood p(x)의 하안(lower bound)을 구해서(detrive) 최적화시켜야 합니다.

 

VAE는 autoencoder(AEs)라는 비지도학습 모델과 관련 있습니다. 우선 autoencoder는 데이터 생성이 목적이 아닙니다. AE는 레이블 되지 않은 학습 데이터로부터 저차원의 feature representation을 학습하기 위한 비지도 방법입니다. input data x가 있고 어떤 feature 'z'를 학습하길 원하는 모습입니다. 여기에서 encoder는 input data x를 feature z로 변환하는 mapping function의 역할을 합니다.

일반적으로 encoder로 Neural network를 사용합니다. 2000년 대에는 Linear + nonlinearirty를 이용한 모델을 주로 사용했고 그 이후로는 FC-layer를 사용한 더 깊은 네트워크를, 그 후에는 더 나아가 CNN을 사용했습니다.

일반적으로 z는 x보다 작습니다. 그래서 기본적으로 AE를 통해 차원 축소의 효과를 기대할 수 있습니다. z가 data x의 가장 중요한 feature를 잘 담고 있어야 하기 때문에 z가 x보다 더 작도록 합니다. z가 data x의 중요한 요소들이 담겨있는 feature들을 학습하길 원한다는 말입니다.

 

AE는 원본을 다시 복원(reconstruct)하는데 사용될 수 있는 feature들을 학습하는 방식을 취합니다. AE의 과정을 살펴보면, input data x가 있고 encoder는 x를 더 낮은 차원의 z로 mapping 합니다. z가 바로 encoder의 출력이 됩니다. input data로부터 만들어진 feature z는 두 번째 네트워크인 decoder에 사용됩니다. decoder의 출력은 input x와 동일한 차원이고, x와 유사해야 합니다. 즉 원본 데이터를 복원한다 말할 수 있습니다.

decoder는 기본적으로 encoder과 동일한 구조를 지닙니다. 즉 이 둘은 대칭적이여야 하는데 대개 CNN으로 구성합니다.

 

input data x가 encoder에 input으로 들어갑니다. encoder는 예를 들어 4-layer CNN이 될 수 있습니다. 이렇게 encoder를 거쳐 feature z를 얻으면, z를 decoder에 통과시킵니다. decoder는 upconv가 되면 될 것입니다(저차원 z를 고차원으로 복원하기 위해).

다시 복원하기 위해선 L2같은 loss함수를 이용합니다. L2 loss는 "복원된 이미지의 픽셀 값과 입력 이미지의 픽셀 값이 서로 같았으면 좋겠다"라는 의미를 담고 있습니다. 

AE는 loss가 필요하긴 하지만 train 과정에서 추가적인 label은 필요하지 않습니다. 학습 때 사용하는 것은 레이블이 없는 input data 뿐이며, input data x로만 네트워크를 통과시키고 Loss도 계산합니다.

 

decoder는 train time에 입력을 복원해서 loss함수를 계산하는 용도로만 쓰이기 때문에 train이 끝나면 decoder는 버려도 됩니다. 결국 encoder만 사용하는데, encoder가 학습한 feature mapping을 지도 학습 모델의 초기값으로 사용할 수 있습니다. encoder가 input x를 feature z에 mapping 하면 그 위로 추가적인 classifier를 붙입니다. 클래스 레이블을 출력해야 하는 분류 문제로 바뀌게 됩니다. 이 경우 loss 함수는 softmax가 되면 됩니다.

 

AE는 많은 레이블링 되지 않은 데이터로부터 양질의 general feature representation을 학습할 수 있는 장점이 있습니다. 이렇게 학습시킨 feature representation을 데이터가 부족한 지도학습 모델의 초기 가중치로 이용할 수도 있습니다. 데이터 양이 적으면 학습이 힘듭니다(overfitting이 일어날 수도 있고 다양한 문제가 존재). 이 경우 AE는 지도 학습 모델이 더 좋은 feature로 초기화될 수 있도록 도와줍니다. 즉, AE는 입력을 복원하는 과정에서 feature를 잘 학습했고 학습된 feature는 지도 학습 모델의 초기화에 이용 가능합니다. 이러한 AE의 특징을 보면 AE가 학습 데이터의 variation을 잘 포착해낼 수 있다는 것을 알 수 있습니다. 즉 잠재 변수인 vector z가 학습 데이터의 variation을 잘 가지고 있습니다.

 

이젠 AE와 조금 관점이 다른 VAE에 대한 내용입니다. 새로운 데이터를 생성할 것이고 이를 위해 모델로부터 데이터를 샘플링합니다.

VAE에 train data xi가 있습니다. i는 1부터 N까지 될 것이고 이 학습 데이터가 우리가 관측할 수 없는 어떤 잠재 변수 z(latent representation z)에 의해 생성된다고 가정합니다. z는 어떤 vector인 것이 point입니다. 이 벡터 z의 각 요소들은 데이터의 변동 요소들을 잘 포착해내고 있습니다.

만약 얼굴을 생성할 때의 feature라고 한다면 생성된 얼굴이 얼마나 웃고 있는지, 눈썹의 위치, 머리의 방향 등이 될 수 있습니다. 이러한 속성들이 모두 학습될 수 있는 잠재된 요소라 할 수 있습니다. 생성과정에서는 z에 대한 prior로부터 샘플링을 수행할 것입니다. 얼마나 웃고 있는지와 같은 속성을 담기 위해서는 이러한 속성들이 어떤 distribution을 따르는지에 대한 prior를 정의해야 합니다. z에 대한 prior로 gaussian distribution을 선택할 수도 있습니다. P(x given z)로부터 샘플링하여 데이터 x를 생성해냅니다.

 

이 생성 모델의 true parameter는 theta star입니다. prior와 conditional distribution에 대한 parameter가 있습니다. 생성모데이 새로운 데이터를 잘 생성하게 하려면 true parameter를 잘 추정해야 합니다. prior인 P(z)는 gaussian처럼 간단한 모델을 선택하기도 합니다.

conditional distribution, P(x given z)는 조금 더 복잡합니다. p(x given z)를 가지고 이미지를 생성하기 때문에 좀 더 복잡합니다. Neural network를 이용해 생성하면 됩니다. 위 그림에서 decoder는 z를 받아서 이미지로 디코딩하는 역할을 합니다.

 

모델들의 parameter를 추정하기 위해서는 모델을 학습시킬 수 있어야 합니다. 학습을 시키는 가장 간단한 방법은 model parameter가 학습 데이터의 likelihood를 최대화하도록 학습시키는 것입니다. VAE의 경우 잠재변수 z가 있습니다. p(x)는 모든 z에 대한 기댓값으로 나타냅니다.

 

이러한 방식은 적분을 이용하는데 적분식은 계산할 수 없다는 문제가 있습니다.

 

그래서 새로운 방식이 나옵니다. 위 식을 먼저 보면 데이터에 대한 likelihood가 등장합니다. 첫 항은 p(z)입니다. p(z)의 prior은 gaussian prior로 정했습니다.

 

p(x given z)는 우리가 정의한 decoder neural network입니다. 따라서 z가 주어지기만 하면 모든 p(x givne z)를 얻어낼 수 있습니다. p(x given z)는 neural network의 output입니다.

모든 z에 대해서 p(x given z)를 계산하고 싶지만 이 부분을 계산할 수 없습니다.

 

 
 

data likelihood를 계산할 수 없기 때문에 posterior density로 나타내보면 p(z given x) = p(x given z) * p(z) / p(x)와 같이 베이즈 룰로 표현할 수 있습니다. 하지만 이 경우 또한 연산이 어렵습니다. p(x given z)는 괜찮지만 p(x)에 들어가는 적분이 계산하기 힘듭니다.

 

따라서 p(x)를 직접 최적화하는 것은 어렵기 때문에 decoder network가 p(x given z) 말고도 추가적인 encoder network를 정의하는 방식으로 이 문제를 해결합니다.

encoder는 q(z given x)를 만듭니다. encoder를 이용해 input x를 z로 인코딩합니다. 이 encoder network(q)를 통해서 p(z given x)를 근사 시킵니다. 이를 통해 data likelihood의 하안(lower bound)을 구할 수 있고 이를 통해 계산이 가능해집니다.

 

VAE에서 우리가 하고 싶은 것은 데이터의 확률론적 생성모델을 만들고 싶은 것입니다. AE에서 encoder는 input x를 받아 z를 만들고 decoder에서는 z를 받아 다시 image를 생성했습니다.

VAE도 기본적으로 encoder/decoder 구조입니다. 그리고 여기에 확률론적인 의미가 추가됩니다.

위에서 Φ를 가진 encoder network q(z given x)를 보겠습니다. encoder의 출력은 평균과 (대각) 공분산입니다(mean & diagonal covatiance of z given x). 이 값들은 encoder network의 출력입니다.

이제 decoder를 보면 z부터 시작해서 평균과 공분산을 출력으로 합니다. p(x given z)에서 x의 차원은 input x와 동일합니다. decoder에는 parameter θ가 있습니다. 실제로 z given x와 x given z를 얻으려면 이들의 분포로부터 샘플링을 해야 합니다.

 

encoder와 decoder network는 각각 z와 x에 대한 분포를 생성해야 하며 실제 값을 뽑으려면 이 분포로부터 sampling을 해야 합니다. 위 그림을 보면 어떻게 새로운 데이터를 샘플링하고 생성해 낼 수 있는지 나와있습니다. 위에 파란 글씨를 보면 encoder/decoder 구조의 또 다른 이름들이 적혀있습니다.

 

data likelihood인 p(x)에 log를 취합니다. 그리고 p(x)에 z에 대한 기댓값(expectation)을 취합니다. z는 encoder network로 모델링한 q(z given x) 분포로부터 샘플링한 값을 의미합니다. log p(x)에 expectation을 할 수 있는 이유는 p(x)가 z에 독립적이기 때문입니다.

 

이제 이 식에 베이즈 룰을 적용하고 어떤 상수를 곱해준 모습입니다. q(z givnen x) / q(z given x)를 곱해주는데 어차피 1을 곱해주는 것과 같습니다. 마지막에 항 세 개(log항과 KL항 두개)있습니다. KL divergence는 두 분포가 얼마나 가까운지를 알려줍니다. 첫 KL 항은 q(z given x)와 p(z)가 얼마나 가까운지(분포 간의 거리의 척도)를 알려줍니다. KL 수식은 바로 위의 expectation과 동일합니다.

 

p(x given z)는 decoder network입니다. 이 첫 번째 항은 샘플링을 통해서 계산 가능합니다. 이런 샘플링 과정에서 미분이 가능하도록 하는 "re-parametrization trick"이라는 기법이 있는데 이를 통해 연산이 가능합니다. 두 번째 항을 보면 가우시안 분포 간의 KL divergence입니다. 우선 q(z given x)는 encoder에서 발생하는 분포로 평균/공분산을 가지는 가우시안 분포입니다. prior p(z) 또한 가우시안입니다. 두 분포가 모두 가우시안일 경우 closed form solution으로 풀 수 있습니다. 마지막 세 번째 항을 보면 q(z given x)와 p(z given x) 간의 KL입니다. 앞서 p(z given x)는 계산할 수 없는 항이기 때문에 q로 근사 시켰습니다. 그래서 이 항은 여전히 문제입니다.

 

하지만 KL divergence는 두 분포 간의 거리를 나타내므로 항상 0 이상의 값을 갖습니다. 따라서 앞의 두 항만 가지고 잘 해보자는 관점으로 본다면 앞의 두 항은 gradient를 이용해 최적화시켜 실질적으로 계산할 수 있는 lower bound가 됩니다. p(x given z)는 미분 가능하고 두 번째 항 KL도 close form solution으로 미분 가능하므로 연산이 가능합니다.

 

이제 VAE를 학습시키기 위해서 앞서 구한 lower bound가 최대화되도록 최적화시키면 됩니다. 즉, data likelihood의 lower bound를 최적화시키는 것입니다. 이는 data likelihood가 적어도 우리가 최적화시킨 lower vound보다는 항상 높을 것임을 의미합니다. 이제 lower bound를 최대화시키기 위해서는 parameter Φ, θ구해야 합니다.

첫 항은 모든 샘플 z에 대한 기댓값입니다. z는 encoder의 출력을 의미합니다. encoder로 z를 샘플링하고, 모든 z에 대해서 p(x given z)의 기댓값을 구합니다. 따라서 복원에 대한 것입니다. 이 첫 항이 크다는 것은 likelihood p(x given z)가 크다는 것이고 데이터를 잘 복원하고 있다는 뜻입니다.

두번째 항은 KL divergence이며 이 값은 작아야 합니다. 근사 시킨 분포 q와 prior의 분포 p가 최대한 가까워야 합니다. 다시 말해 잠재 변수 z의 분포가 prior 분포(가우시안)와 유사했으면 좋겠다는 뜻입니다.

 

lower bound에 대해 구하는 방법은 끝이 났고 이제 이를 통해 VAE를 학습하는 과정을 보겠습니다.

lower bound가 최대가 되도록 학습을 할 것입니다. 먼저 forward pass 과정을 보면 input x(mini batch)가 있습니다. x를 encoder에 통과시키면 q(z given x)가 나옵니다. 여기에서 계산한 q(z given x)는 KL divergence를 계산할 때 이용할 수 있습니다. q(z given x)를 구했으면 이 분포로부터 잠재 변수 z를 샘플링합니다.

이제 z를 decoder에 통과시킵니다. decoder network의 output은 p(x given z)에 대한 평균과 분산입니다. 이 분포를 바탕으로 샘플링을 할 수 있습니다. 이렇게 샘플링을 통해 만든 샘플 출력이 생깁니다. 그리고 training time에는 log p(x given z)가 최대가 되도록 학습하면 됩니다. 이 loss 함수가 말하고자 하는 것은 복원된 이미지에 대한 likelihood가 최대가 되었으면 좋겠다는 것입니다.

이런 식으로 모든 mini batch에 대해서 forward pass를 계산합니다. 이렇게 구한 모든 항은 미분 가능하므로 backprop도 가능합니다. gradient를 계산해 encoder/decoder의 parameter Φ, θ업데이트하고 이를 통해 train data likelihood 최대화합니다.

 

VAE를 학습시키고 나면 데이터 생성 시에는 decoder network만 필요합니다. 앞서 train time에서 z를 posterior였던 p(z given x)에서 샘플링했습니다. 생성과정에서는 posterior가 아닌 prior에서 샘플링합니다. 이를 바탕으로 data x를 샘플링합니다. 위 그림을 보면 MNIST 예제가 생성된 모습을 볼 수 있습니다.

앞서 변수 z가 데이터의 잠재적인 속성들을 나타낼 수 있다고 말했습니다. z에는 우리가 해석할 수 있는 다양한 의미가 담깁니다. 위에 데이터 manifold가 있습니다. 2차원 z공간입니다. 2차원 z 분포에서 적절한 백분위 범위에서 vary z1과 vary z2를 뽑아낸 모습입니다. z1와 z2의 조합으로 생성된 이미지들을 볼 수 있습니다. z1, z2가 변함에 따라 이미지도 부드럽게 변하고 있는 것을 볼 수 있습니다.

 

prior z는 diagonal covariance를 가정했기 때문에(각 차원을 independent 하다고 가정) z의 각 차원이 독립적이며 이로 인해 각 차원마다 독립적인 해석 가능한 요소들이 encoding 될 수 있습니다.

얼굴 이미지를 예로 보면 vary z1은 위아래로 웃음의 정도(the amount of smile)가 변하고 vary z2는 머리의 위치가 변합니다.

이를 통해 알 수 있는 점은, VAE를 학습시킨 결과, z라는 변수가 좋은 feature representation일 수 있다는 점입니다. z에는 해석 가능하고 아주 다양한 의미론적인 요소들이 잘 인코딩 되어 있기 때문입니다. 따라서 앞서 학습시킨 q(z given x) encoder network에 새로운 input x를 넣어서 z 공간으로 mapping 한다면 이 feature vector를 classification이나 다른 테스크에 사용할 수도 있습니다.

 

VAE에 대한 정리입니다. VAE는 autoencoder의 확률론적 변형 버전입니다. AE는 deterministic하게 x를 받아 z를 만들고 다시 x를 복원했다면 VAE는 데이터를 생성하기 위해 분포와 샘플링의 개념이 추가되었습니다. 그리고 계산할 수 없는 분포를 다루기 위해서 variational lower bound를 계산했습니다. variational은 계산할 수 없는 형태를 계산할 수 있도록 근사 시키는 방법(p(z given x)을 q(z given x)로 근사)을 의미합니다.

이러한 VAE와 같은 접근 방식의 이점은 생성모델에 대한 원칙적 접근(principled approach) 방법이라는 점과 모델에서 q(z given x)를 추론한다는 점입니다. q(z given x)는 다른 테스크에서도 아주 유용한 feature representation이 될 수 있습니다. VAE의 단점이 있다면, likelihood의 하안을 계산한다는 점입니다. 어느 정도는 괜찮지만 엄밀하게 pixelRNN/CNN같이 직접 최적화하는 방법보다는 부족합니다. 그리고 GAN과 같은 SOTA 생성 모델에 비해서는 샘플들이 blurry 하고 퀄리티가 낮습니다.

 

마지막으로 GAN 입니다.

 

pixelRNN/CNN은 계산 가능한 확률분포를 가정했습니다. 그리고 이를 이용해 학습 데이터의 likelihood를 최적화했습니다. 반면 VAE의 경우, 잠재 변수 z를 두고 생성 과정을 정의했습니다. 잠재변수 z는 많은 이점이 있지만, 결국 VAE는 계산할 수 없는 확률분포를 가정하기 때문에 likelihood를 직접 최적화시키지 못하고 대신 lower bound를 최적화시켰습니다.

 확률분포를 직접 모델링하는 방법을 아예 포기한다면?? 사실 우리는 생성 모델에게 원하는 것은 샘플링을 잘하는 능력입니다. 우리가 가진 분포에서 샘플링만 잘하면 그만입니다. 이러한 접근 방식이 바로 GAN입니다.

GAN에서는 우리가 직접 확률분포를 모델링하지 않습니다. GAN에는 2 player game이라는 방식으로 학습 분포를 학습합니다.

 

GAN에서 하고자 하는 것은 복잡한 고차원 학습 분포로부터 샘플링을 하는 것입니다. 하지만 분포에서 샘플을 만들어내는 과정에 대해서 생각해보면 이를 직접 할 수 있는 방법은 없습니다. 우리가 가진 분포가 아주 복잡하기 때문에 직접 샘플링하는 것은 불가능합니다. GAN에서의 해결책은 우리가 우선 gaussian random noise 같은 단순한 분포에서 원하는 학습 분포로 변환(transormation)하는 함수를 배우는 방법입니다.

GAN에서는 input으로 random noise vector(z)를 받고 벡터의 dimension은 우리가 직접 명시해줍니다. 그리고 input z가 새성 network를 통과하면 학습 분포로부터 직접 샘플링된 값을 출력합니다. 따라서 모든 random noise 입력이 학습 분포의 샘플에 mapping 되도록 하는 것입니다.

 

두 명의 플레이어가 있는데 한 명은 generator, 다른 한명은 discriminator입니다. generator는 사실적인 이미지를 생성하여 discriminator를 속이는 것이 목표이고 discriminator는 input image가 generator가 만든 가짜 이미지인지 아닌지를 구분해내야 합니다. 

random noise가 generator의 input으로 들어갑니다. generator는 image를 생성해내는데, 이 이미지는 generator가 만든 가짜 이미지입니다. 그리고 학습 데이터에서 나온 실제 이미지도 존재하는데 discriminator는 이미지를 구별할 수 있어야 하고 generator는 더 사실적인 가짜 이미지를 만들 수 있어야 합니다.

 

이제 "minmax game"의 형태로 같이 학습을 시킬 차례입니다. 여기에 "minmax objective function"이 있습니다. 이 object function에서는 generator network인 G의 parameter θ_g는 최대화시키고 discriminator network인 D의 parameter θ_d는 최대화시켜야 합니다.

이 함수에서 말하고자 하는 것을 보겠습니다. 데이터에 대한 expectation E[log D(x)]가 있습니다. log D(x)는 real data x에 대한 discriminator의 출력 값입니다. log D(x)는 real data가 데이터 분포 p_data에 속할 likelihood입니다. 그리고 두 번째 항을 보면 p(z)를 따르는 z에 대한 expectation이 있는데 z~p(z)의 의미는 generator에서 샘플링한다는 의미입니다. 그리고 D(G(z))는 생성된 가짜 이미지(G(z))에 대한 discriminator의 출력입니다.

Discriminator는 objective function을 최대화해야 합니다. 최대화시키는 parameter θ_d를 찾아야 합니다. D(x)의 경우에는 실제 데이터이므로 값이 1이면 좋고 D(G(z))는 가짜 데이터에 대한 것이므로 0일 수록 좋습니다. 그리고 discriminator 입장에서 objective function이 최대화된다는 것은 이미지를 잘 구별한다는 뜻입니다.

generator의 입장에서 objective function이 작을수록 좋으므로 D(G(z))가 1에 가까울수록 좋습니다. D(G(z))가 1에 가까우면, 1 - D(G(z))이므로 값이 작아집니다. 이렇게 작아진다는 의미는 discriminator가 가짜 이미지를 진짜 이미지로 잘못 분류하고 있다는 뜻입니다.

 

중요한 문제가 있습니다. generator의 objective function이 학습이 잘 안 된다는 점입니다. 그 이유는 loss landscape를 보면 알 수 있습니다. 지금 보이는 loss landscape는 D(G(x))의 loss landscape입니다. generator는 1 - D(G(x))의 값이 높을수록 좋습니다. 그래프로 그려보면 위에 파란 선과 같습니다. Loss가 최소가 되도록 하고 싶은데 Loss의 기울기가 오른쪽으로 갈수록 점점 커집니다. 즉 D(G(x))가 1이 될수록 기울기도 크다는 뜻입니다. 즉 generator가 잘 속일수록 기울기도 커진다는 뜻입니다. 반대로 보면 생성된 sample의 성능이 좋지 않을 때는 기울기가 작아 학습이 잘 되지 않습니다.

그래서 이를 개선하기 위해서 objective function을 변경해줍니다. generator에서 gradient ascent를 사용합니다. 앞서 수식에서처럼 discriminator가 정답을 잘 맞힐 likelihood를 최소화시키는 방법 대신에 discriminator가 틀릴 likelihood를 최대화시키는 쪽으로 학습을 시키면 되고  이는 objective function을 log(D(G(x))를 최대화시키는 것으로 구현 가능합니다. 위 그래프에서 초록색 선을 보면 이해할 수 있습니다.

 

이번에는 학습 순서에 대한 내용입니다. discriminator를 조금 학습시키고 그다음 generator를 학습시키는 방식으로 진행됩니다. 우선 k번만큼 discriminator를 학습시킵니다. noise prior z(p(z))에서 미니 배치만큼 noise를 sampling 합니다. 그리고 학습 데이터 x에서 실제 sample을 미니배치만큼 샘플링합니다. 샘플링한 노이즈를 generator에 통과시키면 가짜이미지를 생성합니다. 그러면 미니배치만큼의 가짜 이미지와 진짜 이미지가 준비됩니다. discriminator의 gradient를 계산할 때 이렇게 준비한 진짜 가짜 이미지를 사용합니다. parameter를 update하고 discriminator를 k step 만큼 학습합니다. 어느정도 discriminator 학습이 끝나면 generator를 학습합니다. p(z)에서 noise를 sampling합니다. 그리고 sampling 된 noise를 generator에 통과시켜 최적화시킵니다.

이런 식으로 번갈아가면서 학습시킵니다. 여기서 k step은 논란이 많은데 어떤 이는 k = 1이 좋다 그러고 어떤 이는 k>1이 좋다고도 합니다.

 

위 그림은 generator가 만든 샘플들입니다. 왼쪽은 MNIST의 예시, 오른쪽에는 얼굴 이미지의 예시입니다. 그리고 제일 오른쪽 노란 박스들은 진짜 이미지이고 그 바로 옆이 가장 비슷한 이미지입니다. 이 결과를 보면 생성 모델이 진짜 같은 이미지를 잘 생성해내며 이 결과는 단순히 학습 이미지를 외운 결과가 아님을 알 수 있습니다.

 

이번에는 vector z가 의미하는 것이 무엇인지 좀 더 이해하기 위해 보여준 그림입니다. vector z를 가지고 연산한 그림입니다. 먼저 웃고 있는 여성의 이미지를 뽑아냅니다. 그리고 웃고 있지 않은 여성의 사진고 웃고 있지 않은 남성의 사진도 뽑아냅니다. 그리고 뽑은 벡터 z들에 각 평균을 취합니다. 그다음 (웃는 여성) - (웃지 않은 여성) + (웃지 않은 남성)을 해주면 웃는 남성 이미지를 얻을 수 있습니다. 기본적으로 z를 가지고 이러한 해석을 할 수 있으며 좋은 샘플도 만들 수 있습니다.

 

GAN을 요약하면 특정 확률분포를 정의하지 않았습니다. 대신에 샘플들을 활용한 암묵적인 방법을 사용했으며 게임이론에 기반한 학습을 했습니다. GAN의 장점은 퀄리티가 상당히 좋다는 점입니다. 하지만 단점은 학습시키기 까다롭고 불안정하다는 점과 objective function을 직접적으로 최적화하는 게 아니라는 점입니다.