먼저, SVI 논문을 이해하는 데 도움이되는 몇 가지 메모 :
- 전역 매개 변수의 변동 매개 변수에 대한 중간 값을 계산할 때 하나의 데이터 점을 샘플링하고 크기 의 전체 데이터 세트 를 단일 점인 배로 가장합니다.엔엔
- η지 는 전역 변수 의 전체 조건에 대한 자연 매개 변수입니다 . 이 표기법은 관측 된 데이터를 포함하여 조건부 변수의 함수임을 강조하는 데 사용됩니다. β
가우시안 의 혼합에서 , 우리의 전역 매개 변수는 각각에 대한 평균 및 정밀 (역 분산) 매개 변수 매개 변수입니다. 즉, 는이 분포에 대한 자연 모수입니다.케이μ케이,τ케이η지
μ , τ~ N( μ | γ, τ( 2 α - 1 ) G a ( τ| α,β)
함께 , 및 . (Baneardo and Smith, Bayesian Theory ; 이것은 일반적으로 볼 수있는 4- 파라미터 Normal-Gamma와 약간 다릅니다 .) 우리는 을 사용하여η0= 2 α - 1η1= γ* ( 2 α - 1 )η2= 2 β+γ2( 2 α - 1 )a , b , mα , β, μ
전체 조건부 와 정상 감마이다 PARAMS , , . 여기서 는 이전입니다. (이에있는 도 혼동 될 수 있습니다. 적용되는 트릭 은 시작하는 것이 좋습니다 이며 독자에게 남은 상당한 양의 대수로 끝납니다.)μ케이,τ케이η˙+ ⟨∑엔지n , k∑엔지n , k엑스엔∑엔지n , k엑스2엔⟩η˙지n , k특급ln( p ) )∏엔p (엑스엔|지엔, α , β, γ) =∏엔∏케이( p(엑스엔|α케이,β케이,γ케이))지n , k
이를 통해 다음과 같이 SVI 의사 코드의 5 단계를 완료 할 수 있습니다.
ϕn,k∝exp(ln(π)+Eqln(p(xn|αk,βk,γk))=exp(ln(π)+Eq[⟨μkτk,−τ2⟩⋅⟨x,x2⟩−μ2τ−lnτ2)]
각 매개 변수는 데이터 수 또는 충분한 통계 중 하나에 해당하므로 글로벌 매개 변수를 업데이트하는 것이 더 쉽습니다.
λ^=η˙+Nϕn⟨1,x,x2⟩
다음은 매우 인공적이고 쉽게 분리 할 수있는 데이터 (아래 코드)를 학습 할 때 데이터의 한계 가능성이 여러 번 반복되는 것처럼 보입니다. 첫 번째 줄거리는 초기 무작위 변이 매개 변수와 반복 의 가능성을 보여줍니다 . 각각의 후속은 두 번의 반복의 다음 힘 이후입니다. 코드에서 은 대한 변형 매개 변수를 나타 냅니다.0a,b,mα,β,μ
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Aug 12 12:49:15 2018
@author: SeanEaster
"""
import numpy as np
from matplotlib import pylab as plt
from scipy.stats import t
from scipy.special import digamma
# These are priors for mu, alpha and beta
def calc_rho(t, delay=16,forgetting=1.):
return np.power(t + delay, -forgetting)
m_prior, alpha_prior, beta_prior = 0., 1., 1.
eta_0 = 2 * alpha_prior - 1
eta_1 = m_prior * (2 * alpha_prior - 1)
eta_2 = 2 * beta_prior + np.power(m_prior, 2.) * (2 * alpha_prior - 1)
k = 3
eta_shape = (k,3)
eta_prior = np.ones(eta_shape)
eta_prior[:,0] = eta_0
eta_prior[:,1] = eta_1
eta_prior[:,2] = eta_2
np.random.seed(123)
size = 1000
dummy_data = np.concatenate((
np.random.normal(-1., scale=.25, size=size),
np.random.normal(0., scale=.25,size=size),
np.random.normal(1., scale=.25, size=size)
))
N = len(dummy_data)
S = 1
# randomly init global params
alpha = np.random.gamma(3., scale=1./3., size=k)
m = np.random.normal(scale=1, size=k)
beta = np.random.gamma(3., scale=1./3., size=k)
eta = np.zeros(eta_shape)
eta[:,0] = 2 * alpha - 1
eta[:,1] = m * eta[:,0]
eta[:,2] = 2. * beta + np.power(m, 2.) * eta[:,0]
phi = np.random.dirichlet(np.ones(k) / k, size = dummy_data.shape[0])
nrows, ncols = 4, 5
total_plots = nrows * ncols
total_iters = np.power(2, total_plots - 1)
iter_idx = 0
x = np.linspace(dummy_data.min(), dummy_data.max(), num=200)
while iter_idx < total_iters:
if np.log2(iter_idx + 1) % 1 == 0:
alpha = 0.5 * (eta[:,0] + 1)
beta = 0.5 * (eta[:,2] - np.power(eta[:,1], 2.) / eta[:,0])
m = eta[:,1] / eta[:,0]
idx = int(np.log2(iter_idx + 1)) + 1
f = plt.subplot(nrows, ncols, idx)
s = np.zeros(x.shape)
for _ in range(k):
y = t.pdf(x, alpha[_], m[_], 2 * beta[_] / (2 * alpha[_] - 1))
s += y
plt.plot(x, y)
plt.plot(x, s)
f.axes.get_xaxis().set_visible(False)
f.axes.get_yaxis().set_visible(False)
# randomly sample data point, update parameters
interm_eta = np.zeros(eta_shape)
for _ in range(S):
datum = np.random.choice(dummy_data, 1)
# mean params for ease of calculating expectations
alpha = 0.5 * ( eta[:,0] + 1)
beta = 0.5 * (eta[:,2] - np.power(eta[:,1], 2) / eta[:,0])
m = eta[:,1] / eta[:,0]
exp_mu = m
exp_tau = alpha / beta
exp_tau_m_sq = 1. / (2 * alpha - 1) + np.power(m, 2.) * alpha / beta
exp_log_tau = digamma(alpha) - np.log(beta)
like_term = datum * (exp_mu * exp_tau) - np.power(datum, 2.) * exp_tau / 2 \
- (0.5 * exp_tau_m_sq - 0.5 * exp_log_tau)
log_phi = np.log(1. / k) + like_term
phi = np.exp(log_phi)
phi = phi / phi.sum()
interm_eta[:, 0] += phi
interm_eta[:, 1] += phi * datum
interm_eta[:, 2] += phi * np.power(datum, 2.)
interm_eta = interm_eta * N / S
interm_eta += eta_prior
rho = calc_rho(iter_idx + 1)
eta = (1 - rho) * eta + rho * interm_eta
iter_idx += 1