跳转至

9 Generative Models

之前我们讲的都是监督学习 (Supervised Learning),是通过给定数据以及相应的标签进行学习的。相对应的无监督学习 (Unsupervised Learning) 只有数据并没有标签,需要我们根据数据学习到潜在的数据结构

这一讲我们要介绍 生成模型,其与无监督学习的关系如下:

  • 生成模型属于无监督学习的子集:大多数生成模型(如自编码器、变分自编码器 VAE、生成对抗网络 GAN、扩散模型等)都是在无监督或自监督的方式下训练的,即它们只使用未标记的数据来学习数据的潜在结构。
  • 无监督学习不全是生成模型:一些无监督学习方法(如K均值聚类、主成分分析 PCA)并不生成新的数据样本,而是专注于发现数据的结构或进行降维,因此它们不是生成模型。

9.1 Introduction

给定训练数据,生成模型的目标是从相同的数据分布中生成新的样本。

生成模型的目标是学习一个概率分布 \(p_{model}(x)\),使其尽可能接近真实数据的分布 \(p_{data}(x)\)密度估计是无监督学习中的一个核心问题,即从数据中估计出其潜在的概率分布,而密度估计有两种不同的方法,大致可以分为 显式密度估计(Explicit Density Estimation)隐式密度估计(Implicit Density Estimation)

  • 显式密度估计是直接定义并求解模型的概率分布 \(p_{model}(x)\)。比如说 PixelRNN/PixelCNN,VAE。优点是可以直接计算和采样,理论清晰。缺点是有时难以精确建模复杂的高维分布

  • 隐式密度估计是学习一个模型,让它能够从 \(p_{model}(x)\) 中采样,但不需要明确地定义这个分布。比如说生成对抗网络(GAN)、扩散模型(Diffusion Models)。优点是可以建模非常复杂的分布,生成高质量的样本。

生成模型的应用

  • 生成逼真的样本用于艺术创作、超分辨率、着色等。e.g. 通过生成模型,可以从低分辨率图像中生成高分辨率图像,恢复细节,提升图像质量。

  • 时间序列数据的生成模型可用于模拟和规划。e.g. 在金融领域,生成模型可以模拟未来的市场走势,帮助投资者做出更明智的决策。

  • 训练生成模型还可以推断潜在表示,这些表示可用作通用特征

9.2 PixelRNN/CNN

这个生成模型采用的方法是显式密度估计

对于一个图像 \(x\),其像素值可以看作是一个随机变量序列 \((x_1,x_2,...,x_n)\),其中 \(n\) 是像素总数。通过链式法则,我们可以将图像的联合概率分布 \(p(x)\) 分解为各个像素值的条件概率的乘积。

\[ p(x) = \prod_{i=1}^{n} p(x_i | x_1, ..., x_{i-1}) \]

通过最大化训练数据的似然性来训练模型,即找到一组参数,使得训练数据出现的概率最大。

PixelRNN

从角落开始生成图片,每一个像素的生成依赖于前面的像素,通过 RNN (LSTM) 进行生成。

但是它有一个缺点就是生成的速度太慢了

PixelCNN

同样是从角落开始生成图片,不过这次是通过 CNN 的方式进行生成

计算概率的时候不是需要前面所有像素的信息吗,CNN不是只能看到感受野部分的信息吗?

单层 CNN 只能看到局部区域。但是多层的累计就可以让其看到前面所有像素的信息了,这里我们使用一个技术 Masked Convolutions,设置两种掩码,让其有效地只观察到前面的像素

这个方法的训练速度比 PixelRNN 快,因为我们可以并行地训练每一个像素,但是在生成的时候依然很慢,需要顺序地生成

9.3 Variational Autoencoders (VAE)

VAE 引入了一个隐藏层来估计密度方程

\[ p_\theta(x) = \int p_\theta(z)p_\theta(x|z)dz \]

但是上面这个估计方式我们并不能直接优化,而是用过优化下界的方式来进行的【这在后面会介绍】

Autoencoders

我们通过一些神经网络从一张图片中提取到了一些特征,那么我们是否可以根据这些特征来重构原始图像呢?

在整个过程中我们并没有用到原始数据的标签信息,所以这是一个无监督的模型

Note

我们可以将训练好的 encoder 拿出来作为监督模型的初始值,然后结合相应的标签完成监督模型的训练

VAE

变分自编码器(Variational Autoencoder, VAE)是一种基于概率建模的生成模型,旨在从数据中学习潜在表示,并能生成与训练样本相似的新数据。其核心思想是将传统自编码器的概率化,通过引入潜在变量 \(z\) 和概率分布,实现从数据生成的角度理解输入。

