Introduction

Created: March, 23, 2023

对于生成式模型来说,我们要解决的核心问题就是如何构造一个 highly flexible families of probability distribution 去拟合真实的数据分布,并且我们希望这个分布家族对于,

  • learning:通过数据学习分布形式。
  • sampling:从分布中取样。
  • inference:计算条件概率 $p(x|y)$。
  • evaluation:计算给定样本出现的概率 $p(x)$。

这四个任务,都是或尽可能都是 analytically 或者 computationally tractable [1]_ 的 :raw-latex:\parencite{sohl2015deep}

为了这个目标,人们提出了各种各样的模型,方法。这些方法的核心思路基本就是,在保证 tractable 的前提下,尽可能的提升flexibility,从而更好的拟合复杂的真实数据分布。常见的模型包括:Mixture Gaussian, VAE, Normalizing Flow, DDPM, GAN 等等。对于这些模型,上述的四个任务并不是都能够解的,大部分都只能解决其中一个或几个(例如GAN,我们只能做 learning 和 sampling)。

Think from Scratch #

以上的介绍可能过于抽象,现在我们可以从零开始思考,如果现在我们拥有一堆数据,这些数据有很多样本,比如说我们有 N 个样本,每个样本都是一个 D 维的向量,我们要如何学习这些数据的分布呢?

想要回答这个问题,我们必须理解 ”分布“ 是什么?分布其实就是概率分布,概率分布就是一个随机变量不同取值的概率构成的一个函数。对于一个连续的随机变量,单个取值的概率没有意义,这时候,分布其实是代指概率密度函数。

这时候,我们应该知道,对于前面提到的数据,如果我把数据中的样本视作一个 D 维的随机变量,我们实际上就是想要学习这个随机变量的概率密度函数。

这时候,又引出了一个新的问题,这个概率密度函数的形式是什么样的呢 ?如果我们知道概率密度函数的解析形式,那么我们就可以通过极大似然估计,根据给定的数据,估计出这个分布的未知参数了。例如,如果我们假设数据服从高斯分布,但是均值方差未知,通过极大似然估计,我们就可以得到这个分布的均值和方差。

数据分布的形式的选取是需要根据我们的先验知识决定的,但很多时候,我们并没有这些先验知识,我们也不想自己决定。另一方面,即便我们有一些先验知识,但是现实中可供选取的 family of distribution 是有限的,这些分布并不一定能够建模复杂的真实数据。

Latent Variable Model #

为此,我们通常考虑使用 Latent Variable Model 对数据分布进行建模,即我们希望从一个known well-defined distribution 出发,通过学习一个分布的映射,将这个已知分布映射到未知的数据分布。

Modeling #

具体的,假设我们有一个 q 维的 latent space $\mathbb{R}^{q}$ 和 n 维的 data space $\mathbb{R}^{n}$,我们事实上是希望学习一个能够将 latent space 里的 sample(样本) 映射到 data space 里的函数,$g: \mathbb{R}^{q} \rightarrow \mathbb{R}^{n}$。

如果这个函数是 deterministic 的,那么我们就得到了 GAN 这个模型。特别的,我们要求 data space 里的每个样本,都至少有一个 latent space 里的样本与之对应。

如果这个函数是 stochastic 的,那么我就得到了 VAE,DDPM 等模型。这时候,我们在学习的函数实际上变成了一个后验概率分布 :math:p_{g}(\mathbf{x} \mid \mathbf{z})\ 。我们通常会选取具有具体形式的分布对 :math:p_{g}(\mathbf{x} \mid \mathbf{z}) 进行建模(例如高斯分布),我们学习的函数实际上就变成预测这些分布的未知参数。

进一步的,在学习到后验概率分布 :math:p_{g}(\mathbf{x} \mid \mathbf{z})\ ,结合已知的先验分布 :math:p_{\mathcal{Z}}(\mathbf{z})\ ,我们便可以通过全概率公式,求出未知的数据分布,如下:

