목차
생성모델
Generative Model
- 생성 모델 은 새로운 데이터 인스턴스를 만들어냅니다.
- 판별 모델(Discriminative models) 은 다른 종류의 데이터 인스턴스를 분류합니다.
예를 들어 사진 속에서 고양이를 찾는 것은 판별 모델, 실제 고양이를 그리는 것은 생성 모델입니다.
수학적으로 표현해봅시다🧮. 주어진 데이터 집합 X와 라벨(레이블) 집합 Y가 있습니다.
- 생성 모델 은 결합 분포
p(X,Y)
를 학습하거나, 라벨이 없으면p(X)
분포만 학습합니다. - 판별 모델 은 X일때 Y일 확률, 즉 조건부 확률
p(Y|X)
를 학습합니다.
생성모델은 X에서 Y가 생성되게 학습해야 합니다. 즉,
X=Y=X∩Y
,(X∩Y)ᶜ=∅
이 되어야 합니다.
판별 모델은 X가 Y에 포힘되도록 학습해야 합니다. 즉,X∩Yᶜ=∅
이 되어야 합니다.
눈치가 빠른 사람은 생성 모델이 판별 모델보다 어렵다는 것을 발견했을 겁니다.
예를 들어 고양이를 찾는다면 주변과 구분되는 특징(꼬리...) 하나 이상만 찾으면 됩니다. 하지만 고양이 그림을 그리려면, 고양이의 모든 특징(꼬리, 귀, 눈, 털...)을 정확히 알아야 합니다.
생성 모델은 집합 X와 집합 Y를 최대한 일치시키는 방법을 찾아야 합니다.
반면에 판별 모델은 집합 Y에 속한 X만 찾으면 됩니다.
(X를 학습해야 하는 정보, Y를 고양이의 특징이라고 생각해 봅시다)
생성 모델의 종류로는 VAE, GAN, HMM, Bayesian 등이 있습니다. 판별 모델의 종류로는 k-NN, 로지스틱 회귀, SVM, 결정트리 등이 있습니다. 이 글에서 함께 생성 모델인 VAE를 살펴봅시다.🤗
배경지식
VAE를 살펴보기 전엔 확률분포, 베이즈 정리, 쿨백-라이블러 발산 배경지식이 필요합니다. 전부 아신다고요? 다음 장 으로 넘어가세요🎉
저는 개념이 지겨워서 역순으로 코드 먼저 볼 때가 많습니다
확률분포
probability distribution
확률 분포는 확률변수(x)가 특정한 값을 가질 확률을 나타내는 함수(f(x))입니다. 확률 분포는 이산확률분포(Discrete Probability Distribution) 와 연속확률분포(Continuous Probability Distribution) 로 나뉘는데요, 이산확률분포는 확률변수가 가질 수 있는 값이 가산집합인 확률분포를 말합니다. 반면에, 연속확률분포는 확률변수가 연속적이고 확률밀도함수로 표현할 수 있는 분포를 말합니다.
통계학을 들으신 분이라면 이항분포의 특수한 형태인 푸아송 분포 와 대표적인 연속확률분포인 정규분포가 어렴풋이 기억날겁니다.
정규분포(Gaussian distribution)와 연속확률분포를 조금 더 자세히 볼까요?
연속 확률 변수의 확률밀도함수(f(x))는 다음 두 조건을 만족합니다.
- 모든 실수 x에 대해 f(x)≥0
정규분포 또한 연속확률분포로 확률밀도함수의 특징을 갖습니다.
정규분포는 평균(μ, mu)과 표준편차(σ, sigma)로 분포를 표기합니다.
평균이 0이고 표준편차가 1인 정규분포 N(0,1)을 표준정규분포라 합니다. 정규분포는 정규화를 통해 표준정규분포를 얻을 수 있습니다.
각 사건이 벌어졌을 때의 이득과 확률을 곱한 값의 합을 기댓값이라고 하는데요, 연속확률변수에서 기댓값은 다음과 같습니다.
정규분포에서 기댓값을 계산해 보면 모평균과 같습니다.
베이즈 정리
Bayes' theorem
베이즈 정리는 두 확률변수의 사전확률과 사후확률 사이의 관계를 나타냅니다.
A,B는 가측집합이고 P(B)>0일 때,
조건부 확률을 통해 쉽게 증명할 수 있습니다.
P(B)>0임을 가정했으므로
첫 식에 를 이용하면
TMI
부가적으로, 사건 A와 사건 B가 독립일 때 조건부 확률
이므로
임을 알 수 있습니다.
쿨백-라이블러 발산
Kullback–Leibler Divergence
쿨백-라이블러 발산은 두 확률분포의 차이를 계산하는 함수입니다.
두 확률변수에 대한 확률분포 P, Q에 대해 쿨백-라이블러 발산은 다음과 같이 정의됩니다.
- 이산확률분포:
- 연속확률븐포:
(p,q는 각각 확률분포의 확률밀도함수입니다)
연속일때 조금 더 풀어보면 다움과 같습니다
KL divergence 눈으로 이해하기 쉬운 좋은 자료를 만들어 주셨습니다.
쿨백-라이블러 발산의 중요한 특징은 다음과 같습니다.
증명은 다음에 하겠습니다
VAE
생성 모델 구조를 봅시다.
의 확률변수가 주어졌을 때, 원하는 x값을 얻을 확률은 입니다. 우리의 목적은 일 수도 있는 근사값 를 구하는 것입니다.
주의! 는 생성기(generator)가 아닌 확률분포입니다
그렇다면 와 가장 비슷한 를 어떻게 구해야 할까요? 둘 사이의 MSE(Mean Square Error)가 최소가 되는 분포를 찾으면 가장 비슷할까요?
파란색 분포를 라고 합시다. 주황색 분포는 변형이 존재하고, 회색 분포는 x축 이동을 했습니다. 주황색과 회색 분포 중 무엇이 파란색 분포에 더 가까울까요?
회색 분포는 단순히 이동을 했기 때문에 의미적으로 파란색과 동일합니다. 하지만 파란색 분포와 다른 확률분포의 차이(MSE)를 계산하면, 오류가 있지만 더 가까이 있는 주황색 분포가 작습니다.
즉, 사전 확률(prior probability, ) 지표로 학습하면 올바르게 학습되지 않습니다. 따라서 사후 확률(posterior probability, )과 근사값 를 포함해 변분법(Calculus of Variational) 을 통해 학습합니다.
왜 앞에있는게 사후확률이야
p(z)를 바로 학습하는 것이 아니라, 이미 존재하는 결과( 사후확률)로 z를 학습합니다.
이때 근사함수 를 각각 encoder
, decoder
로 부르겠습니다.
(신경망은 각각 λ와 θ를 파라미터로 가집니다)
자, 그럼 이제 변분법을 통해 참 사후조건인 를 찾으면 됩니다! 왜 VAE인지 이제 알겠군요!😉
ELBO
Evidence Lower BOund
생성해야할 x의 분포 p(x)의 확실한 최소 경계값을 추정하고 최댓값을 구해 유사한 분포를 만들 수 있습니다.
이상적인 사후조건에 베이즈 정리를 적용해봅시다.
양변에 로그를 취합니다
로그의 성질에 따라
-1)
우리가 알고있는 근사분포 는 연속확률분포임으로
입니다.
1이 곱셈의 항등원이라는 점을 이용해 식을 변형해봅시다.
log p(x) 양변에 1을 곱하면
식1)을 사용하여
0이 덧셈의 항등원이라는 점을 이용해 식을 변형합니다. 양변에 을 더합니다. 이때, 우리가 알아낼 수 있는 것()을 생각해 짝지어 줍시다
이전식에서 양변에 0을 더하면
몬테카를로 추정과 쿨백-라이블러 발산으로 변형하면
쿨백-라이블러 발산의 특징(≥0)을 이용하면
자! 길었습니다.😅 여기에서 확실한 최소 경계 가 ELBO 입니다!
각 항의 의미는 다음과 같습니다.
- : 디코더 의 기댓값으로 재생성 에러를 나타냅니다.
- : 알수있는 파라미터로 분포를 정규화할수 있습니다.
- : 실제(참) 사후조건분포 는 계산할 수 없습니다.
따라서 앞의 두 항을 최대화하는 방법을 사용합니다.
말로만 하면 어려우니 그림을 볼까요?
에 따라
확률분포 log p(x)와 ELBO(λ)는 0 이상의 차이(거리)가 있습니다.
하지만 는 계산할 수 없으므로, ELBO를 최대화 하는 방법으로 학습합니다.
(다른말로 디코더의 기댓값 최대화, 이상적인 인코더 생성을 목표로 합니다)
Reparameterization Trick
backpropagation 문제를 해결합니다.
수학과 코드
import tensorflow_probability as tfp
# ds = tfp.distributions
... 전략 ...
q_z = self.encode(input_sequence, x_length, control_sequence)
z = q_z.sample()
# Prior distribution.
p_z = ds.MultivariateNormalDiag(
loc=[0.] * hparams.z_size, scale_diag=[1.] * hparams.z_size)
# KL Divergence (nats)
kl_div = ds.kl_divergence(q_z, p_z)
r_loss, metric_map = self.decoder.reconstruction_loss(
x_input, x_target, x_length, z, control_sequence)[0:2]
free_nats = hparams.free_bits * tf.math.log(2.0)
kl_cost = tf.maximum(kl_div - free_nats, 0)
beta = ((1.0 - tf.pow(hparams.beta_rate, tf.to_float(self.global_step)))
* hparams.max_beta)
self.loss = tf.reduce_mean(r_loss) + beta * tf.reduce_mean(kl_cost)
scalars_to_summarize = {
'loss': self.loss,
'losses/r_loss': r_loss,
'losses/kl_loss': kl_cost,
'losses/kl_bits': kl_div / tf.math.log(2.0),
'losses/kl_beta': beta,
}
return metric_map, scalars_to_summarize
Tips
Reference
What is a Generative Model?
[위키]확률 분포
[위키]베이즈 정리
[위키]쿨백-라이블러 발산