在VAE中,假设每个观测数据 \(x\)(如图像)由一个未观测的潜在变量 \(z\) 生成。潜在变量 \(z\) 的先验分布被设定为标准高斯分布 \(p_θ(z)=N(0,I)\),这是人为固定的,便于后续从模型中随机采样生成新样本。然而,每个具体样本 \(x\) 对应的 \(z\) 并非直接采自该先验,而是通过编码器学习一个后验分布 \(q_ϕ(z∣x)\),其均值和方差由神经网络从训练数据中学习得到,从而实现对数据的有效编码。

解码器则定义了条件分布 \(p_θ(x∣z)\),通常为以 \(z\) 为输入、输出图像均值的高斯分布。这表示:给定一个潜在编码 \(z\),模型可以生成符合该分布的图像 \(x\)。因此,解码器不仅是一个映射函数,更是一个“分布生成器”,使模型具备生成多样样本的能力。

Encoder & decoder network

网络生成的实际上是每个变量的分布,即均值和方差

VAE的目标是让模型生成的数据分布接近真实数据分布。这通过最大化数据的边缘似然:

\[ p_θ(x)=∫p_θ(z)p_θ(x∣z)dz \]

实现,即让真实样本 \(x\) 在模型下的概率尽可能高。

但由于该积分难以直接计算,VAE采用变分推断,引入证据下界(ELBO)作为优化目标

