随机变分推断在高斯贝叶斯混合中的应用


9

我试图实现与随机变推理高斯混合模型,如下

在此处输入图片说明

这是高斯混合的pgm。

根据本文,随机变异推断的完整算法为: 在此处输入图片说明

我仍然对将其缩放到GMM的方法感到非常困惑。

首先,我认为局部变分参数仅为qz,其他均为全局参数。如果我错了,请纠正我。步骤6是什么意思as though Xi is replicated by N times?我应该怎么做才能做到这一点?

你能帮我吗?提前致谢!


就是说,不使用整个数据集,而是采样一个数据点并假装您有个大小相同的数据点。在许多情况下,这将是等同于一个数据点由一个期望乘以ÑNN
英林2016年

@DaeyoungLim感谢您的回复!我现在明白了您的意思,但是我仍然感到困惑,哪些统计应该在本地更新,哪些统计应该在全球更新。例如,这是高斯混合的实现,您能告诉我如何将其缩放为svi吗?我有点迷路了。非常感谢!
user5779223 '16

我没有阅读完整的代码,但是如果您要处理的是高斯混合模型,则混合成分指标变量应该是局部变量,因为它们每个都只与一个观测值相关。因此,遵循Multinoulli分布(在ML中也称为分类分布)的混合成分潜在变量为在上面的描述中。zi,i=1,,ñ
英林2016年

@DaeyoungLim是的,我理解你到目前为止所说的话。因此,对于变化分布q(Z)q(\ pi,\ mu,\ lambda),q(Z)应该是局部变量。但是有很多与q(Z)相关的参数。另一方面,还有许多与q(\ pi,\ mu,\ lambda)相关的参数。而且我不知道如何适当地更新它们。
user5779223 '16

您应该使用均值场假设来获得变量参数的最佳变量分布。这是参考资料:maths.usyd.edu.au/u/jormerod/JTOpapers/Ormerod10.pdf
Daeyoung Lim

Answers:



1

首先,一些说明可以帮助我理解SVI论文:

  • 在计算全局参数的变分参数的中间值时,我们对一个数据点进行了采样,并假装我们大小为整个数据集是该单个点N次。ññ
  • 为全局变量的全部条件的自然参数 β。该符号用于强调它是条件变量(包括观察到的数据)的函数。 ηGβ

在的混合物高斯,我们的全球参数为平均和精度(逆方差)参数μ ķτ ķ PARAMS每个。即,η 是该分布的自然参数,以下形式的普通伽马ķμk,τkηg

μ,τN(μ|γ,τ(2α1)Ga(τ|α,β)

η 1 = γ * 2 α - 1 η 2 = 2 β + γ 22 α - 1 。(贝纳多和史密斯,贝叶斯理论;请注意,这与您通常看到的四参数正态伽玛有所不同。)我们将使用a b m来指代α的变分参数η0=2α1η1=γ(2α1)η2=2β+γ2(2α1)a,b,mα,β,μ

的充分条件是一个普通伽马使用参数;· η + Σ Ñ Ž Ñ ķΣ Ñ Ž Ñ ķ X ÑΣ Ñ Ž Ñ ķ X 2 Ñ,其中;· η是先验的。(其中的z n k也可能造成混淆;从exp ln pμk,τķη˙+ñžñķñžñķXññžñķXñ2η˙žñķ特技施加到 Π Ñ p X Ñ | Ž Ñα β γ = Π Ñ Π ķ p X Ñ | α ķβ ķγ ķ Ž Ñ ķ,并与结束留给读者的是相当数量的代数。)经验值lnpñpXñ|žñαβγ=ñķpXñ|αķβķγķžñķ

这样,我们可以使用以下命令完成SVI伪代码的步骤(5):

ϕñķ经验值ñπ+ËqlnpXñ|αķβķγķ=经验值lnπ+Ëq[μķτķ-τ2XX2-μ2τ-lnτ2]

更新全局参数更加容易,因为每个参数都对应于数据计数或其足够的统计数据之一:

λ^=η˙+ñϕñ1个XX2

0一个bαβμ

在此处输入图片说明

在此处输入图片说明

#!/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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.