是……是吗?
O. 生成式模型绪论
生成式模型,归根到底就是要支持从某个集合中生成样本。生成的模式大体可以分为以下几种:
- 基于似然性的模型:对于样本集合中的某个元素 \(x\),其似然性 \(p(x)\) 是可以被直接求出的。但是我们关心的是如何采样而不是给定样本判定其出现的概率,因此需要其它方法来对其采样,例如 MCMC。
- 基于采样的模型:直接进行采样。但是,仅知采样方法,往往难以计算似然性。
「采样」对应的英文是 sample 或 generation。至于「计算似然性」,有一个专有名词是 inference——不过实际上它可能与采样有些混用(是我的问题还是别人的问题?)
这个模型支持不完全的似然性和采样:EBM。
这些模型仅支持采样,不支持计算似然性:VAE、GAN、SBM、Diffusion。
这些模型既支持采样,又支持计算似然性:NF、自回归模型。
MCMC 误差大、效率低,因此并非合适的选择。大部分 distance metric 只在可计算似然性时能通过 Monte Carlo 计算。仅在分布简单(如 Gaussian)时,存在简单的计算方法。
这其中,最常见的 metric 是 KL 散度
其中,我们一般默认 \(p\) 是先验分布,\(q\) 是用来拟合其的分布。则这种 KL(\(p\) 在前 \(q\) 在后)的分布被称作 Forward KL。当使用单峰分布(如 Gaussian)的 \(q\) 来拟合 \(p\) 时,若 \(p\) 是多模态(多峰)函数,最优的 \(q\) 会拟合其中一个最主要的峰,而忽视所有其它峰。另一种 \(q\) 在前 \(p\) 再后的 KL 被称作 Reverse KL,最优的 \(q\) 会均匀地拟合所有模态,但是每一个模态拟合效果都不佳。
I. 基于能量的模型
这是一类相对泛用的思想。假如可以对某个样本 \(x\) 定义一个能量 \(E(x)\),则可以令其出现的概率为 \(p(x)=\dfrac1Ze^{-E(x)}\),其中 \(Z=\sum_xe^{-E(x)}\) 是归一化系数。
要算似然性就要算 \(Z\),而这是困难的。不过,使用 MCMC,则采样时作 \(x\to x'\) 则只在意 \(\dfrac{p(x')}{p(x)}\),于是 \(Z\) 就被约去了。
训练时假设要最大化某个集合的对数似然性,即最大化 \(\dfrac1{|S|}\sum_{x\in S}\log p(x)\),则有
现在假如我们的 \(E(x)\) 是被某个可微神经网络 \(\theta\) 刻画,则直接得到
这就是基于能量的模型 (Energy Based Model) 的全部思想。
Hopfield Network & Boltzmann Machine
这两者中,参数 \(\theta\) 就是一个矩阵 \(W\in M^{n\times n}\),然后数据集是 \(\cur{\pm1}^n\)。能量是 \(E(x)=-\dfrac12x^TWx\)。
EBM 的核心是 Monte Carlo。因为模型的特殊结构,此处可以每次仅尝试翻转一位,则变成 Gibbs Sampling。
要想增强 BM 的表现力,就要给它多安一些隐藏的神经元,即 Hidden Boltzmann Machine。但是这样做会让 \(p_\t{data}\) 难以求(因为对于数据,我们只知道其可见处的值,不可见处的值是不知道的)。解决方案是只对隐变量作 MC,即 impainting 任务:补全缺损图样。对于每一个训练数据,对其做几遍 impainting 补全隐变量即可。
这样的 HBM 训练比较慢(主要是因为难以并行)。RBM 是一种改进后的结构:令可见变量为 \(v\in V^n\)、不可见变量为 \(h\in V^m\),则 \(E(x)=-\dfrac12 vWh\),即转移是二分图。这样 impainting 时,Gibbs Sampling 只需进行一轮,因为 \(v\) 是固定的。
II. 基于隐变量的模型
我们希望存在一个易采样的隐变量分布 \(p(z)\),和另一个易采样的条件分布 \(p(x|z)\),这样要生成样本 \(x\),只需先采样 \(z\) 再根据 \(z\) 采样 \(x\) 即可。
如何训练这个模型?我们有的是很多 \(x\)。因此建立后验模型 \(q_\varphi(z|x)\) 和条件模型 \(q_\theta(x|z)\),\(q_\theta\) 就是由 \(z\) 采样 \(x\) 的模型,被称作 decoder;而 \(q_\varphi\) 即为 encoder。训练时需要 encoder 辅助,而采样时只用 decoder 即可。
那么这个模型就有两方面需求:
- 一方面,我们希望对于固定的 \(x\),有 \(q_\varphi\) 尽量贴合某个易采样的先验分布 \(p(z)\)。
- 另一方面,我们希望 \(x\to z\to x'\) 得到的 \(x'\) 尽量贴合原本的 \(x\)。
于是对于固定的 \(x\),可以直接搓一个式子出来
这个式子看上去非常粗暴:仅仅是一个 NLL 和一个 KL 的和取反后的结果(因此是越大越好)。但是其实是很有道理的。
同理,上述隐变量模型只是一个框架,具体的 \(q_\varphi,q_\theta\) 都可以是一切模型。不过,无论模型如何,有两个问题是需要特别注意的:
- Reconstruction Likelihood 当令 \(z\sim q_\varphi(z|x)\) 并以此估测时,只能 MC。MC 就带来两方面的问题:难以 scale up——这还不是最糟糕的——以及,sample 的过程是不可微的,则梯度无法回传到 \(q_\varphi\) 中。
- KL 散度同样不好求。
下述 VAE 通过一些特别的技巧分别解决了这两个问题。
AE
首先介绍一下 AE (Autoencoder)。其被用于特征提取,不对隐空间的分布作要求,仅使用 Recon Loss。其 Encoder 和 Decoder 都是确定性的。这就导致隐变量的分布是非连续的,有很多隐空间中的点并不能正确 decode。Encoder 的随机性就是用来填充那些不在数据中的方位的。这就是有的时候我们需要人为加一些随机性(特别是训练的时候)的原因:为了抚平那些不存在的点。之后出现的 SBM 会更多体现这一点。
VAE
在 VAE 中:
- encoder:\(q_\varphi(z|x)\) 是 \(\c N(\mu_\varphi(x),\sigma^2_\varphi(x))\),其中 \(\mu_\varphi\) 和 \(\sigma_\varphi\) 都可以是任何可微网络。
- 隐变量分布:\(p(z)\) 被固定为 \(\c N(0,I)\)。
- decoder:\(q_\theta(x|z)\) 是 \(\c N(\mu_\theta(z),\sigma^2_\theta(z))\)。在模型简单时,也可以默认 \(\sigma=1\),乃至直接不要 \(\sigma\),直接把 \(q_\theta(x|z)\) 变成一个确定性神经网络 \(f_\theta(z)\)。
现在,来解决前述的两个问题。
- Recon Loss 使用 Reparameterization Trick:原本是 \(z\sim\c N(\mu_\varphi(x),\sigma^2_\varphi(x))\),现在直接变成 \(z\sim\mu_\varphi(x)+\sigma_\varphi\cdot\c N(0,I)\),这样采样的部分就只有 \(\c N(0,I)\) 这个不需要回传的东西了。此外,这样做还降低了 MC 的误差,使得只需要少量甚至一次采样即可处理(因为采样的东西是很低维的正态分布,所以误差被大大降低了)。
- KL Loss 现在是在两个 Gaussian 间求。显然,这存在封闭形式解。
VAE 的问题之一在于假设了隐变量是单峰 (Gaussian) 的,且 Reverse KL 进一步强调了这一点。此外,使用 MC 求 Recon Loss 总归是不牛的。有一些改进版模型一定程度上规避了这些问题。
CVAE
我们可能还需要一个标签 \(y\),并强制模型只生成某个标签下的图片。
无非是 encoder 用 \(q_\varphi(z|x,y)\),decoder 用 \(q_\theta(x|z,y)\) 即可。
那么半监督学习,即同时存在有标签和无标签的数据呢?
此时不仅需要 \(q_\varphi(z|x,y)\),还需要 \(q_\varphi(z,y|x)\)。因此 encoder 还要额外支持一个 \(q_\varphi(y|x)\) 的部分。具体而言,有
可以发现,因为没法对 \(y\) 进行 reparameterization,所以必须枚举 \(y\),这就导致可支持的类型数目不能太多。
β-VAE
将 KL loss 前添加一个可以调整的超参 \(\beta\),即改为
大的 \(\beta\) 会强调 KL,即让分布趋近于 Gaussian,带来的效果就是 \(z\) 的每一维的效果解耦(因为这是 Gaussian 固有的性质)。小的 \(\beta\) 会强调 recon,质量更好,代价是分布不像 Gaussian。
Gumbel-Softmax
使用 Gaussian 作为隐变量分布不是很牛。能不能让隐变量的取值是离散的?即,隐变量是 \(z\in\cur{0,\dots,K-1}^m\)。希望让 \(z\) 的每一维都是 \(\t{Unif}(0,\dots,K-1)\)。
如果要建模一个离散分布,我们会选择什么?显然,是 softmax。那么一个基础的结构就已经很清晰了:
- Encoder:第 \(i\) 位上有 \(q^i_\varphi(z^i|x)=\t{softmax}(l^i_\varphi(x))\),其中 \(l^i_\varphi\) 是一个长度为 \(K\) 的 logit。
- Decoder:\(q_\theta(x|z)\)。
现在来处理 loss。
- 因为每一位的 \(q_\varphi^i\) 是独立的,所以 KL 自然可以分开计算。
- 但是,Recon Loss,还是需要一种和 reparameterization 类似的手法,以取得比单纯 MC 更好的效果。
使用一些数学手段。定义 Gumbel 分布
其中 \(p(x)\) 是 PDF。满足 \(Q(\mu,\beta)=\mu+\beta\cdot Q(0,1)\)。
这个分布满足一个良好的性质:对于一组 \(\cur{\mu_i}\),令 \(k=\t{argmax}\{x_i\gets Q(\mu_i,1)\}\),则 \(k\) 即服从 \(\t{softmax}(\mu_i)\) 的分布。由此,将 softmax 转为 hardmax。那么,就有
……虽然这么做看起来很有道理,但是它终究没有摆脱 MC 的桎梏,因此还是不很牛,只能处理维数不很高的场合。
VQ-VAE
另一种建模离散分布的方式是维护一个含 \(K\) 个向量 \(e_0,\dots,e_{K-1}\),所有向量均属于 \(\R^d\) 的字典 \(E\)。Encoder 在确定 \(z\) 的第 \(i\) 位即 \(z^i\) 时,会使用神经网络生成一个 \(\R^d\) 的向量 \(v^i\),然后从字典中寻找最近邻居编号作为量化结果。
那么,这里的 encoder,就是确定性的。之所以确定性也可以,一方面是因为最近邻居这件事本身就对邻域不敏感,如前文所述,填充了未在训练数据中出现的部分;另一方面,是字典本身也会动态更新,保证了具有强适应性。
确定性的 encoder 首先就完全规避了 MC 的不稳定性——它本身都是确定性的,还用得着 MC?还有另一个好处就是 KL 是常数……感觉完全脱离了 VAE 的框架了!但是我们仍然称之为 VAE 而非 AE,因为 VAE 相对于 AE 的核心在于隐空间的连续性和可生成性,而 VQ-VAE 仍然保证了这两点。
现在考虑其应该被如何训练。有三个部件要被训练:
- 从 \(x\) 到 \(v^i\) 的 Encoder \(q^i_\varphi(v^i|x)\);
- 被用于寻找最近邻居的字典 \(E=\cur{e_0,\dots,e_{K-1}}\);
- 从离散数据到生成结果的 Decoder \(q_\theta(x|z)\)。
因为最近邻居显然不是可微函数,因此只能另辟蹊径。
一方面,要学习字典,所以 \(e_{z^i}\) 应该贴近 \(v^i\);另一方面,要学习 Encoder,所以 \(v^i\) 又应该贴近 \(e_{z^i}\)。因此两方面统合得到以下方法
其中,\(\t{StopGrad}\) 是停止梯度回传的标记。为了让训练稳定,在训练 \(E\) 时显然应该用 moving average——因为传进去的东西被停止回传了,所以就当成一个常数处理即可。
会训练了,又引出下一个问题:以上过程并没有运用 KL 散度等对隐空间的分布作显式的约束。因此需要额外训练一个 \(q_\psi(z)\) 以在生成时先验地采样 \(z\)。这是在整个 VQ-VAE 被固定后再进行的:在 Encoder、字典、Decoder 均固定后,所有的训练样本对应的 \(z\) 也都确定了,使用这些东西为数据训一个自回归的模型来直接生成 \(z\) 即可。
注意到 VAE 仍然没有限制 Encoder 和 Decoder 的结构。现行的 Encoder 一般都不会对输入样本有过大的改变,例如如果输入数据是图片,Encoder 就会是一堆卷积,最终的 \(z\) 仍然是一个二维结构;输入数据是音频,Encoder 就会是时域卷积,最终的 \(z\) 仍然是一个线性结构;输入数据是文本,Encoder 就会是 BERT 状物。这就使得对 \(z\) 的处理就可以使用相应的自回归模型直接一步到位:图片则是 PixelCNN、音频则是 WaveNet、文本则是 Transformer-Decoder。
VQ-VAE 2
做了一些神秘的改进。例如,采取了一个双层 VAE 的模式:
- 有一个上层,通过上层的编码器 \(\t{Enc}_\t{top}(x)\) 生成对应的向量 \(v_\t{top}\),然后由上层的密码本 \(E_\t{top}\) 得到量化后的隐变量 \(z_\t{top}\)。
- 有一个下层,下层的编码器使用输入 \(x\) 和上层特征 \(v_\t{top}\) 共同得到下层向量,然后使用下层密码本量化得到 \(z_\t{bottom}\)。一般而言,下层编码器会对 \(v_\t{top}\) 作一个名叫 上采样 的操作后,直接加到 \(x\) 上,然后过常规 Encoder。上采样是把低分辨率图像扩张为高分辨率的过程——Encoder 一般会作压缩。
- 最终选择 \((z_\t{top},z_\t{bottom})\) 一同作为隐变量,传给 Decoder。
- 使用条件 PixelCNN 建模 \(p(z_\t{top})\) 和 \(p(z_\t{bottom}\mid z_\t{top})\)。
- 一般而言,上层因为分辨率低,可以使用更强大(但开销也大)的 Encoder,把握全局特征;下层则把握零碎特征。
MHVAE
这是 Diffusion Model 的直接理论根底。希望隐变量并非一步到位,Encoder 是分步的 \(q_\varphi(z_1|x),q_\varphi(z_2|z_1),\dots,q_\varphi(z_T|z_{T-1})\),而 Decoder 则是反向的 \(q_\theta(z_{T-1}|z_T),\dots,q_\theta(x|z_1)\)。因为前向过程是一个 Markov Chain,所以这个模型被称作 Markovian Hierarchical VAE。其 VAE 直接对整个 Markov 链展开,可以得到
其中,粉色的部分就是 Reconstruction Loss,即从第一层重建第零层(原始值)的误差。蓝色的部分进行一些推导
就是我们熟悉的 VAE 中的 KL 散度,专业术语是 Prior Matching Loss。
最后紫色的部分也可以类似推导,最终得到如下的 MHVAE ELBO
- 第一部分是重建的对数似然。
- 第二部分是最后一层拟合先验分布的误差。
- 第三部分是正反向结果保持一致的误差。
这是一种推导方式,还存在另一种得到形式更好的误差的方式。仍然回到最初的 ELBO 式
其中,红色部分的添加是因为 Markov 性质。为什么我们要加入它?因为接下来要代入 Bayes 公式,得到
红色的部分就可以在 \(\prod\) 中裂项相消,得到
- 粉色部分仍然是相同的 Reconstruction Loss。
- 蓝色部分仍是 Prior Matching Term,与之前的区别在于不需要期望——因为裂项的方式较之前一种方式有点变化。
- 紫色部分是新的 Denoising Matching Term。
两种 ELBO 式对于一切 MHVAE 都有效,但是其主要的应用还是在于 Diffusion Model。我们将在讲述其时,recap 相关内涵。
III. 基于对抗的模型
GAN 是一种与似然性无关,直接生成样本的方法。对于自变量 \(z\sim\c N(0,I)\),生成器 \(G_\theta(z)\) 会直接生成一个样本 \(x\)。希望 \(G_\theta\) 和 \(p_\t{data}\) 的分布尽量贴合。用什么 metric 衡量贴合程度?注意到我们不知道似然性,因此 KL 散度等需要知道似然性的 metric 是不能使用的。我们只能使用一个可微的神经网络 \(D_\varphi(x)\) 来衡量生成的质量:它是一个二分类器,给定 \(G\) 伪造的数据,或者原始的数据,\(D\) 尝试区分二者。
\(G\) 的目标是最大化得分
而 \(D\) 的目标是最小化 NLL,也即最大化下式
二者可以交替训练:\(G\) 的 loss 是
而 \(D\) 的 loss 则为
直接训,有一定效果,但不太好。
在此之上,一个更重要的问题是,因为 GAN 无法获取 likelihood,则需要设计一种合适的 evaluate 方案,其不涉及到似然性。
Evaluation: IS Score
原始数据集一般是一个含分类标签的集(如 CIFAR10)。这时候再在上面训一个分类器 \(f(y|x)\),则有两个性质:
- 对于与 \(p_\t{data}\) 相似的 \(x\),这个分类器给出的标签分布会有较低的熵(趋近于某个特定的标签);而不相似的 \(x\),标签的熵就很高(接近平均)。
- 另一方面,又希望生成的 \(x\) 尽量涵盖各种标签。也即,将它们的 distribution 平均后,应该接近随机。
于是第一个比较通用的 metric 就是 Inception Score (IS):定义 \(\bar f(y)=\E_{x\gets G}f(y|x)\),即当 \(x\gets G\) 时 \(y\) 的期望分布,然后有
这个分数越高越好。可以发现,在单个 \(f(y|x)\) 质量高即熵低、平均的 \(\bar f(y)\) 分布广即熵高的场合,这个分数确实会很高。
但是,IS Score 只考虑了数据的 模式,没有考虑数据的 频度。于是就会出现如下场合:倘若生成器记忆住了每种类别恰一个样本,则这个分数一样很高。因此还需要考虑更好的 metric。
Evaluation: FID Score
FID Score 首先使用一个名叫 Inception V3 的模型把生成图像提取特征,然后把特征使用 Gaussian 建模,分别求出 \(\mu_\t{data},\Sigma_\t{data}\) 和 \(\mu_G,\Sigma_G\),然后计算两者间一个叫做 Wassenstein Distance 的东西。
显然,这个 Distance 越低,则二者越接近。
IS 和 FID 均为常见的 metric。
Vanilla GAN Analysis
现在我们回头对朴素的 GAN 为什么效果不好进行一些分析。考虑一个理想状态,即 \(D\) 获取到了 likelihood,即 \(p_\t{data}(x)\) 和 \(p_G(x)\) 都对 \(D\) 开放。那么推式子可知此时应有 \(D_{\varphi^*}(x)=\dfrac{p_\t{data}(x)}{p_\t{data}(x)+p_G(x)}\)。这是在 \(G\) 固定时,最优的 \(D_{\varphi^*}\)。
另一方面,假如判别器已经是最优的 \(D_{\varphi^*}\) 了,那 \(G\) 的 loss 呢?其即为
其可以被 JSD 所衡量。定义 Jensen-Shannon Divergence
则其具有对称性、非负性和三角不等式,因此是一个度量。则 loss 可以用 JSD 描述为
这说明,当 \(D_{\varphi^*}\) 最优时,按照其训出来的生成器倾向于最小化与 \(p_\t{data}\) 的 JSD。
GAN Issues: Mode Collapse & Training Instability
因此,其自然会拥有一些 JSD 固有的性质:JSD 在这方面更像 Forward KL,会倾向于还原某一个特定子模式,而非均匀涵盖所有模式。这种现象被称作 Mode Collapse,包括以下种类:
- Partial Mode Collapse:覆盖了部分模式,但忽略了其它模式。
- Complete Mode Collapse:完全坍塌到单一模式,生成几乎相同的样本。
- Oscillatory Mode Collapse:在不同模式间振荡。
其中,前两者会产生,一方面是因为 JSD 的性质,另一方面也是因为判别器可能不够强大,导致生成器找到了欺骗判别器的简单方式。而最后者的判别器响应速度比较慢(或者说,生成器的学习率太高),因此当判别器会判别当前的模式后,生成器可以切换到其它模式,表现出振荡的态势。这本质上是因为判别器-生成器的博弈并不存在一个 Nash Equilibrium:这个博弈较轻微的场合会导致振荡,而严重的场合会导致压根不收敛,即 Training Instability。
模型难以收敛的另一个原因可能是生成器的梯度消失:因为生成器是从低维到高维的映射,所以判别器可能很容易学习到生成样本所在的低维子空间,因此判别器很容易达到接近满分。而该场合时,生成器所在处不管向哪走都不会编号,梯度几乎为零。
DCGAN
提出了一堆经验性技巧来优化训练。纯纯的调参大赛。
Improved Training Techniques for GAN [Salimans et al, NIPS2016]
提出了一些比较有用的结构性改进。
其之一是把判别器的 objective 由 \(\log(D_\varphi(G_\theta(z)))\) 更换为信息更丰富的另一种。令 \(f_\varphi(x)\) 为 \(D\) 在过全连接层前的结果,则其应该是一个好的特征,所以更希望二者的特征贴近。于是有 feature mapping:使用如下 objective
其之二是给判别器提供一些与同一个 batch 中其它样本的相关性信息,即 minibatch discrimination。如果发生了 mode collapse,那么同一批次的样本应该比较像,而判别器有可能能通过识别这一点来遏制之。具体而言,在获得 batched feature \(f_\varphi(x_{1\sim B})\) 后,对它们统一乘上一个映射张量 \(T\) 得到 \(M_{1\sim B}\),然后按照某种 metric 计算 \(B\times B\) 的相似矩阵(例如,\(C_{i,j}=\exp(|M_i-M_j|)\)),然后为每个 \(i\) 求出额外特征 \(o_i=\sum_iC_{i,j}\),把 \((f_\varphi(x_i),o_i)\) 一同传给最后一层,最后一层依据这两个信息再来为每个位置打分。
其之三是作 historical average 来降低 oscillation。
其之四是在模型很自信时,让它最高只提供 \(0.9\) 的置信度。这是因为,当训练数据的权重为 \(\alpha\)(默认为 \(1\))、生成数据的权重为 \(\beta\)(默认为 \(0\))时,最优的 \(D^*=\dfrac{\alpha\cdot p_\t{data}(x)+\beta\cdot p_G(x)}{p_\t{data}(x)+p_G(x)}\)。这种被称作 One-sided label smoothing 的方法会在 \(\beta>0\) 时,如果 \(p_\t{data}(x)=0\),则会提供令 \(p_G(x)\) 趋近 \(0\) 的激励。
WGAN
有很多问题是 JSD 这个 metric 不够好导致的。一个问题是,在两个分布完全不重叠时,JSD 会为无穷大,不提供任何有效信息。如果要想在此时提供一个令两者贴近的激励,可以使用 Wassenstein Distance
其中,\(\gamma\) 是边缘分布分别为 \(P,Q\) 的一个联合分布。这个 metric 的别名是 Earth Mover's Distance,因为它的直观理解方式可以是,进行最少的“搬动”使得 \(P,Q\) 相等,而搬动的代价是其移动的距离。
如果使用 WD,就会为两个分布提供一个贴近的激励,而这是好的。但是,注意到 JSD 并非我们刻意引入的,因此如何将其替换为 WD 就有一些挑战。并且,对联合分布 \(\gamma\) 求上界也是困难的。
正如 Total Variance Distance 有两种等价表述一般,WD 同样可以通过一种 Kantorovich Rubinstein Duality 来转化为一种更优雅的形式
其中,\(|f|_L\leq K\) 即指 \(f\) 是 \(K\)-Lipschitz 连续,即 \(\forall x,y:|f(x)-f(y)|\leq K|x-y|\)。显然只需要证明 \(K=1\) 的场合即可,而此时其与原始定义是对偶的。具体推导省略,先 take it for granted。
那么,WGAN 中的判别器就需要维护一个 \(1\)-Lipschitz 的 critic \(f_\varphi(x)\)。
- 判别器使用 \(L(\varphi)=\E_{x\sim p_\t{data}}f_\varphi(x)-\E_{x\sim p_G}f_\varphi(x)\)。
- 生成器使用 \(L(\theta)=\E_{x\gets G_\theta(z)}f_\varphi(x)\)。
但最大的难点其实在于确保 critic 确实是 \(1\)-Lipschitz 的。论文放弃了数学推导(事实证明,在 DL 中,数学越多效果越差!),而直接使用如下经验性策略:
- 对所有参数进行梯度裁剪。
- 不使用会过量累积的动量,而使用 RMSProp。
- 为保证 critic 训练充分,判别器需要比生成器有更多的更新。一般每 \(n_\t{critic}=5\) 轮更新 critic 后,更新一次生成器。
但是,使用梯度裁剪除了真的简单又方便之外,没有丝毫好处:裁剪阈值设过小,会导致梯度消失;设大了又会让训练难以收敛。因此,有一些更好的方法,例如 Gradient Penalty。
注意到最优的 \(f^*\) 必然满足几乎处处都有 \(|\nabla f|=1\),以保证“传输”效率最高。因此,考虑如下的判别器 loss
其中,\(\eps\gets\t{Unif}(0,1)\) 是插值系数。之所以这样插值,是因为二者中间处恰好是 Earth Mover “传输”时的可能路径,且最容易出现梯度非 \(1\) 的可能,所以需要额外进行约束。但是其也有一些问题,包括更新时要算二阶梯度很昂贵、学习率过高时因为每次选择的 \(\eps\) 不同可能导致训练不稳定等。
Conditioned GAN & Semi-Supervise
假如样本是 \((x,y)\) 即数据-分类二元组呢?生成器需要能生成给定类型的数据,即 \(G(z,y)\to x\);而判别器 \(D(x)\) 不再是真伪二分类,而是一整个 \(K+1\) 类的 distribution:其中前 \(K\) 类为真实样本的分类,以及额外的第 \(K+1\) 类表示伪样本。\(D\) 会提供 logit \(l_1,\dots,l_K\),与手动设置的 \(l_{K+1}=1\) 一起作 softmax 后得到 distribution。
直接一步到位到半监督学习。
- 对于无标签数据 \(x\),判别器的 loss 为 \(L(x,\varphi)=1-\t{softmax}(\t{type}=K+1|l_1,\dots,l_K,1)\)。
- 对于有标签数据 \((x,y)\),判别器的 loss 为 \(L(x,y,\varphi)=\t{softmax}(\t{type}=y|l_1,\dots,l_K)\)。
BiGAN: GAN as Representation Learning
\(G\) 是 \(z\mapsto x\) 的映射。而反过来的提取器 \(E:x\mapsto z\) 则可以被提取特征。如何训练 \(E\)?注意到,我们希望 \((z,G(z))\) 和 \((E(x),x)\) 是同一个分布。于是有 BiGAN [Donahue et al, ICLR2017]:
- 判别器接受 \((x,z)\) 二元组:其既可以是 \((z,G(z))\),也可以是 \((E(x),x):x\sim p_\t{data}\)。判别器试图区分二者。
这个方法比朴素的 Autoencoder 效果更好。
Pix2Pix & CycleGAN: GAN as Style Transferer
以上,我们默认 \(G\) 的输入 \(z\) 是 Gaussian。但是,\(z\) 也可以服从其它东西:例如,它可以是一种风格的图片。那么,对应的 \(x\) 就可以是另一种风格。
这就是 Pix2Pix [Isola, CPVR2017] 的思想:训练数据是 \(\cur{(x,z)}\) 二元组,其中 \(z\) 是输入、\(x\) 是迁移目标。生成器 \(G:z\mapsto x\),判别器尝试区分 \((x,z)\) 和 \((G(z),z)\)。
注意到 Pix2Pix 依赖配对的 \((x,z)\) 二元组。但是显然,这样的数据并不容易找。我们可能只有 \(X=\cur{x_i}\) 和 \(Y=\cur{y_i}\) 两个数据集。
于是有 CycleGAN [Junyan Zhu et al, ICCV2017],就需要两个生成器 \(G:x\mapsto y\) 与 \(F:y\mapsto x\),以及两个判别器 \(D_X(x)\to[0,1],D_Y(y)\to[0,1]\)。它的 loss 是什么呢?
- 首先当然是对抗损失 \(\E_{y\gets Y}\log D_Y(y)+\E_{x\gets X}\log(1-D_Y(G(x)))\)。
- 当然还有另一边的对抗损失 \(\E_{x\gets X}\log D_X(x)+\E_{y\gets Y}\log(1-D_X(F(y)))\)。
- 最后是 循环一致性损失
这是为了在无监督学习中避免模式崩溃。
IV. 完全可追踪的模型
之前介绍的所有模型都无法很准确地确定似然性。而 Normalizing Flow 模型拥有良好的性质,允许准确确定似然性。
其基本原理是,对于一个简单的背景分布例如 \(z_0\sim\c N(0,I)\),经过一众 确定性 且 可逆 的变换 \(f_1,\dots,f_K\),依次得到中间态 \(z_1,\dots,z_K\),然后最终结果 \(x\) 即等于 \(z_K\)。
这样,distribution 就是完全 tractable 的:有
但是显然,算行列式这件事的代价太大了。我们需要保证 Jacobi 矩阵是对角阵。
NICE
首先,按照某种惯例,这里认为 \(z=f(x)\),与前文反向。但是因为存在可逆性,所以两种表述并无区别。
每个 \(f\) 都有一个 \(m\),在计算 \(f(x)\) 时,将 \(x\) 分割为 \(x_{1:m}\) 与 \(x_{m+1:d}\) 两部分。
- \(x\to z\):有 \(z_{1:m}=x_{1:m},z_{m+1:d}=x_{m+1:d}+\mu_\theta(x_{1:m})\),其中 \(\mu_\theta(\cdot)\) 是一个神经网络。
- \(z\to x\):\(x_{1:m}=z_{1:m},x_{m+1:d}=z_{m+1:d}-\mu_\theta(z_{1:m})\)。
显然,有
于是其是保体积变换。
为了让所有维数变得平等,需要加入一些例如随机重排各维或者对维数进行 reverse 的 coupling layer。此外,因为上述变换是保体积的,其表达能力必然受限,因此要在第一层加一个 re-scaling 层 \(z_i=S_{ii}x_i\)。这就是 Nonlinear Independent Components Estimation [Dinh et. al, 2014]。
因为其 Jacobian 很简单,所以其梯度 \(\nabla_x p(x)\) 是容易求的,因此在做 impainting 时,可以直接在定义域上做梯度抬升,这是好的。
Real-NVP
添加了一些缩放。
- \(x\to z\):\(z_{1:m}=x_{1:m},z_{m+1:d}=x_{m+1:d}\cdot\co{red}{\exp(\alpha_\theta(x_{1:m}))}+\mu_\theta(x_{1:m})\)。
- \(z\to x\):\(x_{1:m}=z_{1:m},x_{m+1:d}=(z_{m+1:d}-\mu_\theta(z_{1:m}))\cdot\co{red}{\exp(-\alpha_\theta(x_{1:m}))}\)。
红色的部分就是缩放。有 \(\det J=\prod_{i=m+1}^d\exp(\alpha_\theta(x_{1:m}))_i\)。
GLOW
前面的方法表现力有限。有没有方法让变换仍然可逆且比较通用,但是算行列式的代价没那么大?
令输入 \(x\) 是 \(h\times w\times c\) 的图片,且 \(c\) 比较小。则对于每一个像素,进行 \(z_{ij:}=Wx_{ij:}+b\) 的映射,其中 \(W\) 是一个 \(c^2\) 维矩阵。于是只需要对 \(W\) 算行列式即可,可以 \(O(c^3)\) 简单算。
V. 基于场的模型
Langevin Dynamics
EBM 的一切问题都在于归一化系数 \(Z=\sum\exp(-E(x))\) 难以计算。然而,有一个 Langevin Dynamics 的 MCMC 过程,仅使用 \(\nabla_x\log p(x)\) 就能从任意初始分布出发,关于 \(p(x)\) 采样。注意这里的梯度就是关于定义域 \(x\) 的梯度。
具体而言,对于先验分布 \(x_0\sim\pi(x)\),按照以下方式迭代
其中 \(z_i\sim\c N(0,I)\) 是随机噪音。当 \(\eps\to0\) 时,最终分布会越来越接近 \(p(x)\),但代价是收敛时间越来越长。其中,噪音的加入看似违反直觉,但是其实是一个类似模拟退火的 trick。
因此,可以直接对梯度建模。定义一个 score \(s_\theta(x)=\nabla_x\log p(x)\)。如何训练?
Fisher Divergence and Score Matching
首先,对于任两个分布 \(p,q\),定义它们的 Fisher Divergence
\(F(p_\t{data}(x)\|p_\theta(x))\) 可以被直接拿来当成 objective,但是显然这个形式不能被拿来训练——我们不知道 \(\nabla_xp_\t{data}(x)\)!不过,可以推导得到一个更优雅的形式
这个做法在使用 EBM 建模概率的场合尤其有用,因为未归一化的 \(p(x)\) 和归一化的 \(\tilde p(x)=p(x)/Z\) 具有相同的对数梯度。
但是,注意到计算 \(\t{trace}\) 并非好的选择,这需要进行 \(O(d)\) 次 BP。因此,有必要使用一些更能 Scaling 的方法。
Denoising Score Matching
考虑给原始采样加一点噪声。虽然这看上去很反直觉,但是下一节将阐明这一方法的内涵。本节先来从公式角度指出,这一方法有助于训练。
有 \(p_\t{data}(x)\)。对于 \(x\),可以加上强度为 \(\sigma\) 的噪音 \(q_\sigma(\tilde x|x)\),得到扰动分布 \(q_\sigma(\tilde x)\)。通过一些推导,最终可以得到
直接令噪音是 Gaussian Noise \(q_\sigma=\c N(x,\sigma I)\),即得 \(\nabla_{\tilde x}\log q_\sigma(\tilde x|x)=-\dfrac{\tilde x-x}{\sigma^2}\)。于是即可训练:有
这个式子使用了 Reparameterization Trick,是可以很好地计算的。
但是注意到,其最终生成的 \(s_\theta\) 是在拟合噪声分布 \(q_\sigma(\tilde x)\),因此无法真正还原原始数据;另一方面,如果把噪声规模 \(\sigma\) 设的很小,那么 \(\nabla_{\tilde x}\log q_\sigma(\tilde x|x)\) 就会过大,两方面是一个取舍。
Annealed Langevin Dynamics
Fisher Divergence 有一个内生的问题就是对数梯度差 \(\|\nabla_x\log p_\t{data}(x)-s_\theta(x)\|^2_2\) 被 \(p_\t{data}(x)\) 加权了。这使得在 \(p_\t{data}(x)\) 很低的地方,就算 \(s_\theta(x)\) 的估计极度失真,也不会产生很大影响。
解决方案同样是加噪声:噪声会让原本低密度区域也有样本分布,因此可以准确估测 score 的区域就会大幅增加。但是显然噪声会导致原始数据发生改变,因此需要权衡:
- 强噪声导致可估测 score 的区域扩大,但是高密度区域的 score 质量会受到影响。
- 弱噪声则会增强高密度区域的质量,代价是低密度区域的质量下降。
既然我们使用 score 的过程是 Langevin Dynamics,那么解决方案就很显然了:把噪声级别 \(\sigma\) 也当作 \(s_\theta\) 的输入,可以使用 \(s_\theta(x,\sigma)\) 来获取某噪声规模下 \(x\) 处的 score。在 Langevin 的过程中,以等比数列的速度调小噪声级别,即有噪声序列 \(\sigma_1,\dots,\sigma_L\)。为了保证最初的噪声覆盖全平面,\(\sigma_1\) 应约等于数据点的最远距离;为了保证最终收敛到原始分布,\(\sigma_L\) 应充分小。显然,这是一个类似模拟退火的过程,因此有如下的 Annealed Langevin Dynamics:
- 有噪声序列 \(\cur{\sigma_i}\)、Langevin 迭代参数 \(\eps\)、单一噪声重复次数 \(T\)。
- 迭代噪声序列,定义当前的 step size \(\alpha_i=\eps\cdot\sigma_i^2/\sigma_L^2\),则重复 \(T\) 遍 \(x_{t+1}=x_t+\dfrac{\alpha_i}2s_\theta(x_t,\sigma_i)+\sqrt{\alpha_i}z_t\) 的迭代即可。
NCSN
NCSN 是训练含噪声的 \(s_\theta(x,\sigma)\) 的一种方法。具体而言,希望模型同时关注到所有噪声下的 \(q_\sigma\),因此其 loss 可以被写作
即把所有噪声规模下的 Denoised Score Matching 的 Loss 通过系数 \(\lambda\) 合并了。如何设置 \(\lambda\)?一般取 \(\lambda=\sigma_i^2\),于是上式就变成
其中 \(\eps_\theta(\cdot,\sigma_i)=\sigma_is_\theta(\cdot,\sigma_i)\)。于是可以选择训 \(\eps_\theta\),也可以选择训 \(s_\theta\)(反正二者等价)。
为什么这里要多此一举地定义一个 \(\eps_\theta\) 呢?下一节就将揭晓。
VI. 基于噪声的模型
之前介绍的所有东西本质上仍是 Score Based Model,现在终于来到 Diffusion Model 了!虽然在课上把它当成一种与 SBM 类似状物,但是其本质却是更接近 VAE(准确地说,前文特意提及的 MHVAE)而非 SBM,只不过通过一些数学计算可以表明,它建模对象的实质其实是 SBM 的 score function 罢了。
其在基础 MHVAE 的基础上添加了如下几个条件:
- 隐变量 \(x_{1:T}\) 的形状与原始变量 \(x_0\) 总是相同。注意到出于某些习惯,我们没有使用 \(z\) 表示隐变量,且 \(x_0\) 是原始变量。
- Encoding 的每一步是 不可训练 的固定 Gaussian \(q(x_t|x_{t-1})\sim\c N(\sqrt{1-\beta_t}x_{t-1},\beta_t)\)。因为不可训练,此处的 \(q\) 下没有下标。遵循习惯,有对应的 \(\alpha_t=1-\beta_t\),\(\bar\alpha_t=\prod_{i=1}^t\alpha_t\)。
- 假设最终的分布是标准 Gaussian 分布。
- 因此,要学习的就只有 Decoder 了。
于是,我们可以重新掏出来 MHVAE 的两个 ELBO 式,并令其适配此处的新符号体系。
到这里,我们终于可以解释,为什么要费劲定义两种 ELBO 了。
- 首先,Reconstruction Loss 在两种 ELBO 中都相同,即加噪-降噪流程后,\(\co{pink}{x_0}\) 的重建结果,和 VAE 中相同。
- 其次,Prior Matching Loss 虽然一个有期望一个没有,但是当加噪步数 \(\co{lightblue}T\) 趋于无穷时,显然 \(\co{lightblue}{x_T}\) 会趋向于标准 Gaussian,因此这个都可以忽略。
- 最后,Consistency Loss 或 Denoising Matching Loss,是 Diffusion Model 的核心。一般实践中,都选取 Denoising Matching Loss 为 metric,这是因为前者的期望中同时包含 \(\co{violet}{x_{t-1}}\) 和 \(\co{violet}{x_{t+1}}\) 两者,据说可能方差会比较大(?)。后者也是合理的:\(\co{violet}{q(x_{t-1}|x_t,x_0)}\) 是真实的后验分布,而 \(\co{violet}{q_\theta(x_{t-1}|x_t)}\) 则是使用 Decoder 模型,在仅知道 \(\co{violet}{x_t}\) 的场合逆向 \(\co{violet}{x_{t-1}}\) 的尝试。希望二者结果相近。
真实后验分布 \(q(x_{t-1}|x_t,x_0)\) 可以被证明服从 Gaussian 分布。具体而言,有均值 \(\mu_q(x_t,x_0)=\dfrac{\sqrt{\alpha_t}(1-\bar\alpha_{t-1})x_t+\sqrt{\bar\alpha_{t-1}}(1-\alpha_t)x_0}{1-\bar\alpha_t}\),标准差 \(\Sigma_q(t)=\dfrac{(1-\alpha_t)(1-\bar\alpha_{t-1})}{1-\bar\alpha_t}I\)。可以发现,\(x_t\) 与 \(x_0\) 的取值仅仅影响分布的均值,而分布的标准差在加噪的 schedule \(\cur{\alpha_t}\) 确定后即被固定。
于是,我们对 \(q_\theta(x_{t-1}|x_t)\) 的建模即可使用标准差相同的 Gaussian \(\c N(\mu_\theta(x_t,t),\Sigma_q(t))\)。代入 Gaussian KL 公式后,得到最小化该 KL 的 \(\theta\) 其实是在最小化下式
但是该式不能被直接用于优化,因为 \(\mu_q\) 还涉及到 \(x_0\)。我们希望将 \(\mu_q\) 重塑为只支持 \(x_t,t\) 的形式。这就有三种解法:
- 直接预测原始数据 \(x_0\)。
- 预测噪声 \(\eps\)。
- 预测 score \(\nabla\log p(x_t)\)。
Denoising Diffusion Probabilistic Model (DDPM) 就是在预测噪声,而 SBM 在预测 score。
首先先提一下第一种做法,即建立预测对 \(x_0\) 的预测 \(\hat x_\theta(x_t,t)\),然后直接将其代入 \(\mu_q\) 的计算式然后开训即可。很遗憾的是,因为模型能力有限,这样做效果不是很好。
DDPM
- Forward Diffusion Process 就是不断加噪的过程。系数 \(\alpha_t\) 往往是递减的,即越往后原始数据的比重越小、随机方差的权重越大。此处的 \(\alpha_t\) 与 Langevin Dynamic 中的 \(\alpha\) 虽然地位相似但意义和使用方法完全不同:Diffusion 中的 \(\alpha\) 虽然递减,但一般都取接近 \(1\) 的值;而 Langevin 中的 \(\alpha\) 是衰减的步长,是可以减到 \(0\) 的。
- Sampling Process 则是从纯粹 Gaussian Noise 中依次还原每一步的过程。
有 \(x_t=\sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}\eps_t\) 的递推式。显然,其给人一种强烈的展开欲望,因此得到
这意味着,假如真实噪声 \(\eps_0\) 可以被 \(x_t,t\) 建模,那么 \(\mu_q\) 同样可以。于是最小化模型的预测 \(\hat\eps_\theta(x_t,t)\) 与 \(\eps_0\) 的实际值,即得
把常系数扔掉,即得最终训练目标
知道如何训练后,下一步就是采样。使用 \(\hat\eps_\theta\to x_0\to\mu_q\to\c N(\mu_q,\Sigma_q)\) 的逻辑流程,最终可以得到
注意此处使用了一个 \(\sigma_t\) 来表示标准差,而非 \(\Sigma_q\) 中的那个复杂式子。原论文中 \(\sigma_t^2\) 直接选取了 \(\beta_t\)(即 \(\sigma_t=\sqrt{1-\alpha_t}\)),后面的论文对其做了更多平滑化工作。
- 为什么可以作简化?因为实践证明,扩散模型的主要目标应为匹配均值 \(\mu\)(或等价的噪声 \(\eps\)),而非计较细枝末节的噪声规模。而在噪声规模较小时,简化噪声和原本复杂公式没啥区别。因此不如简化掉。
- 这提示我们,AI 领域,math is cheap,show me your evaluation。
Between DDPM and NCSN
这两个算法之间存在一些深刻的联系,由下述 Tweedie's Formula 所刻画:
假设由真实信号 \(x\) 获得噪声观测 \(y\),且满足 \(y\gets x+\eps:\eps\sim\c N(0,\sigma^2I)\),则反过来即有有后验期望
那么,由
即可推知
代入 \(\mu_q(x_t,x_0)=\dfrac{\sqrt{\alpha_t}(1-\bar\alpha_{t-1})x_t+\sqrt{\bar\alpha_{t-1}}(1-\alpha_t)x_0}{1-\bar\alpha_t}\) 并推一坨大的后,即得
我们前面还得到另一个公式
因此噪声 \(\eps_0\) 和 score \(s(x_t)=\nabla_{x_t}\log p(x_t)\) 本质上仅仅差了一个常数 \(-\sqrt{1-\bar\alpha_t}\),与 NCSN 中的结论相同。从另一个角度来看,这表明扩散模型的去噪就是在沿着 score function 即数据密度增加最快方向移动。
Controllable Generation
如果我们希望生成某个特定类别的图片呢?把类别也当成参数传进去即可。即,
这个 \(c\) 其实可以不局限于一个特定的「类别」,而是可以更加一般:
- 首先,其可以就是一个猫猫狗狗等的类别。解决方案是把类别过一个 MLP 变成 embedding 后,将其嵌入输入 \(x_t\)。
- 其次,其也可以是一个 prompt 句子。解决方案是把图片拆分成若干 embedding 向量 \(Q\),然后使用 prompt 建立 \(K,V\),对二者作一个 cross-attention,使用 attention 的结果操控 \(\eps_\theta\) 的生成。(实际操作会稍微复杂一点,不过大体仍然是基于 cross-attention 的)。也有把 image 和 prompt 的 embedding 排在一块然后做 self-attention 的。
- 最后,其甚至可以是一张图片,例如简笔画等。
LDM
注意到现在所有的 \(x_t\) 均与初始图片 \(x_0\) 具有相同的 shape。这意味着在生成如 \(1024\times1024\) 等高分辨率图片时,效率会很低。
解决方案是,既然 Diffusion Model 本身是一个 VAE 式模型,它自然可以被嵌套入 VAE 的内部,而 VAE 可以实现降维的功能。在 VAE 的隐空间层,使用 Diffusion Model,这就是 Latent Diffusion Model。现今通用的 Stable Diffusion 等模型,正是建立在这种范式下。
DC-AE
寻求更极致的压缩。加了一些例如 Channel Averaging 等方法,以更多地降低 Latent Space 的维数。训练模式也很复杂:先用低分辨率的图和 Reconstruction Loss 训整个模型,再仅保留靠近 Latent 的两层冻结其它部分,最后加上 GAN loss 只训输出头。
ControlNet
对于每一种输入(如边缘检测图、黑白图、简笔画),模型需要被 fine-tune 到适合这种输入。ControlNet 就是借鉴了 LoRA 思想,对基干模型冻结,而把融合控制信号的功能放到 LoRA 中,初始是一个全零的 \(1\times1\) 卷积层,在训练初始不影响基干模型(因为初始全零)时,随着不断训练,控制信号逐渐被整合。
一句话总结:Diffusion 中的 LoRA 技术。
DDIM
现在训很好训(因为多次加噪等于一次加噪),但是采样时必须层层降噪,有点太慢了。
DDPM 的核心无非是两行公式
如果,我们能将其换成非 Markov 链方式,即 \(q_\zeta(x_t|x_{t-1},x_0),q_\zeta(x_{t-1}|x_t,x_0)\),那么采样就会变得更加优雅。
具体而言,\(\eps_\theta\) 其实是对 \(x_0\to x_t\) 的 \(\eps\) 的拟合。这意味着,假如我们知道 \(\bar\eps\gets\eps_\theta(x_t,t)\),就能直接一步到位地还原出
这个估测虽然不是很准(因为模型能力有限),但是不妨碍我们用它重建出
发现了什么?它的解码是确定性的!并且,其可以被加速:可以使用 \(x_t\) 先估计 \(\bar x_0\) 再还原出比如说 \(x_{t-10}\),然后再到 \(x_{t-20}\),再……这直接带来了大量的采样速度提升!当然确定性有时也是需要的,所以还是会加上一个 \(\sigma_tz\),但是这里的常数 \(\sigma_t\) 可以任选——使用 \(\eta\in(0,1)\) 作为参数修正。
Progressive Distillation
DDIM 做到 20x~50x 优化就已经差不多了,如果还想更快怎么办?蒸!Teacher Model 是 DDIM 的两步,然后 Student Model 可以只用一步来拟合之。「渐进式」体现在训练好的 Student Model 就可以被当作新的 Teacher,训练一步当四步的 Student。
这样做需要额外的训练成本,且灵活性受限。
Classifier Guidance
在文生图等有条件的生成任务中,我们希望从条件分布 \(p(x\mid y)\) 中采样——其中 \(x\) 是图像,\(y\) 是描述。早期扩散模型可能出现生成图像质量高但与描述无关的「漂移」现象。于是有 Classifier Guidance:使用外部预先训好的分类器模型,将 \(x\) 拉回到与 \(y\) 对齐的状态。
首先我们有一个 Conditional Diffusion Model \(p_\theta(x_{t-1}\mid x_t,y)\),具有基本的条件生成能力。然后有一个 noise-aware classfier \(p_\phi(y\mid x_t)\),它允许判定一张 加噪图片 的原始类别。
对于后验分布 \(p(x_t\mid y)\),由 Bayes 公式,有
取 \(\log\) 并对 \(x_t\) 求梯度得到
这意味着 引导后 score function = 分类器引导的 score + 原始 score function。于是直接在原始预测噪音(与 score function 成正比)上加一个分类器提供的修正项即可将采样推向分类器更确定是类别 \(y\) 的方向。而分类器修正,因为是关于输入 \(x_t\) 的梯度,而分类器是可微的 MLP,所以直接 AutoGrad 即可!
于是引入超参数「引导强度」\(s\) 表示这一修正的比例,并还原为噪声预测场合,即得去噪流程:
- 标准预测 \(\eps_\t{pred}\gets\eps_\theta(x_t,t,y)\);
- 分类器梯度 \(\t{grad}\gets\nabla_{x_t}\log p_\phi(y\mid x_t)\);
- 使用转化因子变为预测的噪声 \(\eps_\t{grad}\gets-\sqrt{1-\bar\alpha_t}\cdot\t{grad}\);
- 修正噪声 \(\eps_\t{guided}=\eps_\t{pred}+s\eps_\t{grad}\);
- 使用标准的 DDPM/DDIM 公式计算即可。
Classifer Free Guidance
CG 的训练复杂且灵活性差,更何况其分类器模式也不适用于复杂引导(如文本引导)。其扩展 CFG Context Free Grammar Classifier Free Guidance 则摆脱了对分类器的依赖,完全依靠模型自身提供监督信号。
回到上述 Bayes 公式。我们可以移项得到
即 引导 score = 有条件 score function - 无条件 score function。这意味着,只要训练模型同时学会有条件生成和无条件生成,则取两者差即可直接作为引导项。那么流程就很明显了:
训练时:
- 对于输入的图像 \(x\) 和描述 \(c\) 的对,以一定概率随机丢弃描述(将其替换为空描述 \(\varnothing\)),这样模型就可以同时学到条件噪声 \(\eps_\theta(x_t,t,c)\) 和无条件噪声 \(\eps_\theta(x_t,t,\varnothing)\)。
生成时:
- 标准预测 \(\eps_\t{pred}=\eps_\theta(x_t,t,\co{red}\varnothing)\)。
- 直接有引导 \(\eps_\t{grad}=\eps_\theta(x_t,t,c)-\eps_\theta(x_t,t,\varnothing)\)。
- 修正噪声 \(\eps_\t{guided}=\eps_\t{pred}+s\eps_\t{grad}\) 然后仍然使用标准 DDPM/DDIM 公式计算即可。
注意看,此处红色的部分表明,标准预测采用了无条件噪声,与 CG 中的有条件噪声作为标准预测不同,这是为什么呢?
在 CG 的场合,我们的目标是从 \(p(x_t\mid c)\) 中采样;但是这样做有些太平庸了,我们会使用更激进的策略,其针对增强过的分布
采样,给予那些符合条件的样本更高概率。有其即可自然地导出更新公式
其与上述生成流程相匹配。从这个角度来看,\(s\) 的不同取值的影响就非常明显了:\(s=0\) 表明引导无用,即做的是纯粹无条件生成;\(s=1\) 等效于默认条件生成;\(s>1\) 作了 外插 (extrapolation),更强调对描述的服从性,以获得更贴近条件的生成。
VII. 基于噪声的文本模型
SBM 因为显式地寻求对梯度的建模,所以难以处理离散的场合,如文本生成。反之,Diffusion 因为只涉及到随机加噪降噪的 Markov 过程,而并不在意具体对什么类型的变量在操作,所以由 VAE 相关理论,我们可以允许扩散文本模型。
LLaDA
开山之作。虽然我也不知道开了个什么山。
训练:
即,将 \(x_0\) 中占比为 \(t\) 的 token 随机替换为 mask \(\t M\) 后,使用 \(x_t\) 还原每个被 mask 的位置的原始值。
现在,给定一个 prompt \(p_0\),令回答是 \(r_0\),则我们希望自 \(p_\theta(r_0|p_0)\) 中 sample。假设已有 \(t\in(0,1]\) 时刻的 \(r_t\),希望降噪到 \(s\in[0,t)\) 时刻的 \(r_s\),则流程如下:
- 使用 \(p_0,r_t\) 共同预测 \(r_t\) 中所有 mask 的值。
- 将所有预测的值中占比为 \(\dfrac st\) 的部分重新改回 mask,以保证 \(r_s\) 中恰有占比为 \(s\) 的部分为 mask。
- 使用了一些神秘的 remasking 技巧:low-confidence remasking,将置信度最低的 token remask;semi-autoregressive remasking,一块块地生成文本,生成完一段再生成下一段。
显然,其有点过于粗糙了——一开始生成的那些魔怔 token,一旦被生成且未被抹去就会一直存在,而这是不牛的。
然后是 finetuning。对于训练数据,匹配的 prompt-response \((p_0,r_0)\) 对,需要对 \(p_\theta(r_0|p_0)\) 建模。SFT 的式子也很类似
这个东西能通过简单拼接,令 \(x_0=p_0|r_0,x_t=p_0|r_t\) 来与 pretraining 融合。
这整个算法有一定道理。因为有 ELBO 式
但是与常规 autoregressive 模型最大的区别,是这个方法是 intractable 的——它不能计算 \(p_\theta(x_0|x_t)\),只能采样!可能只能使用这个 ELBO 式来算概率。有人提出下式可能更好。
唯一的区别是,将 每个 token 以 \(t\) 的概率被 mask,替换为 恰好 mask \(l\) 个 token。这样做方差似乎更小。
IX. 自回归模型
自回归模型的通用范式是将生成分块为 \(x=[x_1,\dots,x_L]\),然后使用
的方式生成。
这种做法的优势在于 tractability——只要知道分块的方式,且每一块内部是 tractable 的,那么整个数据自然也是 tractable 的。但是,其有最大最大的一点劣势,即在于线性 append 后继的难以并行性。
WaveNet
前 transformer 时代的音频生成模型。
其核心思想是 Dilated Causal Convolution:因为要获得 \(<i\) 的感受野,所以分层进行,第 \(k\) 层的位置 \(i\) 会看到上一层 \(i-2^k\) 处的值。这样,感受野不断倍增,只需要 \(\log\) 层即可覆盖所有位置,可以看做是传统 CNN 在一维时的一种特化。可以添加一些类似 LSTM 的门控机制,以及 residue connection 和 skip connection,以增加稳定性等。
卷积层需要搭配 pre-calc 和 post-calc 食用。
可以使用量化方法:训练时对于时序音频信号,将其量化为 8-bit 共 256 个离散值,然后把 one-hot 的离散值过线性层后映到连续向量;卷积后,最后特征过线性层后映到 256 维概率分布向量。
也可以使用概率方法:即 \(p(x_i\mid x_{1\sim i-1})\sim\c N(\mu_\theta(x_{1\sim i-1}),\sigma_\theta^2(x_{1\sim i-1}))\),以 handle 连续场合。
这玩意除了轻量级一点,其实全面被 transformer 吊起来打。但为什么还值得一提呢?因为它有一些扩展的融合应用。
PixelCNN
把图像分块后,从上到下、从左到右地生成每一块。
如何保证训练时的单向视野?mask。例如,对于一个 5×5 的卷积,kernel 就被 mask 为
11111
11111
11000
00000
00000
但是这就会导致感受野中存在锯齿状的 blind spot,例如如果是 3×3,一个位置 * 经过多层卷积后,能看到的部分就只有下图中 1 处
11111111
1111111-
111111--
11111---
111*0000
00000000
而 - 处的信息就无法被观测,这是一个很大的问题。
Gated PixelCNN
解决方案有很多种,例如开两个 stack。
-
垂直堆栈使用如下形状的卷积核
111 0*0 000以感受上方的东西。
-
水平堆栈使用如下形状的卷积核以感受左方的东西
000 1*0 000
本层的垂直堆栈由上一层的垂直堆栈特征图决定,而本层的水平堆栈由 本层的垂直堆栈 和 卷积后的上一层水平堆栈 使用门控机制组合起来后确定。这里有严格的信息流动设计:水平堆栈永远不会流向垂直堆栈,由此避免循环依赖。
RNN & Transformer
相信大家都会了,跳过!
Parallel WaveNet
考虑朴素 WaveNet 的概率式
注意与前文有一些差别,此处更具体,用指数限制标准差必须为正。
那么可以简单 reparameterization 得到
注意到,只要 \(z_{1\sim i}\) 确定,即可唯一确定 \(x_i\),且表现力没有任何受损。因此可以换一种建模方法,让 \(z_{1\sim i}\) 作为神经网络的输入,即
这样,在生成时,即可采样全体 \(z_i\) 后,直接并行地生成每一位。
但是这么做有什么坏处呢?就是其 inference 也即计算 likelihood 时的效率降低了:原本可以直接计算 \(p(x_i\mid x_{1\sim i-1})\),现在必须计算出全体 \(z_{1\sim i-1}\) 后,才能解出 \(z_i\)。
综上,标准 WaveNet 在自回归生成时不可并行,但 inference 时却可以;并行 WaveNet 则恰恰相反,生成时可以并行,inference 时不可。
如何解决?可以训一个标准 WaveNet \(p_T(x_i\mid x_{<i})\) 作为 teacher model,再 distill 一个并行 WaveNet \(p_S(x_i\mid z_{<i})\) 作为 student model。这样做是合理的:因为训练时只需要 inference,所以用标准 WaveNet 作 Teacher 是好的。注意 distill 时的顺序:要最小化的是下式
为什么不反过来?因为这样可以使用 Monte Carlo:\(p_S\) 是易于 sample 的。因此流程如下:
- 使用 \(p_S\) 采样 \(z\) 和 \(x\)。
- 计算 \(\log p_S(x)\),这可以并行——因为 \(z\) 已知。
- 计算 \(\log p_T(x)\),这可以并行——因为标准 WaveNet 的 inference 可并行。
Multi-Token Prediction
Transformer 有一个问题是生成时不能并行。但是,或许我们可以在序列长度 \(K\) 很小时,进行并行?即,对于 \(K\) 个 token,可以直接有
有一定效果。
不过,这个想法的本质,是使用一个 高速但低质的模型(此处即为并行版本),来近似一个 低速但高质的模型(满血模型)。
因此其其实是一个特例版的:
Speculative Decoding
使用一个低质模型 \(q(x)\) 作 proposal distribution。因为高质模型的 inference 即求 \(p(x)\) 是高速的,所以可以直接使用 Gibbs Sampling 的思想:对于当前前缀 \(x\),考虑一次生成多个后继 token \(x'\),并采用 proposal,即 \(x'\sim q(x'\mid x)\);然后以 \(\min(1,\dfrac{p(x'\mid x)}{q(x'\mid x)})\) 的概率接受。假如被拒绝,再回退到高质模型的生成。但是,对于不同的 \(x'\),回退的概率也不同,为了保证最终仍然服从 \(p\) 的总分布,在调用高质模型得到 \(p(x'\mid x)\) 后,实际要从残差分布 \(x'\propto\max(0,p(x'\mid x)-q(x'\mid x))\) 中采样。可以证明,这样做后总分布不变,仍然是 \(p(x'\mid x)\)。
即,策略如下:
- propose 接下来 \(K\) 个 token。
- 并行 inference 这些 token,找到第一个被拒绝的位置。
- 如果存在被拒绝的位置,单步地回退并使用残差分布重新采样这个位置,并丢弃所有后续 propose 的 token(因为换成了高质模型生成的 token)。
X. 图神经网络
简单讲一些 GNN 相关的内容吧。虽然 GNN 一般不会被拿来当作生成器,而是当作特征提取器。
- 针对图像,我们有 CNN 和 ViT 提取特征。
- 针对文本,我们有 Transformer。
- 针对音频,我们有 WaveNet。
- 针对图论中的图呢?
首先对问题进行建模。有一张带点权 \(x_i\) 的图,要根据这份信息为每个点预测 label \(y_i\)(一般是 01 label)。假设这个 label 与连通性高度相关 (Homophily Assumption)。
因此希望学习得到每个点的特征 \(z_i\)。
GCN
图卷积。根据点权 \(x_i\),可以得到信息 \(h_i\gets f(x_j)\),然后特征通过对邻域进行 pooling 得到,例如 \(z_i=\dfrac1{|N(i)|}\sum_{j\in N(i)}h_j\) (Average Pooling)。还可以有 Maximal Pooling 等。于是,信息会逐渐在图上传播。
写成公式就是
其中 \(A\) 是邻接矩阵,\(\tilde A\) 是度数归一化邻接矩阵(令 \(D\) 是对角的度数矩阵,则 \(\tilde A=D^{-1}A\))。这整个步骤可以被记作一个图卷积 \(Z\gets\t{GC}_G(H)\)。GCN 就是多层 GC 叠一块。
如何训练?最后学出来的特征 \(z_i\) 过一个判别器 \(g(z_i)\) 得到 predicted label \(\hat y_i\),然后算交叉熵即可。
以上是 node label prediction。如果是预测边的存在性即 edge prediction 呢?
因为输入数据是 unlabelled,所以要从原图中随机干掉一些边造出待预测的数据。还需要一些随机图作为负样本。
对于某些图像整体的信息,可以把所有节点放一块再作一个 aggregation,例如 Average Pooling 等。
GraphSage
GC 中的 Aggregation 是 Average Pooling。有人把它换成了 MLP + MaxPooling。还有人用 LSTM + Random Reorder(因为 LSTM 有顺序性)。
GAT
LSTM 都出了,那自然该考虑 Attention 了。甚至因为无序性,都不需要 position embedding。
Issues of GNN
问题之一是 over-smoothing:假如 \(L\) 过大,则所有点的特征会趋于一致,因为所有点的感受野中都有大量重合。解决方法是少用 GC 层,以及在层内用更好的 Aggregation 以增强单层的 capability,还有加一些虚边(例如在二分图中添加一些同侧边)或者虚点(连接所有点)等。如果层真的很多,就用 Residue Connection 吧!
问题之二是邻域 Aggregation 内生的问题:例如,它无法区分一个点是属于三元环还是属于四元环。需要一些更高端的技巧。
XI. 特征学习与对比学习
图神经网络其实就是特征学习的一种:它学习每个节点的特征。
同理,前面提到的 VAE 在生成的同时,也自动提取出了特征;NF、Diffusion 等同理。
但生成式模型也有其问题:其比较难训。假如我们只需要特征的话,有没有更简单的自监督、判别式方法?
解决方案是使用输入 \(X\) 的一部分当作虚拟的标签,即 mask 掉一部分然后预测剩下的部分——这一点已经在 GCC 中 edge prediction 中用过了。此外还有 mask 掉图片的一部分然后要求 impaint、对于黑白图和色调图要求互相预测、对于旋转的图像预测转角等。BERT 也采用了这样的方案。
不过可以看看远处的对比学习。
CPC
开山之作。应用于序列预测的 task:使用特征提取器生成前 \(t\) 时刻的特征汇总 \(c_t\),然后过一个线性层或 MLP 等得到未来 \(k\) 步的预测 \(\hat z_{t+k}\)。之后,选择真实 \(t+k\) 时刻的信息 \(z_{t+k}\) 为正样本,随机采样 \(z_j\) 为负样本。得分为 cosine similarity,要求正样本得分尽量高、负样本尽量低。使用
进行训练。其中 \(\tau\) 是温度。
MoCo
加了一些更好的优化。
- 正样本是对同一个数据应用两种随机数据增强后得到的数据对 \((x_q,x_k)\)。
- 对 query 和 key 使用不同的编码器:后者的编码器使用动量更新,更加稳定。
- 负样本会替代 key 与 query 作匹配。为增强稳定性,维护一个负样本队列,新的 key 会取代最老的负样本。
- loss 同上。
MAE
AutoEncoder 结构,不过与 VAE 不同:VAE 需要好的 Decoder 用来生成,Encoder 会被丢弃;而此处是特征学习,因此需要好的 Encoder,Decoder 则会被丢弃。数据是被大面积 (75%) mask 的图片,任务是预测被 mask 的部分。
CLIP
多模态对比学习,数据是配对的文本和图片对。
XII. 元学习
来点 meta learning。
我们希望模型具有 Few Shot Learning 的能力。
因此,训练数据集 \(D\) 中包括很多的任务,每个任务 \(T\) 由两部分组成:support set \(S_T=\cur{(x_i^S,y_i^S)}\) 和 test set \(B_T=\cur{(x_j^B,y_j^B)}\)。因为是 Few Shot,所以 \(|S_T|\) 一般很小。
一个具有 Few Shot Learning 能力的模型可以被符号化描述为 \(y\gets f_\theta(x\mid S_T)\),即在提供 support set 为 \(S_T\) 后,给定 \(x\),给出对应的 \(y\)。这个模型在某个任务上的能力即为
最优的模型自然就是
那么一个 Meta Learner 的训练自然就由两层循环表示:
- 外层循环:枚举 \(T\in D\),使用其更新当前的 \(\theta\)。
- 内层循环:对 \(\theta\) 在当前 \(S_T\) 上 tune 过后,算 loss 并反向传播回去。
Metric Learning
一种思路是,使用好的特征提取器提取所有东西的特征,然后对于询问 \(x\),找到所有 \(x^S\) 中与之最相近的一个,然后返回对应的 \(y^S\)。
Siamese Neural Network [Koch, Ruslan et al, ICML 2015] 使用 \(\sigma(W|\phi(x)-\phi(y)|)\) 作为衡量两张图片是否属于同一个类别的 metric。还有一些基于 attention 但本质不牛的做法。所以还是看看远处的 MAML 吧。
MAML
\(f_\theta(x\mid S_i)\) 可以使用某个 \(\theta_i\) 来描述,即 \(f_\theta(x\mid S)=g_{\theta_i}(x)\)。
如何求出这样的 \(\theta_i\)?直接 Gradient Descent 即可。令 \(\theta^{k+1}=\theta^k-\eta\cdot\nabla L(S_i,\theta^k)\) 然后迭代多次即可。
但是这个 idea 显然问题很大。首先,要迭代多次才能收敛。其次,你如何对一个 SGD 进行 BP?
答曰:直接使用一步 GD 拟合 SGD 即可。即,令 \(\theta_i=\theta-\eta\nabla L(S_i,\theta)\),然后在这个任务上的 loss 就是 \(L(B_i,\theta_i)\),其中 \(B_i\) 是前面提到的 test set。这个东西是可以 BP 的。
这样学出来的 \(\theta\) 处于一个能很快趋向所有 task 的中间态,具有高度适应力。
Test Time Training
MAML 使用了 support set \(S\) 作为训练样本。假如把 \(B\) 也用上呢?即,利用测试数据本身的信息,可以在推理时进行在线适应,更加贴合这一批数据本身的特色。
TTT 需要三个模型:
- 提取特征的 \(\theta_e\)。
- 主任务头 \(\theta_m\),即为你想做的任务,例如分类器等。
- 辅助任务头 \(\theta_s\),例如旋转预测头。
信息流为,将数据输入提取器得到特征后,分别传给主任务和辅助任务,loss 也是独立的。
在训练阶段,直接将主任务头和辅助任务头的 loss 相加,即可联合训练二者。
在 TTT 阶段,对测试样本应用辅助任务对应的数据增强。例如,辅助任务是旋转,就将图片旋转后,计算在辅助任务上的损失。因为只有提取器对主任务有用,所以冻结辅助任务头,只训提取器。与 MAML 类似,同样可以只用一步 SGD 来近似。
这个做法相当于人造了一个自监督的 metric 出来辅助学习,可能是牛的。
INF. 总结
堂堂完结!上课真不能开摆。注意力涣散了就只能靠 post-training 挽回了。
本文涵盖了几乎所有深度学习课上(准确地说,课件上)cover 的内容,并结合了其它个人的、DeepSeek 老师的、Gemini 老师的、别的课程的或是网络上的各种资料——所以里面会出现不少未在课上涉及的东西,权当课外阅读了。有错漏之处欢迎指出,应该会修改的。

浙公网安备 33010602011771号