Notes——模型坍缩&高维空间&变分分布(sds vs vsd)
- 这篇笔记源自在读 ProlificDreamer 提出的 VSD 对 SDS 的改进思路,感觉比较难理解,所以专门写一篇 Note 记录一下,如果感兴趣可以去查看原文:
- DreamFusion (SDS): https://arxiv.org/abs/2209.14988
- ProlificDreamer (VSD): https://arxiv.org/abs/2305.16213
- 这里就不解释 SDS 的原理了,具体可以看原文,或者我的另一篇 blog 点我
SDS 的一些问题
- DreamFusion 通过对 3D 模型随机采样,对每一个采样点利用一个预训练好的 Diffusion 模型接收文本描述并评分,并以此更新 3D 模型
- 但是 DreamFusion 每次迭代只考虑一个样本点对 3D 模型的更新,也即对于每一个样本点,相对于当前的文本描述,Diffusion 模型会给出一个唯一的评价标准返回;但其实这并不合理——对于一个文本描述,可能同时存在多个合理的渲染结果,也即对于一次迭代,我们的“理想样本”应该是一组特定分布的样本点,而不是一个样本点;因此,DreamFusion 的做法可能会导致“模型坍缩(Model Collapse)”
- 如果我们从概率论的角度来解释的话,DreamFusion 是通过最大化 likelihood 来找到 mode,它所反映的是整个样本空间中概率密度最高的点,但并不一定是概率“质量”最高的点,特别是在高维空间中
- 我们先来看一个例子证明这一点,再来考虑原因,比如 Gauss 分布
- 对于 $d\gt\gt1$ 的高维 Gauss 分布 $\mathcal{N}(0,I)$ 而言,概率密度函数为 \(p(\textbf{x})=\frac{1}{(2\pi)^{\frac{d}{2}}} \exp(- \frac{\mid\mid\textbf{x}\mid\mid^{2}}{2})\)
- 显然,当 $\mid\mid\textbf{x}\mid\mid=0$ 时,指数部分达到最大值 $e^{0}=1$,此时 $p(\textbf{0})=\frac{1}{(2\pi)^{\frac{d}{2}}}$,也即此时在 $\textbf{0}$(注意不是 0 值,而是 0 向量,也即高维空间的原点)处取到 mode,此时 likelihood 最大
- 然后我们来理解一下,什么是概率密度和概率质量
- 概率密度(Probability Density):表示单位体积内的概率(单个点的密度并不是概率,只有把密度在一个区域内积分才能得到该区域的概率)
- 概率质量(Probability Mass):指的是在某个区域内对该区域的概率密度积分得到的总概率,其实也就是我们所说的概率
- 在高维空间中,我们可以使用球坐标把积分拆分为径向部分和角度部分,对 $d$ 维空间来说,半径为 $r$ 的球面的体积元素(想象为球面薄薄一层的体积)与 $r^{d-1}$ 成正比,因此在半径 $r$ 处的概率质量可以写为 \(P(r)\propto r^{d-1}\exp(- \frac{r^{2}}{2})\)
- 当 $r$ 很小时,$r^{d-1}$ 很小,导致整体概率质量下降
- 当 $r$ 增大时,$r^{d-1}$ 很大,即使密度 $r$ 在下降,其积分也有可能变大
- 根据推导证明,$P(r)$ 在 $r\approx \sqrt{d-1}$ 附近达到最大值,也即对于高维的高斯分布而言,概率质量集中在半径为 $\sqrt{d-1}$ 的球壳上,如下图所示
- 可以看到,其中概率质量最大的区域对应的样本是一张“雪花噪声”图,而概率密度最大的点对应的样本却是一张纯色图,相差很大
- 然后我们来理解一下,什么是概率密度和概率质量
- 我们先来看一个例子证明这一点,再来考虑原因,比如 Gauss 分布
一些概念解释:
- 模型坍缩:在训练生成模型时,模型生成的输出变得重复、无意义和缺乏多样性
- 样本空间:对于若干随机变量(比如对于上面 $d$ 维 Gauss 分布,就是 $d$ 个随机变量构成的一个向量),所有可能的观测样本分布所在的空间
- 概率密度函数(PDF):对于一个样本空间而言,对应的概率密度函数可以描述这个样本空间中所有观测样本的分布密度情况
- likelihood:本质也是一个函数,$P(D\mid\theta)$,也即如果你已经得到了数据 D,那么这个数据 D 是用 $\theta$ 参数计算得到的概率
- mode(模式/模型):在概率密度函数中,取值最高的那个点
- typical sample(典型样本):概率质量最高的区域,也即大多数样本实际分布的区域
- 由此,我们可以想象到, SDS 不断放大 likelihood 的优化方式,会导致所有样本都只向着 mode 一个点收敛,从而导致多样性缺失,也即出现“模型坍缩”的现象;同时,也有可能导致很多的随机初始点偏移典型样本,向着 mode 收敛优化
- 另一方面,SDS还有一个问题——它对 $t\sim \text{Uniform}(0,1)$ 进行采样;简单解释一下,$t$ 表示扩散的持续时间,$t$ 值越大,则扩散程度越高,噪声越明显;
- 简而言之,SDS 选择对各个扩散程度的样本都进行采样,这样做的好处是对整个优化过程引入“平滑性”,因为当 $t$ 比较大的时候,离最终结果还比较远,$p_{t}(x_{t}\mid y)$ 分布会相对平滑,梯度更稳定,更容易优化;但问题是,它会导致生成的样本过于平滑,以至于丢失部分细节
- 其实理想情况下,我们只需要对 $p_{t=0}(x_{0}\mid y)$ 这个分布优化即可
- 为了缓解细节丢失的问题,SDS 会使用非常大的 CFG 值来增加细节,又容易导致 SDS 生成的结果过饱和,也即颜色、对比度等参数过强
VSD 的改进思路
- 在开始介绍 VSD 的改进思路之前,我们先了解一下,什么是变分分布 (Variational distribution)
- 其实可以理解为,变分分布就是分布的“变量”,是一个可以不断变化、调整的分布
- 求解某个变量的真实分布往往非常复杂,直接计算或采样都非常困难;因此,我们引入一个结构简单、易于操作的分布,并通过不断调整它的参数,让它尽可能接近想要得到的目标分布——这个简单且可调的分布就称为变分分布
- 现在我们回到 SDS 中,我们已经知道在 3D 生成任务,也即从一段文字描述中生成一个 3D 模型的过程,可能有无数种合理的结果;而 SDS 只关注一个“最优解”,由此导致模型坍缩的问题
- VSD 在 SDS 的基础上,引入变分分布的思想——也即,我们希望找到的不是一个“最优解”,而是一个“最优分布”
- 具体来说,VSD 将 SDS 优化公式的第二项由零均值的 Gauss 换成了变分分布的 score \(\begin{aligned} \text{SDS/SJC:} \quad \nabla_\theta \mathcal{L}_{\text{SDS}}(\theta) &\triangleq \mathbb{E}_{t, \epsilon, c} \left[ \omega(t) \left( \epsilon_{\text{pretrain}}(x_t, t, y) - {\epsilon} \right) \frac{\partial g(\theta, c)}{\partial \theta} \right] \\ \text{VSD:} \quad \nabla_\theta \mathcal{L}_{\text{VSD}}(\theta) &\triangleq \mathbb{E}_{t, \epsilon, c} \left[ \omega(t) \left( \epsilon_{\text{pretrain}}(x_t, t, y) - {\epsilon_\phi(x_t, t, c, y)} \right) \frac{\partial g(\theta, c)}{\partial \theta} \right] \\ \end{aligned}\)
- 这里详细解释一下公式
- $g(\theta,c)$
- 其中 $\theta$ 是模型需要优化的参数,$c$ 是条件(相机参数、视角等指导生成过程的信息);而 $g()$ 表示生成器,以参数 $\theta$ 和条件 $c$ 作为输入,输出生成的结果
- $x_{t}$
- 表示在扩散过程中的噪声图像(也即,输入数据 $x$ 经过 $t$ 时间的扩散扰动后的,带噪声的数据)
- $t$
- 表示扩散过程中采样的时间步
- $y$
- 表示条件信息,比如文本描述
- $\epsilon()$
- 噪声生成器,$\epsilon_{\text{pretrain}}(x_{t},t,y)$,表示以 $x_{t}$、$t$、$y$ 为输入,用预训练权重生成的噪声,代表了 Diffusion 模型认为当前状态应该对应的噪声
- $w(t)$
- 关于时间 $t$ 的权重函数,用来对不同时间步的重要性加权
- $\mathbb{E}_{t,\epsilon,c}$
- 表示对时间 $t$、噪声 $\epsilon$、条件 $c$ 等变量进行平均,这种采样方式确保了梯度更新可以充分考虑整个数据空间及噪声扰动的影响
- ${\epsilon}$ vs ${\epsilon_\phi(x_t, t, c, y)}$
- 在 SDS 中:$\epsilon$ 是直接从标准 Gauss 分布中采样得到的噪声
- 在 VSD 中:$\epsilon_\phi(x_t, t, c, y)$ 则是由一个参数化的变分分布(参数记为 $\phi$)生成的噪声估计
- $g(\theta,c)$
- VSD 的改进主要是为了,额外的变分分布 score 可以让样本收敛到图中灰色圆环上的典型样本区域,同时增加样本的多样性
- 如图所示,对 likelihood 的优化会驱使样本向 mode 点移动,而变分分布的分数惩罚则会驱使样本之间互斥分开
- 不过有一个问题,由于变分分布自身也是很容易不断变化的(你可以想象一组具有几乎固定相对位置的粒子,即使你把它固定在原点附近的区域,它们自身也可能不断调换位置,但保持彼此相对位置不变)
- 而变分分布不断变化,可能会导致梯度信号不稳定,甚至有可能导致训练发散(你可以想象模型的更新方向,一会儿要往左,一会儿要往右,因为目标不是一个点,而是一个范围)
- 因此,VSD 引入了 LoRA (后面有详细解释) ,它可以快速地学习变分分布;并且由于 LoRA 有一些 prior,我们可以用很少量的样本就学习到一个不错的 score
你可以想象,LoRA 本身见过很多的分布,它印象中固定了一种样本之间的分布形状,因此它会阻滞变分分布自身的变化,同时不影响变分分布整体向着正确的方向移动
- 我们可以考虑,变分分布是由 LoRA 在预训练权重上学习出的一个复杂的变分分布,而 particle (粒子)可以被视为变分分布中采样出的一些样本,用来“代表”这个复杂分布
-
另一方面,SDS 一般需要将 CFG 设置为很大的值(比如 100)来增加生成图像的细节;而 VSD 缓解了这一点,通常可以设置为正常的值(如 7.5),从而缓解了 SDS 带来的过饱和问题
- 整体来说,ProlificDreamer 的流程图如下(来自原文献)
- 最后提一下对于 particle 数量的讨论
- 因为每一个 particle 表示的是一个 NeRF 或者一个 Mesh,因此数量无法设置很大,通常是 1-4
- 当particle 只有 $n=1$ 时,VSD 仍然与 SDS 不同;因此 VSD 用了一个比较复杂的网络来建模分布 score,因此即使只有 1 个 particle,它也不会直接聚集在 mode 点,因此仍然能达到比 SDS 更好的效果,并且 CFG 仍然可以设置到一个正常的值
LoRA (Low-Rank Adaption)
- LoRA,低秩适应,听起来似乎很复杂,不过有一个比较简单的比喻让你很容易理解它——
- 假设你有一本写得很好的食谱(预训练模型),你想用它来迎接你的老板,但是你的老板特别迷恋肉桂的味道,因此你想要稍微调整一下食谱,但是又不想重新写一本或者推翻这本食谱;而 LoRA 方法,就是在原食谱的基础上,只加一点“调味料”(额外的低秩矩阵)
- 传统的 finetune 方法往往需要更新模型中的大量参数,导致计算量很大;而且由于用于 finetune 的数据量往往较少,很容易过拟合
- 因此,LoRA 提出的想法是
- 保持原有的预训练参数不变
- 只在部分关键位置增加一个小的,可训练的“补充项”,这些补充项用低秩矩阵来表示
- 因此,LoRA 提出的想法是
- 为什么强调“低秩矩阵”?
- 其实低秩可以理解为一种压缩的方式,一个完整的矩阵可能包含很多信息,而低秩矩阵是用尽可能少的参数来近似原来的矩阵,从而尽可能减少对原模型参数的影响,又能够尽可能对原模型产生一定影响
- 在 LoRA 中,我们将需要调整的权重矩阵 $W$ 拆分成固定部分 $W$ 和一个低秩更新项 $A\times B$(其中 $A$ 和 $B$ 都是比较小的矩阵),也就是 \(W^{\prime}= W+A\times B\)