12. Bayesian Latent Variable Models and Variational Inference#

This chapter is adapted from AM207 (Harvard, Fall 2021). Watch the recorded lecture.

In this chapter

  1. Bayesian Latent Variable Models

  2. Coordinate Ascent Variational Inference

  3. Bayesian Gaussian Mixture Models

Hide code cell content

### Import basic libraries
import numpy as np
import scipy as sp
import pandas as pd
import sklearn as sk
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
%matplotlib inline

12.1. Bayesian Latent Variable Models#

Overfitting is an always a concern when using MLE model parameters. We can mitigate the effect of outliers in the data on the model we learn by treating the parameters as random variables and placing priors on them.

In a latent variable model, maximum likelihood inference treats parameters \(\theta\), \(\phi\) as unknown constants and produces point-estimates for them. In a Bayesian latent variable model, \(\theta\), \(\phi\) are random variables and we derive the posterior distribution over them.

../_images/bayesian_model.jpg

That is, we want to infer

\[p(\theta, \phi, Z_1, \ldots, Z_N|Y_1, \ldots, Y_N, a, b) = \frac{p(\theta | a)p(\phi|b)\prod_{n}p(Y_n|Z_n, \phi)p(Z_n|\theta)}{\prod_{n} p(Y_n)}.\]

Challenges in Bayesian Inference#

Unfortunately, most Bayesian models with multiple types of random variables (like Bayesian latent variable models) have complex posteriors that do not match known distributions. Exact inference is not possible.

Sampling from the posterior may not always be the best option because:

  1. Convergence of samplers may be slow (due to high dimensionality of the distribution or multimodality)

  2. Samplers like Metropolis-Hastings requires evaluating the likelihood \(\prod_n p(Y_n | Z_n, \phi)\) in each iteration, if the observed data is large (\(N\) is in the millions), this computation is expensive.

The Idea of Variational Inference#

Idea: (Approximate Inference) Approximate the hard posterior \(p(\theta, \phi, Z_1, \ldots, Z_N|Y_1, \ldots, Y_N)\) with a distribution \(q\) that is easy to sample from (like a Gaussian). Any computation involving the posterior can now be done with \(q\).

This approximation of \(p(\theta, \phi, Z_1, \ldots, Z_N|Y_1, \ldots, Y_N)\) with a distribution \(q\) is called variational inference.

../_images/variational.jpg

The Design of the Variational Objective#

Goal: given a target posterior distribution \(p(\psi | Y_1, \ldots, Y_N)\), \(\psi \in \mathbb{R}^I\) we want to find a distribution \(q(\psi |\lambda^*)\) in a family of distributions \(Q = \{q(\psi |\lambda) | \lambda \in \Lambda \}\) such that \(q(\psi |\lambda^*)\) best approximates \(p\).

Design Choices: we need to choose:

A. (Variational family) a family \(Q\) of candidate distributions for approximating \(p\). The members of \(Q\) are called the variational distributions.

Our Choice: we assume that the joint \(q(\psi)\) factorizes completely over each dimension of \(\psi\), i.e. \(q(\psi)= \prod_{i=1}^I q(\psi_i | \lambda_i)\). This is called the mean field assumption. What can go wrong with this design choice?

B. (Divergence measure) a divergence measure to quantify the difference between \(p\) and \(q\).

Our Choice:

\[D_{\text{KL}}(q(\psi | \lambda) \| p(\psi | Y_1, \ldots, Y_N)) = \mathbb{E}_{\psi \sim q(\psi|\lambda)}\left[\log\left( \frac{q(\psi | \lambda)}{p(\psi | Y_1, \ldots, Y_N)} \right) \right]\]

What can go wrong with this design choice?

Variational Inference as Optimization#

We now formalize variational inference for a target \(p(\psi)\): find \(q(\psi|\lambda^*)\) where

\[\begin{split}\begin{aligned} \lambda^* &= \underset{\lambda}{\text{argmin}}\; D_{\text{KL}}(q(\psi|\lambda) \| p(\psi|Y_1, \ldots, Y_N))) \\ &= \underset{\lambda}{\text{argmin}}\; \mathbb{E}_{\psi \sim q(\psi|\lambda)}\left[\log\left(\frac{q(\psi | \lambda)}{p(\psi|Y_1, \ldots, Y_N))}\right) \right] \end{aligned}\end{split}\]

Recall that for EM, we had proved that minimizing the KL is equivalent to maximizing the ELBO (for which it is easier to compute the gradient). We will do the same here:

