在之前的一篇博客中,已经介绍了变分推断的基本原理,下面将以高斯混合模型为例,推导变分推断的公式,并给出了CAVI算法流程。同时将使用python3实现这个小案例。
下图为为高斯混合模型的生成过程:
在这里插入图片描述
其中,$x_{i}$便是一个样本数据,共有$n$个样本,并且这$n$个样本是从$K$个独立的高斯分布中抽的,$\mu {k}$为每个高斯分布的均值,$c {i}$表示$x_{i}$样本对应的哪个高斯分布,其服从一个多项式分布。
从上图中的生成过程可以发现,这里需要估计的隐变量是$\mu$和$c$。
基于贝叶斯定理,可以计算得到参数和样本的联合概率分布:
在这里插入图片描述 )
这个公式很容易理解,不过过多介绍。
假设变分参数为:$m=(m_1,\ldots,m_K),s^2=(s_1^2,\ldots,s_K^2),\varphi=(\varphi_1,\ldots,\varphi_n)$,其中第一个和第二个是均值$\mu {k}$对应的两个变量,第三个参数为类别$c {i}$对应的变量。这三个参数决定了变分分布$q$.
在这里插入图片描述
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
class gmm ():
def __init__ (self, data, num_clusters, sigma=1 ):
'''initialization
model parameters(m,s2,phi)--need update
'''
self .data = data
self .K = num_clusters
self .n = data.shape[0 ]
self .sigma = sigma
self .phi = np.random.random([self .n,self .K])
self .m = np.random.randint(np.min (data), np.max (data), self .K).astype(float )
self .s2 = np.random.random(self .K)
def compute_elbo (self ):
'''calculate ELOB '''
p1 = -np.sum ((self .m**2 + self .s2) / (2 * self .sigma**2 ))
p2 = (-0.5 * np.add.outer(self .data** , .m** + .s2) + np.outer( .data, .m))*( .phi)
p3 = -np. (np.log( .phi))
p4 = np. ( * np. (np.log( .s2)))
elbo_c = p1 + np. (p2) + p3 + p4
elbo_c
( ):
e = np.outer( .data, .m) + (- * ( .m** + .s2))[np.newaxis, :]
.phi = np.exp(e) / np. (np.exp(e), axis= )[:, np.newaxis]
.m = np. ( .data[:, np.newaxis] * .phi, axis= )/( / .sigma** + np. ( .phi, axis= ))
.s2 = / ( / .sigma** + np. ( .phi, axis = ))
( ):
elbo = []
elbo.append( .compute_elbo())
i (iters):
.update_bycavi()
elbo.append( .compute_elbo())
( , elbo[i])
np. (elbo[- ] - elbo[- ]) <= epsilon:
( ,i)
elbo
( ):
sns.set_style( )
i ( ( .n/size)):
sns.distplot(data[size*i : (i+ )*size], rug= )
x = np.linspace( .m[i] - * .sigma, .m[i] + * .sigma, )
plt.plot(x,mlab.normpdf(x, .m[i], .sigma),color= )
plt.show()
__name__ == :
number =
clusters =
mu = np.array([ , , , , ])
data = []
i (clusters):
data.append(np.random.normal(mu[i], , number))
data = np.concatenate(np.array(data))
model = gmm(data, clusters)
model.trainmodel( , )
( , (model.m))
model.plot(number)
Blei D M, Kucukelbir A, McAuliffe J D. Variational inference: A review for statisticians[J]. Journal of the American Statistical Association, 2017, 112(518): 859-877.