\[ \begin{align*} \log p_{\theta}(x^{(i)}) &= \mathbb{E}_{z \sim q_{\phi}(z|x^{(i)})} \left[ \log p_{\theta}(x^{(i)}) \right] & (\text{$p_{\theta}(x^{(i)})$ Does not depend on $z$}) \\ &= \mathbb{E}_{z} \left[ \log \frac{p_{\theta}(x^{(i)}|z)p_{\theta}(z)}{p_{\theta}(z|x^{(i)})} \right] & (\text{Bayes' Rule}) \\ &= \mathbb{E}_{z} \left[ \log \frac{p_{\theta}(x^{(i)}|z)p_{\theta}(z)q_{\phi}(z|x^{(i)})}{p_{\theta}(z|x^{(i)})q_{\phi}(z|x^{(i)})} \right] & (\text{Multiply by constant}) \\ &= \mathbb{E}_{z} \left[ \log p_{\theta}(x^{(i)}|z) \right] - \mathbb{E}_{z} \left[ \log \frac{q_{\phi}(z|x^{(i)})}{p_{\theta}(z)} \right] + \mathbb{E}_{z} \left[ \log \frac{q_{\phi}(z|x^{(i)})}{p_{\theta}(z|x^{(i)})} \right] & (\text{Logarithms}) \\ &= \underbrace{\mathbb{E}_{z} \left[ \log p_{\theta}(x^{(i)}|z) \right] - D_{KL}(q_{\phi}(z|x^{(i)})||p_{\theta}(z))}_{\mathcal{L}(x^{(i)}, \theta, \phi)} + \overbrace{D_{KL}(q_{\phi}(z|x^{(i)})||p_{\theta}(z|x^{(i)}))}^{\geq 0} \\ \end{align*} \]
KL term

KL 散度(Kullback-Leibler Divergence),也叫相对熵(Relative Entropy),是用来衡量:

一个概率分布 \(q(x)\) 与另一个概率分布 \(p(x)\) 之间的差异程度。

它回答的问题是:

“如果我用分布 $ q $ 来近似真实分布 \(p\),我会损失多少信息?”


数学定义(连续情况)

对于两个连续概率分布 \(p(x)\)\(q(x)\),KL 散度定义为:

\[ D_{\text{KL}}(q \parallel p) = \int_{-\infty}^{\infty} q(x) \log \frac{q(x)}{p(x)} dx \]

离散情况(更直观)

如果 \(x\) 是离散的,KL 散度为:

\[ D_{\text{KL}}(q \parallel p) = \sum_{x} q(x) \log \frac{q(x)}{p(x)} \]

关键性质

性质 说明
✅ 非负性 \(D_{\text{KL}}(q \parallel p) \geq 0\),当且仅当 \(q = p\) 时等于 0
❌ 不对称性 \(D_{\text{KL}}(q \parallel p) \neq D_{\text{KL}}(p \parallel q)\),所以不是距离
📌 方向性 \(D_{\text{KL}}(q \parallel p)\) 表示:用 \(p\) 近似 \(q\) 的代价

直观理解

  • 如果 \(q(x)\) 在某个地方有高概率,而 \(p(x)\) 很低 → \(\log \frac{q(x)}{p(x)}\) 很大 → KL 值大

  • 如果 \(q(x) \approx p(x)\) 处处成立 → \(\log \frac{q(x)}{p(x)} \approx 0\) → KL 值接近 0

所以 KL 散度越小,说明两个分布越相似。


一句话总结

KL 散度 \(D_{\text{KL}}(q \parallel p) = \int q(x) \log \frac{q(x)}{p(x)} dx\) 衡量的是:用分布 \(p\) 来近似分布 \(q\) 时的信息损失,值越小表示两个分布越接近。

于是需要训练的目标是 ELBO,得到相应的参数 \(\theta^*, \phi^*\)

\[ \theta^*, \phi^* = \arg \max_{\theta, \phi} \sum_{i=1}^{N} \mathcal{L}(x^{(i)}, \theta, \phi) \]

一个基本训练路线如下所示

详细可以参考

那么我们的生成方式就是利用解码器对高斯分布随机选取的 z 进行解码得到新的图像

我们也可以改变 z 的一些变量的值,可以发现生成的图片的特征也发生了相应的变化

9.4 Generative Adversarial Networks (GAN)

GAN 是一种基于博弈论的生成模型,它通过两个神经网络之间的“对抗”来学习数据分布并生成新的样本。这两个网络分别是:

  • 生成器(Generator, G*G*):负责从随机噪声中生成尽可能逼真的样本。

  • 判别器(Discriminator, D*D*):负责区分生成的样本和真实的数据样本。

GAN 的核心思想是让生成器和判别器进行一个“猫鼠游戏”,在这个游戏中:

  • 生成器试图生成越来越逼真的样本以欺骗判别器。
  • 判别器则试图提高自己的能力,准确地区分生成的样本和真实的数据样本。

最终目标是达到一个平衡点,在这个点上生成器生成的样本足以“欺骗”判别器,使得判别器无法区分生成的样本和真实的数据样本。

我们需要完成的损失函数优化如下:

\[ \min_{\theta_g} \max_{\theta_d} \left[ \underbrace{\mathbb{E}_{x \sim p_{data}(x)} \log D_{\theta_d}(x)}_{\text{Discriminator output for real data } x} + \underbrace{\mathbb{E}_{z \sim p(z)} \log (1 - D_{\theta_d}(G_{\theta_g}(z)))}_{\text{Discriminator output for generated fake data } G(z)} \right] \]
  • Discriminator (\(θ_d\) ) wants to maximize objective such that \(D(x)\) is close to 1 (real) and \(D(G(z))\) is close to 0 (fake)

  • Generator (\(θ_g\) ) wants to minimize objective such that \(D(G(z))\) is close to 1 (discriminator is fooled into thinking generated \(G(z)\) is real)

我们整个训练过程就像是两个棋手在博弈,交替训练 discriminator 和 generator

  • Gradient ascent on discriminator
\[ \max_{\theta_d} \left[ \mathbb{E}_{x \sim p_{data}(x)} \log D_{\theta_d}(x) + \mathbb{E}_{z \sim p(z)} \log (1 - D_{\theta_d}(G_{\theta_g}(z))) \right] \]
  • Gradient descent on generator
\[ \min_{\theta_g} \mathbb{E}_{z \sim p(z)} \log (1 - D_{\theta_d}(G_{\theta_g}(z))) \]

但是在实践过程中我们发现对 generator 的优化做的并不是那么好,

我们可以发现

  • \(D(G(z))\) 接近于 0 时(即生成样本明显为假),损失函数 \(\log⁡(1−D(G(z))\) 的曲线非常平坦。
  • 曲线平坦意味着梯度较小,这会导致生成器参数更新缓慢,学习过程变慢。

于是我们使用 \(\log⁡(D(G(z)))\) 作为生成器的损失函数,训练生成器的时候采用梯度上升的方式

\[ \max_{\theta_g} \mathbb{E}_{z \sim p(z)} \log (D_{\theta_d}(G_{\theta_g}(z))) \]

这样我们在开始的时候就可以获得较大的梯度,在实践中的结果很好

Note

同时训练两个网络是具有挑战性的,可能会不稳定。选择具有更好损失地形的目标函数有助于训练。

训练算法的代码大致如下:

可以看到实践上我们有时候会更多地训练 discriminator。这就是实践上的 trick 了

在训练结束之后,我们就可以利用生成器来产生新的图片了。将生成器的网络改为 CNN 之后,得到的结果相当好!


深入到 GANS 内部,我们尝试理解 z 特征的含义

我们随机选择两个 z ,然后对两者进行插值,将中间的结果放入生成器中生成相应的结果

可以看到中间的结果在视觉上也是一种插值的结果

z 值甚至可以做加减


GANs 是截止2017最好的结果了,基础版本的不足之处在于难以训练,后续提出了很多 GANs 的不同版本,如 Wasserstein GAN, LSGAN 等等,还有很多其他的 GANS,可以参考

评论区

对你有帮助的话请给我个赞和 star => GitHub stars
欢迎跟我探讨!!!