\[\begin{split}\begin{aligned} \underset{\lambda}{\min}D_{\text{KL}}(q(\psi|\lambda) \| p(\psi|Y_1, \ldots, Y_N))) \overset{\text{equiv}}{\equiv}& \underset{\lambda}{\max} -D_{\text{KL}}(q(\psi|\lambda) \| p(\psi|Y_1, \ldots, Y_N))) \\ =& \underset{\lambda}{\max} -\mathbb{E}_{\psi \sim q(\psi|\lambda)}\left[\log\left(\frac{q(\psi | \lambda)}{p(\psi|Y_1, \ldots, Y_N))} \right)\right] \\ =& \underset{\lambda}{\max}\underbrace{\mathbb{E}_{\psi \sim q(\psi|\lambda)}\left[\log\left(\frac{p(\psi, Y_1, \ldots, Y_N))}{q(\psi | \lambda)} \right)\right]}_{ELBO(\lambda)} \\ &- \log p(Y_1, \ldots, Y_N). \end{aligned}\end{split}\]

Thus, the variational objective can be rephrased as maximizing the \(ELBO\).

Gradients of the ELBO#

Unfortunately, the ELBO for variational inference of the posterior does not have easy gradients,

\[\begin{aligned} \nabla_{\lambda}\,\underbrace{\mathbb{E}_{\psi \sim q(\psi|\lambda)}\left[\log\left(\frac{p(\psi, Y_1, \ldots, Y_N)}{q(\psi | \lambda)} \right)\right]}_{ELBO(\lambda)}. \end{aligned}\]

In particular, the issue is that the gradient taken is with respect to the parameter \(\psi\) of the distribution over which we are taking the expectation - i.e. we cannot push the gradient into the expectation.

In this chapter, we will maximize the \(ELBO\) using coordinate ascent (just as in the case of EM). But you’ll see that coordinate ascent variational inference requires that we perform model specific computations (often in closed form). This restrict the class of Bayesian models for which we can perform variational inference.

Two of the major developments we will cover in Chapter 22 address how to estimate this gradient efficiently and without bias.

Coordinate Ascent Variational Inference#

Maximizing the ELBO via Coordinate Ascent#

The coordinate ascent algorithm maximizes an objective function \(ELBO(\lambda)\) by iteratively maximizing over \(\lambda_i\), holding constant \(\lambda_{-i} = [\lambda_1\; \ldots\; \lambda_{i-1}\; \lambda_{i+1}\; \ldots\; \lambda_{I}]\).

The coordinate ascent variational inference algorithm:

  1. Initialization: pick an initial value \(\lambda^{(0)}\)

  2. Coordinate-wise maximization:

    Repeat for \(j=1, \ldots, J\) iterations:

    \(\quad\quad\) Cycle thru \(i=1, \ldots, I\) coordinates:

\[q(\psi_i | \lambda^{\text{new}}_i) \propto \exp\left\{ \mathbb{E}_{\psi_{-i} \sim q(\psi_{-i} | \lambda^{\text{new}}_{1}, \ldots, \lambda^{\text{new}}_{i-1}, \lambda^{\text{old}}_{i+1}, \ldots, \lambda^{\text{old}}_{I})}\left[\log p(Y_1, \ldots, Y_N, \psi)\right]\right\}.\]

where \(\psi_{-i} = [\psi_1\; \ldots\; \psi_{i-1}\; \psi_{i+1}\; \ldots\; \psi_{I}]\).

Bayesian Gaussian Mixture Models#

Variational Inference for Bayesian Gaussian Mixture Models#

We consider a Bayesian model for a mixture of \(K\) number of univariate Gaussians:

../_images/bayesian_gmm.jpg

The hyperparameters of the models are \(\pi, \sigma^2, m_0, s^2_0\), which are constants that must be selected prior to inference. For example, to simplify our computations we selected \(\pi = [1/K, \ldots, 1/K]\), \(m_0 = 0\), \(\sigma=1\).

We make the mean field assumption – that our variational posterior factorizes completely:

\[q(Z, \mu| m, s^2, \phi) = \prod_{k=1}^K q(\mu_k|m_k, s_k^2) \prod_{n=1}^N q(Z_n|\phi_n).\]

Implementation of CAVI for Bayesian GMM#

Hide code cell content