$$ p_{\mathcal{X}}(\mathbf{x})=\int p_{g}(\mathbf{x} \mid \mathbf{z}) p_{\mathcal{Z}}(\mathbf{z}) d \mathbf{z} \label{eq-intro-px} $$

Learning #

直观的,如果我们定义好后验概率分布 :math:p_{g}(\mathbf{x} \mid \mathbf{z}) 和先验分布 :math:p_{\mathcal{Z}}(\mathbf{z}) 之后,我们就能够通过公式 [eq-intro-px] <#eq-intro-px>__ 计算出 :math:p(x)\ ,然后我们通过极大似然估计拟合训练数据,即可估计出后验概率分布中未知的参数了。

.. math::

\prod_{x\in X}^X p(x) \label{eq-intro-loglikelihood}

但是!这么做实际上有一个很大的问题。由于积分的存在,公式 [eq-intro-px] <#eq-intro-px>__ 通常是(大部分时候都是)Intractable的。为什么这么说呢?

  • 首先,如果积分可以解析算出来,那肯定没问题。

  • 如果不行,最常见的做法是蒙特卡洛估计,即对 :math:z 随机取样,然后计算被积函数,用其平均值替代积分。取样越多估计越准。见公式 [eq-monte-carlo-px] <#eq-monte-carlo-px>__\ 。

    .. math::

    P(x) \approx \frac{1}{N} \sum_{z_n\sim P(Z)} P(x|z_n)
                  \label{eq-monte-carlo-px}
    
  • 问题在,对于一个高维的 latent variable :math:z 以及真实数据来说,大部分的 :math:p(x|z) 都可能会是零,或非常小,即大部分的 z 都不太可能生成 真实数据中的样本 x [2]_,但是,还是有可能有 z 是可能产生真实数据中的样本 x 的,即 :math:p(x|z) 比较大。因此,为了得到一个准确估计,我们必须要取样非常多的 :math:z\ ,而这对一个高维的 :math:z 来说,将会是一个我们不能接受的数字。

为此,我们通常的做法是优化公式 [eq-intro-loglikelihood] <#eq-intro-loglikelihood>__ 的可解的一个变分下界 VLBO [3](通常也被称为ELBO [4]),做一个近似的似然估计,如下:

.. math::

\begin{aligned} log P(x) & = log\int P(x|z)P(z) dz \ & = log\int \frac{Q(z|x)P(x|z)P(z)}{Q(z|x)} dz \ & = logE_{z\sim Q}[\frac{P(x|z)P(z)}{Q(z|x)}] \ & \geq E_{z\sim Q}[log\frac{P(x|z)P(z)}{Q(z|x)}] \ & = E_{z\sim Q}[logP_\theta(x|z)] - D_{KL}[Q_\theta(z|x) | P(z)] \end{aligned} \label{eq-vae-elbo}

怎么理解这个下界,为什么会想到转换成这个形式呢?这里提供一种解释。回忆刚刚我们遇到的问题,主要是公式 [eq-intro-px] <#eq-intro-px>__ 中的积分没法有效估计,其原因是从 :math:Z 中采样,击中被积函数 :math:P(x|z) 概率大的地方的概率太小,得到有效估计需要的采样数目无法接受。

换句话说,我们本质上是想知道 :math:P(x|z) 相对于 z 的期望,我们现在是从 :math:P(z) 中取样估计这个期望,但这么做取样出来的 :math:z 算出来的 :math:P(x|z) 概率太小了。

.. math:: P(x) = \int P(x|z)P(z) dz = E_{z\sim Z}[P(x|z)]

怎么解决呢?直观的思路就是,那我们就从一个能让 :math:P(x|z) 概率大的分布取一些 :math:z 出来。什么分布能满足这个要求呢?最好的当然是从 :math:P(z|x) 中取样,但真实的 :math:P(z|x) 是一个未知的分布,因此,我们退而求其次,使用一个 :math:Q(z|x) 去近似它,即这时候我们希望这么算 :math:P(x),

