我试图实现与随机变推理高斯混合模型,如下文。
这是高斯混合的pgm。
我仍然对将其缩放到GMM的方法感到非常困惑。
首先,我认为局部变分参数仅为,其他均为全局参数。如果我错了,请纠正我。步骤6是什么意思as though Xi is replicated by N times
?我应该怎么做才能做到这一点?
你能帮我吗?提前致谢!
我试图实现与随机变推理高斯混合模型,如下文。
这是高斯混合的pgm。
我仍然对将其缩放到GMM的方法感到非常困惑。
首先,我认为局部变分参数仅为,其他均为全局参数。如果我错了,请纠正我。步骤6是什么意思as though Xi is replicated by N times
?我应该怎么做才能做到这一点?
你能帮我吗?提前致谢!
Answers:
本教程(https://chrisdxie.files.wordpress.com/2016/06/in-depth-variational-inference-tutorial.pdf)回答了您的大多数问题,并且可能比原始SVI论文更容易理解,因为它专门介绍了针对高斯混合模型(已知方差)实施SVI(以及协调上升VI和gibbs采样)的所有细节。
首先,一些说明可以帮助我理解SVI论文:
在的混合物高斯,我们的全球参数为平均和精度(逆方差)参数μ ķ,τ ķ PARAMS每个。即,η 克是该分布的自然参数,以下形式的普通伽马
与,η 1 = γ * (2 α - 1 )和η 2 = 2 β + γ 2(2 α - 1 )。(贝纳多和史密斯,贝叶斯理论;请注意,这与您通常会看到的四参数正态伽玛有所不同。)我们将使用a ,b ,m来指代α的变分参数,
的充分条件是一个普通伽马使用参数;· η + ⟨ Σ Ñ Ž Ñ ,ķ,Σ Ñ Ž Ñ ,ķ X Ñ,Σ Ñ Ž Ñ ,ķ X 2 Ñ ⟩,其中;· η是先验的。(其中的z n ,k也可能造成混淆;从exp ln (p特技施加到 Π Ñ p (X Ñ | Ž Ñ,α ,β ,γ )= Π Ñ Π ķ ( p (X Ñ | α ķ,β ķ,γ ķ)) Ž Ñ ,ķ,并与结束留给读者的是相当数量的代数。)
这样,我们可以使用以下命令完成SVI伪代码的步骤(5):
更新全局参数更加容易,因为每个参数都对应于数据计数或其足够的统计数据之一:
#!/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