#Generate data
N = 2000
pis = [1./3, 1./3, 1./3]
mus = [6, 10, 14]
sigmas = [1., 1., 1.]
K = 3
zs = np.random.choice(np.arange(K), size=N, p=pis)
y = np.array([np.random.normal(mus[z], sigmas[z]**0.5, 1)[0] for z in zs])

#defining the bayesian model
sigma_sq = 1.**2
s_sq_0 = 1.

#initialization for CAVI
m_init = np.array([2, 4, 5])
s_sq_init = np.array([1., 1., 1.])

#implement coordinate ascent VI
m_current = m_init
s_sq_current = s_sq_init

total_iter = 10000
threshold = 1e-10
delta_m = 1.
delta_s = 1.
i = 0

#implementation of the ELBO
def elbo(m, s_sq, phi):
    summand_1 = (np.log(s_sq) - m / s_sq_0).sum()
    summand_2 = ((-0.5 * np.add.outer(y**2, s_sq + m**2) + np.outer(y, m) - np.log(phi)) * phi).sum()
    return summand_1 + summand_2

ELBOs = []
while i < total_iter and delta_m > threshold and delta_s > threshold:
    #update q(Z_n)
    exponent = np.outer(y, m_current) + -(0.5 * m_current**2 + 0.5 * s_sq_current)[np.newaxis, :]
    phi_unnormalized = np.exp(exponent)
    phi = phi_unnormalized / phi_unnormalized.sum(1)[:, np.newaxis]
    #update mu
    m_new = (phi * y[:, np.newaxis]).sum(0) * (1. / s_sq_0 + phi.sum(0))**(-1)
    #update s squared 
    s_sq_new = (1. / s_sq_0 + phi.sum(0))**(-1)
    
    #compute ELBO
    ELBOs.append(elbo(m_new, s_sq_new, phi))
    
    #compute variational parameter change
    delta_m = np.linalg.norm(m_new - m_current)
    delta_s = np.linalg.norm(s_sq_new - s_sq_current)
    
    m_current = m_new
    s_sq_current = s_sq_new
    
    i += 1
    
#sample from posterior predictive    
def posterior_predictive_sampling(means, variances, S):
    posterior_predictive_samples = []
    for mean, variance in zip(means, variances):
        posterior_samples = np.random.normal(mean, variance**2, size=S)
        posterior_predictive_samples += [np.random.normal(sample, sigma_sq**2, 1)[0] for sample in posterior_samples]
    return np.array(posterior_predictive_samples)
    
x = np.linspace(y.min(), y.max(), 1000)
fig, ax = plt.subplots(1, 1, figsize=(10, 5))
ax.hist(y, bins=60, density=True, color='gray', alpha=0.7, label='histogram of birth weights')
posterior_predictive_samples = posterior_predictive_sampling(m_current, s_sq_current, 100)
ax.hist(posterior_predictive_samples, bins=60, density=True, color='red', alpha=0.3, label='variational posterior predictive')
ax.set_title('GMM for Birth Weights')
ax.legend(loc='best')
plt.show()
../_images/694ff7079b808d909724fc754efb199fafe04b9ff97028d4fb270373e13a1388.png

Sanity Check: ELBO During Training#

Remember that plotting the posterior predictive against actual data is not always an option (e.g. high-dimensional data).

A sanity check for that your CAVI algorithm has been implemented correctly is to plot the ELBO (or alternatively, the observed data log-likelihood) over the iterations of the algorithm:

\[ ELBO(\phi, m, s^2) = \mathbb{E}_{Z, \mu\sim q(Z, \mu | \phi, m, s^2)} \left[\log \left( \frac{p(Y_1, \ldots, Y_N, Z_1, \ldots, Z_N, \mu)}{q(Z, \mu | \phi, m, s^2)}\right) \right] \]
fig, ax = plt.subplots(1, 1, figsize=(10, 2))
ax.plot(range(len(ELBOs)), ELBOs, color='red', alpha=0.5)
ax.set_title('ELBO over iterations of CAVI')
plt.show()
../_images/d2b62cc3f2b93daf2cb5dc5d103654263d572e51b3ad8380e6fc0b9c130230a6.png

12.2. Exercises#

These problems were originally assigned as homework. Data files are in the book’s data/ folder. Worked solutions, where available, are collapsed beneath the questions they answer; try each problem before expanding them.

Problem Set: Understanding EM and Variational Inference#

Hide code cell content

### Import basic libraries
import numpy as np
import pandas as pd
import sklearn as sk
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
%matplotlib inline