.. math::

\begin{aligned} P(x) & = \int P(x|z)P(z) dz \ & = \int \frac{Q(z|x)P(x|z)P(z)}{Q(z|x)} dz \ & = E_{z\sim Q}[\frac{P(x|z)P(z)}{Q(z|x)}] \end{aligned}

这时候蒙特卡洛估计就会更准了,如下所示:

.. math:: P(x) \approx \frac{1}{N} \sum_{z_n\sim Q(Z|x)} P(x|z_n) P(z_n) / Q(z_n|x)

还没完,通常,我们一般会用 log 似然估计,因为这样可以把概率的连乘变成连加。即这时候,我们希望最大化这个函数:

.. math:: log P(x) = log E_{z\sim Q}[\frac{P(x|z)P(z)}{Q(z|x)}]

那我们要怎么求解 :math:log P(x) 呢?对于 :math:P(x)\ ,它等价于一个期望,我们直接蒙特卡洛估计没什么问题。但是对于 :math:log P(x) 呢?直觉来看,我们能不能蒙特卡洛估计求出 :math:E_{z\sim Q}[\frac{P(x|z)P(z)}{Q(z|x)}] 然后再取个 log 呢?答案是不行,但我还没找到一个精确的解释和反例。直观上来解释,蒙特卡洛估计只能针对一个分布,而 :math:log P(x) 不是一个分布,所以不能这么干。

我们的做法是通过 Jensen 不等式,将 :math:log P(x) 进行放缩转换成优化一个期望,这时候就可以正常使用蒙特卡洛估计了。

.. math::

\begin{aligned} log P(x) & = logE_{z\sim Q}[\frac{P(x|z)P(z)}{Q(z|x)}] \ & \geq E_{z\sim Q}[log\frac{P(x|z)P(z)}{Q(z|x)}] \ & = E_{z\sim Q}[logP_\theta(x|z)] - D_{KL}[Q_\theta(z|x) | P(z)] \end{aligned} \label{eq-vae-elbo-jensen}

后记: :math:Q(z|x) 这个分布的选取策略,塑造了不同的生成式模型,例如,在 VAE [5]_ 中,\ :math:Q(z|x) 是一个联合训练的已知分布(例如高斯或伯努利),在 DDPM 中,\ :math:Q(z|x) 是一个由已知分布(例如高斯或伯努利)组成的马尔可夫链。

如果你对EBLO对推导还不太明白,可以再参考一下这篇博客 [6]_。

.. [1] 如果一个问题即能在有效时间内解决,不管是通过解析还是近似的方式,我们就称它是 tractable 的。

.. [2] 可以考虑自然图像代表的数据空间,一个128_128的图像,可以视作一个128_128维的随机变量,每个维度都有256种取值,但是只有很小的一部分会得到合理的图像,也就是说这个随机变量代表的数据空间里,只有很小的一个子空间概率密度比较大。因为 data space :math:X 每个 sample 都要至少有一个 latent space :math:Z\ \ 的 sample 与之对应,所以从 Z 里取样,通过映射\ \ :math:g\ \ ,还是很难落到概率的子空间里。\ \ 思考\ \ :那我们对 data space 做一个压缩不就行了吗,用PCA 或者 VQVAE 降维?

.. [3] VLBO: Variantional Lower BOund

.. [4] ELBO: Evidence Lower BOund

.. [5] 由前面的解释可以知道,我们采用了一个 :math:Q(z|x) 去近似真实的 :math:P(z|x)\ \ ,这种用一个函数去学习另一个函数的方法,通常被称为 variational xx,这也是 VAE 名字中 V 的来源。

.. [6] http://www.denizyuret.com/2019/11/a-simple-explanation-of-variational.html