Hide code cell content

# data_df is the dataframe of your data
# estimates_df is a numpy array of cancer rate estimates, one for each county
def scatter_plot_cancer_rates(data_df, estimates=None):
    ax = data_df.plot(kind='scatter', x="pop",y="pct_mortality", alpha=0.0001, color="grey")
    bot_kcancer_counties = data_df.sort_values(by='pct_mortality',ascending=True)[:300]
    top_kcancer_counties = data_df.sort_values(by='pct_mortality',ascending=False)[:300]
    top_kcancer_counties.plot(kind='scatter',x="pop",y="pct_mortality",alpha=0.0001, color="blue", ax=ax, logx=True)
    bot_kcancer_counties.plot(kind='scatter',x="pop",y="pct_mortality",alpha=0.0001, color="red", ax=ax, logx=True)
    if estimates is not None:
        ax.plot(data_df['pop'], 5 * estimates, '.', alpha=0.2, color="green")
    ax.set_ylim([-0.0001, 0.0003])

In this problem, we will draw concrete connections between EM and variational inference by applying both methods to a certain class of latent variable models. You’ll need to refer to the derivation of EM in Chapter 11 and the derivation of the variational inference objective earlier in this chapter. This is an essay question that requires you to engage with complex derivations at a productive but still high level. No implementation is required.

Non-Bayesian Latent Variable Model#

Recall the class of latent variable models we studied in Chapter 11:

../_images/graphical_model.jpg

Bayesian Latent Variable Model#

A Bayesian version of the same class of models involve adding priors for the model parameters:

../_images/bayesian_model.jpg
  1. (Comparing ELBOs) For the above type of Bayesian latent variable model, write down the ELBO for variational inference with a mean field variational family. Compare the variational inference ELBO for the Bayesian model to the expectation maximization ELBO for the non-Bayesian model. What are the differences and similarities between these two ELBOs?

    In both EM and variational inference we optimize the ELBO. Compare the update steps in EM to the update steps in Coordinate Ascent Variational Inference, draw a concrete analogy between them.

    Hint: To make both ELBO’s comparable, make sure that both are in terms of \(z, y, \theta, \phi\).

  2. (Comparing ELBOs and KL-divergences) Recall that the original objective of variational inference is to minimize a KL-divergence, we rewrote the objective to be that of maximizing the ELBO. Why is directly minimizing the KL-divergence in the original objective difficult (be specific about wherein the difficulty lies)?

    In the derivation of the E-step of EM, we reframed an maximization of the ELBO problem as a minimization of a KL-divergence problem. In this case, why was the KL-divergence easier to minimize and the ELBO harder to maximize (use the instantiation of the E-step for Gaussian Mixture Models in Chapter 11 to help support your answer)?

    Earlier in this chapter, we introduced a way to maximize the variational inference ELBO – through coordinate ascent. In the derivation of the updates for coordinate ascent, there is a place where we reframed an maximization of the ELBO problem as an equivalent minimization of a KL-divergence problem. Write down the exact form of this equivalence (the two expressions are separated in the derivation by a bunch of lines, you’ll need to identify both parts that you need). In this case, why was the KL-divergence easier to minimize and the ELBO harder to maximization (use the instantiation of the update for Gaussian Mixture Models earlier in this chapter to help support your answer)?

    Based on this analysis, can you draw some general conclusions about when we’d prefer to minimize the KL-divergence versus when we’d prefer to maximize the ELBO?

  3. (The Mean Field Assumption and Coordinate Ascent) Describe exactly when and how the mean field assumption is used in the derivation of the coordinate ascent updates.

  4. (Generalizability of CAVI) Summarize what kind of derivations/math is needed in order instantiate Coordinate Ascent Variational Inference (CAVI) for a given new model (look at what we did for Gaussian Mixture Models earlier in this chapter and predict what you’d need to do for a new model). Based on this, discuss the potential draw backs of using CAVI for Bayesian inference in general. What do these draw backs imply about the practicality of variational inference as an inference method?

  5. (Generalizability of EM) Summarize what kind of derivations/math is needed in order instantiate Expectation Maximization (EM) for a given new model (look at what we did for Gaussian Mixture Models in Chapter 11 and predict what you’d need to do for a new model). Based on this, discuss the potential draw backs of using EM for MLE inference in general. What do these draw backs imply about the practicality of EM as an inference method?

12.3. Further Reading#

Variational Inference