MIT 6.S184 | 基于随机微分方程的生成式AI | 2026 | 笔记 | Lecture 1: Flow and Diffusion Models

目录

    • 前言
    • [1. Course Introduction](#1. Course Introduction)
    • [2. Class Overview](#2. Class Overview)
    • [3. From Generation to Sampling](#3. From Generation to Sampling)
    • [4. Flow and Diffusion Models](#4. Flow and Diffusion Models)
      • [4.1 Flow Models](#4.1 Flow Models)
      • [4.2 Diffusion Models](#4.2 Diffusion Models)
    • [5. Summary](#5. Summary)
    • 结语
    • 参考

前言

学习 MIT S.184 课程,本篇文章记录课程第一讲:流模型和扩散模型,记录下个人学习笔记,和大家一起分享交流😄

Website:https://diffusion.csail.mit.edu/

Course Notes:An Introduction to Flow Matching and Diffusion Models

1. Course Introduction

这门课程是 MIT CSAIL 在 IAP 寒假学期开设的扩散模型入门课程。课程由 MIT 学生 Peter Holderrieth 和 Ezra Erives 主讲,主要从微分方程的视角讲解扩散模型和流匹配模型的数学理论基础,并辅以实践内容,带领学生从零构建扩散模型。最后,课程还会通过专题讲座介绍这些模型在分子设计和机器人学等前沿领域中的应用。

课程配套的教材笔记写得非常好,推荐仔细阅读。

课程资源

2. Class Overview

大家应该都以某种形式听说过生成式 AI。举几个例子:

我们见过由 AI 算法生成的艺术图像,也见过像 OpenAI Sora 或 Google Veo 3 这样的系统,它们能够生成视频。此外,很多人每天都在使用 ChatGPT 这类语言模型。这些系统的共同特点是,它们都具有某种意义上的 "创造能力",能够生成新的内容。

从最基本的层面来看,这门课要讲的就是生成对象的算法。当然,这里所说的对象并不只是任意对象,而是有用的对象。具体来说,本课程将重点关注 流模型和扩散模型。下面展示的是面向多种数据模态的一些先进生成模型,尤其包括图像、视频和蛋白质等领域:

也许你听说过 Stable Diffusion、DALL-E、OpenAI Sora 或 Meta MovieGen 这类图像与视频生成模型,也可能听说过 AlphaFold3 或 Boltz 这样的蛋白质结构生成模型。这些模型在不同领域中都产生了很大影响,而它们背后有一个共同点:从根本上说,它们都依赖于类似的生成算法,尤其是流模型和扩散模型。这也正是本课程将要讨论的核心内容。

因此,理解这些模型背后的数学原理和算法机制,是一项非常有价值的技能。它能够帮助我们理解当前生成式 AI 系统到底是如何工作的,而不仅仅停留在调用模型或使用工具的层面。

顾名思义,流模型和扩散模型都与常微分方程和随机微分方程的理论密切相关。因此,这门课会包含一定的数学内容,但课程会尽量聚焦于最少且必要的数学工具。与很多只介绍算法结论的课程不同,本课程的讲解会相对严谨,不仅会告诉我们算法是什么,还会展示这些算法是如何推导出来的。

当然,课程也不仅仅关注理论推导,还会强调算法实现。因此,课程中安排了实验环节,要求我们将课堂上学到的知识应用到实践中,亲手构建真正可运行的生成模型。

OK,下面简单概述一下整个课程安排:

Class Overview

  • Lecture 1:
    • From Generation to Sampling: Formalize "generating an image/etc."
    • Construct Flow and Diffusion Models
  • Lecture 2 - Flow Matching: Training algorithm.
  • Lecture 3 - Score Matching, Guidance: How to condition on a prompt.
  • Lecture 4 - Build Image Generators: Network architectures + Latent spaces
  • Lecture 5 - Advanced Topics: Discrete diffusion models, distilled models

在第一节课中,我们将讨论 "生成某个东西" 到底意味着什么,并用数学语言对这个问题进行形式化。随后,我们会构建流模型和扩散模型,理解它们的基本设定以及我们希望它们完成的任务。

第二节课将讨论流匹配,这是训练流模型的一种基本算法。第三节课将讨论 score matching(分数匹配)以及 guidance(引导)。其中,guidance 本质上回答的是如何根据 prompt 对生成过程进行条件控制。也就是说,我们不只是希望模型生成一张任意图像,而是希望它能够根据特定文本提示生成符合要求的图像。

第四节课将讨论如何构建图像生成模型,重点包括具体的网络结构以及潜在空间的设计,使得生成系统能够更加高效地扩展。最后,课程还会介绍一些进阶主题,例如离散扩散模型和 distilled 模型。

OK,下面正式开始本次课程的内容。

3. From Generation to Sampling

我们首先要讨论的是:生成某个东西到底意味着什么?

"生成" 本身是一个非常主观的说法。如果我们想真正设计算法,就必须将这个概念转化为可以操作的数学语言。因此,第一步是明确我们如何表示数据。通常来说,计算机需要用数值形式来表示数据,这意味着图像、视频或蛋白质等对象最终都可以表示为向量:

图像可以表示为一个具有高度和宽度的数组。对于 RGB 图像,每个像素包含三个颜色通道,因此整张图像通常可以表示为一个形状为 H × W × 3 H \times W \times 3 H×W×3 的矩阵。如果我们将这个矩阵展平,就可以得到一个向量。

视频可以看作一系列图像,也就是由 T T T 帧图像组成,其中 T T T 表示帧数。因此,视频同样可以在计算机中表示为一个高维数组,并进一步展平为向量。

类似地,蛋白质等分子结构也可以表示为矩阵。例如,每一行可以对应一个氨基酸或一个原子,而其中的坐标则表示该原子在三维空间中的位置。将这些信息展平之后,也可以得到一个向量。

因此,在本课程中,我们会将数据统一视为向量。所谓生成某个对象,本质上就是生成一个向量。这正是流模型和扩散模型所要解决的核心问题。

那么,成功生成内容究竟意味着什么?

假设我们有这样一条提示词:

A picture of a dog

也就是说,我们希望模型生成一张狗的图像。下面展示了模型可能生成的四张图片:

最左边这张图几乎只是噪声,因此显然不是一个有用的结果。第二张图虽然看起来像一张图像,但它并不是狗。第三张图虽然是某种动物,但类别仍然不对。相比之下,最后一张图才符合我们对 "狗的图片" 的期望。

刚才这些判断其实都是主观的。我们可以说某张图更好,某张图更差,但数学并不直接使用这种主观语言。因此,我们需要将 "生成得好不好" 这个问题形式化。

一种自然的方式是引入数据分布。我们可以假设存在一个分布,例如互联网上所有图像构成的数据分布。对于给定提示词 "A picture of a dog",我们可以问:一张图像在这个条件下出现的可能性有多大?

例如,第一张几乎全是噪声的图像,在真实数据分布中几乎不可能出现;第二张图虽然像图像,但不太符合 "狗" 的提示;第三张图可能是一只动物,因此相对更接近目标;而第四张图非常符合 "狗的图片" 这一提示,因此在对应的数据分布下应该具有较高的可能性。

因此,我们可以将原本主观的判断转化为概率论语言:一张生成图像的质量,可以近似理解为它在目标数据分布下的可能性大小。

为了更具体地表示这个分布,我们通常使用概率密度函数:

p data : R d → R ≥ 0 p_{\text{data}} : \mathbb{R}^d \rightarrow \mathbb{R}_{\geq 0} pdata:Rd→R≥0

它是一个从 d d d 维向量空间到非负实数的函数。对于给定向量,概率密度函数会给出该向量在数据分布下的相对可能性。

换句话说, p data p_{\text{data}} pdata 告诉我们某个特定向量在数据分布下有多 "可能"。如果概率密度为零,那么这个向量几乎不可能从该分布中被采样到;如果概率密度较高,则说明它更可能是该分布中的典型样本。

从该分布中采样可以记为:

z ∼ p data z \sim p_{\text{data}} z∼pdata

这意味着我们希望得到一个来自数据分布的样本。如果我们的模型能够很好地表示数据分布,那么大多数时候,它生成的样本都应该位于数据分布中概率密度较高的区域,也就是看起来合理、自然且符合数据规律的样本。

接下来,我们需要区分数据分布和数据集。

我们设定了一个理想的数据分布 p data p_{\text{data}} pdata ,但在实际训练中,我们并不能直接访问这个完整分布。我们能够获得的只是一个有限的数据集。数据集可以看作从该数据分布中采样得到的有限样本集合。

例如,对于图像生成任务,我们可以想象互联网上所有公开可用的图像共同构成了某个巨大的数据分布。而训练数据集只是从这个分布中抽取出的一部分样本。因此,当我们说训练时从数据分布中采样,实际操作上通常就是从数据集中取出一个数据点。

到目前为止,我们讨论的是从一个固定的数据分布中采样。但在实际应用中,我们通常不仅仅想生成任意图像,而是希望生成具有特定属性的图像。例如,我们可能希望根据不同提示生成狗、猫或风景图像。这就引出了条件生成的问题。

对于条件生成,我们希望给定一个条件变量 y y y ,例如一段文本提示,然后从对应的条件分布中采样:

z ∼ p data ( ⋅ ∣ y ) z \sim p_{\text{data}}(\cdot \mid y) z∼pdata(⋅∣y)

这里的 y y y 可以表示提示词,例如 "狗"、"猫" 或 "风景"。不同的条件变量对应不同的条件分布,而模型需要根据给定条件生成符合要求的样本。

需要注意的是,条件生成虽然是最终目标,但本课程会先从更基础的无条件生成开始讲起。也就是说,我们首先假设存在一个固定的数据分布,并研究如何从这个分布中采样。等理解了无条件生成的基本原理之后,再进一步讨论如何引入条件变量,实现基于 prompt 的条件生成。


Q & A

Q:你如何定义生成的创新性?

A:这里的问题是:我们该如何判断模型生成结果的创新性?

从一个简单的角度来看,创新性可以理解为:模型生成的数据点是否已经存在于训练数据集中。如果我们接受这种定义,那么可以通过检查生成结果是否出现在数据集中来判断它是否具有新颖性。例如,我们生成一张图像,然后检查它是否已经存在于互联网或训练数据中。如果不存在,那么可以认为模型确实生成了一个新的样本。

不过,这只是创新性的一个简单定义。实际评估生成模型时,我们通常还关心生成样本是否有意义、是否具有较高质量,以及是否符合目标分布。因此,对于生成模型的评估,通常会使用多种指标。后面在讨论图像生成时,也许还会进一步介绍这些评估方法。

这个问题的本质是:我们的目标是从目标数据分布中生成样本,但如何判断模型是否真正实现了这一目标,本身就是一个重要问题。


到目前为止,我们已经讨论了生成任务的目标:我们希望从某个数据分布中采样。接下来,我们希望构建能够实现这一目标的生成模型。

所谓生成模型,就是用来生成某个特定分布样本的机器学习模型。通常来说,它的基本过程如下:

我们首先需要一个初始分布 p init p_{\text{init}} pinit 。这个分布通常是已知且容易采样的。那么,最常见、最基本的初始分布是什么呢?答案是高斯分布:

p init = N ( 0 , I d ) p_{\text{init}} = \mathcal{N}(0, I_d) pinit=N(0,Id)

这里的 N ( 0 , I d ) \mathcal{N}(0, I_d) N(0,Id) 表示标准多元高斯分布,其中均值为零,协方差矩阵为单位矩阵。在大多数生成模型中,这几乎都是最常见的初始分布选择。

这意味着,我们首先从这个简单的初始分布中采样。对于图像任务来说,从标准高斯分布中采样得到的结果通常看起来像噪声。然后,我们将这个噪声样本输入生成模型,希望模型能够将它转换成目标数据分布中的样本。

换句话说,生成模型的目标可以理解为:从一个简单、已知、容易采样的分布出发,通过某种模型或过程,将样本变换为目标数据分布中的样本。

理想情况下,如果模型训练得足够好,那么对于 "狗的图片" 这个例子,模型最终应该能够生成一张合理的狗的图像。


Q & A

Q:是否存在不遵循这种方式的生成模型?

A:确实存在不同形式的生成模型。大多数生成模型在生成时都需要某种随机种子,因为任何计算机程序如果要产生随机性,通常都需要引入某种噪声或随机变量。但这并不意味着所有生成模型都严格遵循 "输入噪声到一个神经网络,然后直接输出结果" 的形式。

因此,这里的生成模型应该被理解为一个更一般的黑箱过程。它不一定只是一个单独的神经网络,也可以是一种过程式定义。重要的是,它能够从某个容易采样的随机来源出发,最终产生目标分布中的样本。


4. Flow and Diffusion Models

前面讨论的是生成模型的目标。现在我们正式进入课程的核心内容:流模型和扩散模型

流模型和扩散模型都是实现生成目标的方法。也就是说,它们提供了一种具体机制,用来将简单初始分布中的样本转换为复杂数据分布中的样本。

我们先从流模型开始。

4.1 Flow Models

流模型依赖于 常微分方程(ordinary differential equations, ODEs)。常微分方程在物理或工程课程中经常出现,通常用于描述一个系统如何随时间变化。这里,我们将这种描述动态系统的数学工具用于机器学习和生成建模。

在正式定义 ODE 之前,我们需要先引入两个对象:轨迹(trajectory)向量场(vector field)

首先,什么是轨迹?

轨迹可以理解为一个关于时间的函数。我们将其写作:

X : 0 , 1 → R d , t ↦ X t X : 0,1 \rightarrow \mathbb{R}^d,\quad t \mapsto X_t X:0,1→Rd,t↦Xt

这个函数的定义域是时间区间 0 , 1 0,1 0,1 ,值域是 d d d 维向量空间 R d \mathbb{R}^d Rd 。也就是说,对于每一个时间 t t t ,轨迹都会给出一个向量 X t X_t Xt 。

如果我们考虑二维空间中的例子,那么轨迹就可以理解为一个点从某个初始位置出发,随着时间不断移动所形成的路径。

接下来,我们需要定义 向量场(vector field)

u : R d × 0 , 1 → R d , ( x , t ) ↦ u t ( x ) u : \mathbb{R}^d \times 0,1 \rightarrow \mathbb{R}^d,\quad (x,t)\mapsto u_t(x) u:Rd×0,1→Rd,(x,t)↦ut(x)

向量场是一个函数,它接收当前位置 x x x 和时间 t t t ,并输出一个向量 u t ( x ) u_t(x) ut(x) 。这个输出向量可以理解为当前位置和当前时间下的运动方向与速度。

换句话说,向量场为每一个位置和时间指定了一个速度向量。因此,在直观上,我们可以把向量场理解为:空间中每一个点都附带一个箭头,而这个箭头告诉我们,如果粒子位于该点,它接下来应该朝哪个方向移动。

现实生活中有很多向量场的例子。比如,二维空间中的引力场或力场可以看作向量场;天气图中的风向和风速也可以看作向量场,因为地球上每个位置都对应一个风速向量。

现在,我们可以正式定义常微分方程,也就是 ODE。一个 ODE 由两个部分组成:

d d t X t = u t ( X t ) ▶ ODE X 0 = x 0 ▶ initial conditions \begin{align*} \frac{d}{dt}X_t &= u_t(X_t) &\qquad\qquad\qquad& \blacktriangleright\ \text{ODE} \\ X_0 &= x_0 &\qquad\qquad\qquad& \blacktriangleright\ \text{initial conditions} \end{align*} dtdXtX0=ut(Xt)=x0▶ ODE▶ initial conditions

其中,第二行给出了初始条件。它规定了轨迹从哪里开始,也就是在时间 t = 0 t=0 t=0 时,轨迹的位置为 x 0 x_0 x0 。

第一行则描述了轨迹如何随时间演化。它说明 X t X_t Xt 关于时间的导数由向量场 u t ( X t ) u_t(X_t) ut(Xt) 给出。也就是说,在每一个时间点,轨迹的速度都由当前位置处的向量场决定。

直观地说,如果我们从某个初始点 x 0 x_0 x0 出发,那么向量场会告诉我们在每个位置应该朝哪个方向、以多快的速度移动。沿着这些方向不断演化,就会得到一条轨迹。这条满足 ODE 条件的路径,就是该初始条件下的解。

一个非正式的例子是:如果风场给出了每个位置的风向和风速,那么一片羽毛随风飘动的路径,就可以看作由这个向量场诱导出的 ODE 轨迹。当然,这只是一个帮助理解的直观类比。

下面是一个可视化例子:

图中的箭头表示背景向量场。也就是说,在每一个位置上,都有一个箭头指示该位置的运动方向。随着时间变化,向量场本身也可以发生变化,比如风场会随时间改变。

如果我们从绿色点作为初始位置出发,那么该点会沿着向量场指定的方向不断移动,形成一条随时间演化的轨迹。这就是 ODE 的基本直观含义。


Q & A

Q:初始条件是否也包含粒子的速度?

A :这个问题可以理解为:当我们给定初始条件 X 0 = x 0 X_0=x_0 X0=x0 时,是否还需要额外给出初始速度?

在这里不需要额外指定速度。原因是速度已经由 ODE 的右侧向量场决定了。由于

d d t X t = u t ( X t ) \frac{d}{dt}X_t = u_t(X_t) dtdXt=ut(Xt)

对任意时间 t t t 都成立,所以在 t = 0 t=0 t=0 时,初始速度自然就是

u 0 ( X 0 ) = u 0 ( x 0 ) u_0(X_0) = u_0(x_0) u0(X0)=u0(x0)

因此,只要给定初始位置 x 0 x_0 x0,向量场就已经决定了该点处的初始速度。

Q:粒子的下一个位置是否只依赖于当前状态?

A:是的。在这个设定下,未来状态只依赖于当前状态,而不依赖于更早的历史。因此,它具有类似马尔可夫性质的特点。

换句话说,如果我们知道当前时间、当前位置以及向量场,那么就可以决定当前的运动方向和速度。系统不需要额外记住之前是如何到达当前位置的。后面在讨论如何数值模拟 ODE 时,我们还会继续看到这一点。


在继续之前,我们还需要定义什么是 流(flow)。因为这类模型被称为流模型,所以理解 "流" 的含义非常重要。

简单来说,一个向量场会诱导出一族 ODE 轨迹;而所谓流,就是把所有可能初始条件下的 ODE 解组织在一起得到的映射。

更形式化地说,流可以写作:

ψ : R d × 0 , 1 → R d , ( x 0 , t ) ↦ ψ t ( x 0 ) d d t ψ t ( x 0 ) = u t ( ψ t ( x 0 ) ) ▶ flow ODE ψ 0 ( x 0 ) = x 0 ▶ flow initial conditions \begin{align*} \psi : \mathbb{R}^d \times 0,1 &\rightarrow \mathbb{R}^d, \quad (x_0,t)\mapsto \psi_t(x_0)&& \\6pt \frac{d}{dt}\psi_t(x_0)&= u_t(\psi_t(x_0)) &\qquad& \blacktriangleright\ \text{flow ODE} \\ \psi_0(x_0)&= x_0 &\qquad& \blacktriangleright\ \text{flow initial conditions} \end{align*} ψ:Rd×0,1dtdψt(x0)ψ0(x0)→Rd,(x0,t)↦ψt(x0)=ut(ψt(x0))=x0▶ flow ODE▶ flow initial conditions

这里, ψ \psi ψ 表示流。它接收一个初始位置 x 0 x_0 x0 和一个时间 t t t ,并返回从 x 0 x_0 x0 出发、经过时间 t t t 后到达的位置 ψ t ( x 0 ) \psi_t(x_0) ψt(x0) 。

因此,对于固定的初始点 x 0 x_0 x0 ,函数 t ↦ ψ t ( x 0 ) t \mapsto \psi_t(x_0) t↦ψt(x0) 就是一条轨迹;而对于所有可能的初始点 x 0 x_0 x0 , ψ t \psi_t ψt 则描述了整个空间在时间 t t t 下如何被变换。

在时间 t = 0 t=0 t=0 时,流满足:

ψ 0 ( x 0 ) = x 0 \psi_0(x_0)=x_0 ψ0(x0)=x0

这说明在初始时刻,所有点都还没有发生移动,因此流就是恒等映射。

随着时间变化,流的演化由向量场决定:

d d t ψ t ( x 0 ) = u t ( ψ t ( x 0 ) ) \frac{d}{dt}\psi_t(x_0)=u_t(\psi_t(x_0)) dtdψt(x0)=ut(ψt(x0))

也就是说,每个点沿着向量场指定的速度方向移动。最终,流描述的就是:从任意初始位置出发,在向量场的作用下经过一段时间后会到达哪里。

因此,我们可以把流理解为 ODE 所产生的整体运动过程。它不仅描述某一条轨迹,而是描述所有初始点在同一个向量场下的整体演化。

到目前为止,一切都比较顺利。下面我们通过一个可视化例子来理解流:

图中蓝色箭头表示向量场。也就是说,在每一个位置上,都有一个箭头指示该点的运动方向和速度。红点则表示一组初始点,它们最开始被均匀地放置在网格上。随着时间推移,这些红点会在向量场的驱动下不断移动和演化。

因此,这里的 "流" 可以理解为许多不同初始条件下轨迹的整体演化。它不仅描述单个点如何移动,而是描述整个空间中的点如何同时被移动和变形。

从这个角度来看,ODE 的演化过程实际上会 "扭曲" 空间。一个流会以某种方式改变空间中点的位置关系。更严格地说,在合适条件下,流对应的是一个 微分同胚(diffeomorphism),也就是一种可微且可逆的空间变换。

接下来有一个自然的问题:任意 ODE 是否都有唯一解?

在物理学中,我们常常把 ODE 写成自然规律,并默认给定初始条件后,系统只有一种可能的演化方式。但从数学上讲,这并不总是自动成立。我们需要问两个问题:

  1. 给定一个 ODE,它是否一定存在解?
  2. 如果存在解,这个解是否唯一?

下面来看一个简单例子。

假设我们只考虑一维空间,即 d = 1 d=1 d=1 ,并令向量场为:

u t ( x ) = 2 x u_t(x)=2\sqrt{x} ut(x)=2x

同时给定初始条件:

x 0 = 0 x_0=0 x0=0

现在我们想求解这个 ODE。首先,有一个非常平凡的解:

X t = 0 X_t=0 Xt=0

因为它始终停留在零点,导数也是零。

但同时,另一个函数也满足这个 ODE:

X t = t 2 X_t=t^2 Xt=t2

因为:

d d t t 2 = 2 t \frac{d}{dt}t^2=2t dtdt2=2t

而当 X t = t 2 X_t=t^2 Xt=t2 时,

2 X t = 2 t 2 = 2 t 2\sqrt{X_t}=2\sqrt{t^2}=2t 2Xt =2t2 =2t

在 t ≥ 0 t\geq 0 t≥0 的情况下二者相等。因此, X t = 0 X_t=0 Xt=0 和 X t = t 2 X_t=t^2 Xt=t2 都是满足相同初始条件的解。

这个例子说明,一般情况下,ODE 的解不一定唯一。当然,这个例子对后面的生成模型并不是最核心的内容,如果暂时没有完全理解,也可以先忽略。我们真正需要记住的是:为了避免这种不唯一的情况,我们通常会对向量场施加一些正则性条件。

具体来说,我们通常会假设向量场是连续可微的,并且导数有界。在这样的条件下,ODE 的解存在且唯一。也就是说,对于每一个初始条件,都存在一条唯一的轨迹与之对应,从而可以定义出对应的流。

在机器学习中,由神经网络参数化的向量场通常可以满足我们所需的这些条件,或者至少在实践中我们可以安全地按照这个假设来处理。因此,这一页幻灯片的核心信息就是:在本课程关注的实际场景中,我们可以默认 ODE 的解存在且唯一,流也可以被正常定义。

因此,对于我们实际感兴趣的情况,只要写下如下 ODE:

X 0 = x 0 , d d t X t = u t ( X t ) X_0 = x_0, \quad \frac{d}{dt}X_t = u_t(X_t) X0=x0,dtdXt=ut(Xt)

它就唯一确定了一条轨迹。我们可以直接假设轨迹存在、ODE 解存在,对应的流也存在。


Q & A

Q:为什么在生成模型中需要 ODE 的解唯一?

A:这里的唯一性更多是为了让流成为一个清晰、可用的数学工具。

后面我们会使用流来描述一个点从初始位置经过 ODE 演化后最终到达哪里。如果同一个初始条件可能对应多个解,甚至无穷多个解,那么 "这个点最终会到哪里" 就不再明确,整个生成过程也会变得难以定义。

因此,对生成模型来说,ODE 解的唯一性能够保证从初始样本到最终样本的映射是明确的。这样我们才能把流作为一个稳定的生成机制来使用。


接下来我们看一个具体的 ODE 例子:

这是一个线性 ODE。假设向量场为:

u t ( x ) = − θ x , θ > 0 u_t(x)=-\theta x,\quad \theta>0 ut(x)=−θx,θ>0

这个向量场的含义是:如果 x x x 为正,它会被向零点方向拉回;如果 x x x 为负,它也会被向零点方向拉回。因此,这个系统会将所有点逐渐推向原点。

对于这个 ODE,其对应的流可以写成:

ψ t ( x 0 ) = exp ⁡ ( − θ t ) x 0 \psi_t(x_0)=\exp(-\theta t)x_0 ψt(x0)=exp(−θt)x0

我们可以通过求导来验证它确实满足 ODE。

首先,初始条件成立:

ψ 0 ( x 0 ) = exp ⁡ ( 0 ) x 0 = x 0 \psi_0(x_0)=\exp(0)x_0=x_0 ψ0(x0)=exp(0)x0=x0

然后,对 ψ t ( x 0 ) \psi_t(x_0) ψt(x0) 关于时间 t t t 求导:

d d t ψ t ( x 0 ) = d d t ( exp ⁡ ( − θ t ) x 0 ) = ( i ) − θ exp ⁡ ( − θ t ) x 0 = − θ ψ t ( x 0 ) = u t ( ψ t ( x 0 ) ) \frac{d}{dt}\psi_t(x_0) = \frac{d}{dt}\left(\exp(-\theta t)x_0\right) \overset{(i)}= -\theta \exp(-\theta t)x_0 = -\theta\psi_t(x_0) =u_t(\psi_t(x_0)) dtdψt(x0)=dtd(exp(−θt)x0)=(i)−θexp(−θt)x0=−θψt(x0)=ut(ψt(x0))

其中,在步骤 ( i ) (i) (i) 中使用了链式法则(chain rule)。

这说明公式:

ψ t ( x 0 ) = exp ⁡ ( − θ t ) x 0 \psi_t(x_0)=\exp(-\theta t)x_0 ψt(x0)=exp(−θt)x0

确实是该 ODE 的流。


Q & A

Q:我们能否将流解释为 ODE 的解?

A:可以,但需要稍微更准确地说:流是 ODE 在所有初始条件下的解的集合。

对于某一个固定初始条件 x 0 x_0 x0 ,函数 t ↦ ψ t ( x 0 ) t\mapsto \psi_t(x_0) t↦ψt(x0) 是一条具体轨迹,也就是该初始条件下 ODE 的解。而流 ψ \psi ψ 则更进一步:它接收任意初始条件和任意时间,并告诉我们从这个初始点出发,经过指定时间后会到达哪里。

因此,流不仅仅是一条轨迹,而是一个映射。它将初始位置映射到对应时间下的终点位置。


在上面的线性例子中,ODE 的解可以用解析公式写出来。但这基本上是本课程中少数能够直接写出解析解的情况。

在实际感兴趣的生成模型中,向量场通常由复杂神经网络给出,因此我们几乎不可能写出解析解。此时,我们必须通过数值方法来模拟 ODE。

所谓模拟 ODE,就是:给定一个向量场和一个初始条件,近似计算这条轨迹随时间的演化过程。

下面是最基础的数值模拟方法:

我们给定一个向量场 u t u_t ut 、一个初始条件 x 0 x_0 x0 ,以及模拟步数 n n n 。首先将时间设为 t = 0 t=0 t=0 ,步长设为:

h = 1 n h=\frac{1}{n} h=n1

然后将初始状态设为:

X 0 = x 0 X_0=x_0 X0=x0

接下来进行迭代。在每一步中,我们沿着当前向量场给出的方向前进一步。具体来说:

X t + h = X t + h u t ( X t ) , ( t = 0 , h , 2 h , ... , 1 − h ) X_{t+h}=X_t+h u_t(X_t), \qquad (t=0,h,2h,\ldots,1-h) Xt+h=Xt+hut(Xt),(t=0,h,2h,...,1−h)

这就是最简单的欧拉法(Euler method)。

它的直观含义是:在当前时刻 t t t 和当前位置 X t X_t Xt ,向量场 u t ( X t ) u_t(X_t) ut(Xt) 告诉我们当前应该沿哪个方向移动。然后我们沿着这个方向前进一小步,步长由 h h h 控制。不断重复这个过程,就可以近似得到 ODE 的轨迹。

下面是对前面展示的向量场进行数值模拟后的结果:

对于机器学习应用来说,步长的选择非常重要。步长越小,模拟结果通常越准确,但需要进行更多次神经网络计算,因此计算成本更高。步长越大,模拟速度更快,但误差也会更大。

因此,在实际生成模型中,我们总是需要在 采样质量计算效率 之间进行权衡。更小的步长可以带来更准确的 ODE 解,但也意味着更长的采样时间和更高的计算成本。

到目前为止,我们讨论的主要还是数学工具,还没有真正进入机器学习部分。下面我们回到最初的问题:如何构建生成模型?

现在我们可以正式定义什么是流模型。

回顾一下,我们的目标是:从一个简单的初始分布出发,将其转换为复杂的数据分布。也就是说,我们希望实现:

p init → p data p_{\text{init}} \rightarrow p_{\text{data}} pinit→pdata

这正是生成模型的核心目标。而流模型的思路是:使用 ODE 来实现这个分布之间的转换。

具体来说,我们使用一个神经网络来表示向量场:

u t θ : R d × 0 , 1 → R d u_t^\theta : \mathbb{R}^d\times0,1 \rightarrow \mathbb{R}^d utθ:Rd×0,1→Rd

这里的 u t θ u_t^\theta utθ 是一个带参数 θ \theta θ 的向量场。与前面普通向量场不同的是,现在向量场由神经网络参数化。对于不同的参数 θ \theta θ ,我们会得到不同的向量场。

从理论上讲,在本课程的大部分内容中,我们并不需要过多关心具体的神经网络架构。此时,神经网络可以简单理解为一个参数化函数,它接收当前位置 x x x 和时间 t t t ,然后输出当前位置处的速度向量。

当然,在实际应用中,网络架构非常重要。不同数据类型通常需要不同的架构设计。例如,图像、视频和蛋白质结构使用的神经网络架构可能完全不同。后面的课程会进一步讨论这些实际设计问题。但在当前阶段,我们只需要把神经网络理解为一个参数化向量场即可。

到目前为止,ODE 本身是确定性的。也就是说,如果初始条件固定,那么轨迹也是固定的,没有额外随机性。因此,如果我们想从分布中采样,随机性必须来自初始条件。

所以,在流模型中,我们令初始状态服从一个简单分布:

X 0 ∼ p init X_0\sim p_{\text{init}} X0∼pinit

在大多数情况下, p init p_{\text{init}} pinit 是标准高斯分布。也就是说,我们不是从某个固定点出发,而是从高斯分布中随机采样一个初始点。

随后,我们使用神经网络定义的向量场来演化这个样本:

d d t X t = u t θ ( X t ) \frac{d}{dt}X_t = u_t^\theta(X_t) dtdXt=utθ(Xt)

这里的目标是学习一个合适的神经网络参数 θ \theta θ ,使得经过 ODE 演化之后,终点 X 1 X_1 X1 服从数据分布:

X 1 ∼ p data X_1 \sim p_{\text{data}} X1∼pdata

这就是流模型的基本定义。

换句话说,流模型首先从一个简单、已知、容易采样的分布中生成初始点,然后通过神经网络参数化的 ODE 将其连续地变换到数据分布。只要向量场学习得足够好,最终得到的终点样本就应该来自目标数据分布。

从这个角度来看,流模型实际上是在学习一个从简单分布到复杂数据分布的连续变换过程。

下面通过一个二维 toy example 来可视化这个过程:

这里我们不考虑高维图像,而是考虑二维平面上的简单分布。初始分布是一个二维高斯分布。在高维图像空间中,从高斯分布采样出来的样本看起来通常像随机噪声;而在二维平面中,我们可以直接画出它的密度。

数据分布则是人为构造出来的二维示例。它本身没有实际应用意义,只是为了帮助我们理解流模型的工作方式。

接下来,我们训练一个流模型。虽然此时还没有讲如何训练它,但我们已经知道如何在给定向量场的情况下模拟 ODE。

随着时间推移,初始高斯分布中的样本会在神经网络向量场的作用下不断移动。整个分布被流逐渐 "扭曲",最终变成我们希望采样的目标数据分布。

这就是流模型的核心直觉:通过一个由神经网络定义的连续动力系统,将简单噪声分布逐渐变换为复杂数据分布。


Q & A

Q : θ \theta θ 是固定的吗?

A :在训练完成之后, θ \theta θ 是固定的。

训练过程中,我们会不断调整参数 θ \theta θ ,使得神经网络向量场能够把初始分布变换为数据分布。但一旦训练结束,模型参数就固定下来。在生成或部署阶段,我们不再更新 θ \theta θ ,而是使用固定的神经网络向量场来模拟 ODE。

因此,此时的采样过程就是:从初始分布中采样一个点,然后在固定的向量场下模拟 ODE,最终得到生成样本。

Q : θ \theta θ 是可学习参数吗?

A :是的, θ \theta θ 是神经网络的可学习参数。

更具体地说,流模型中的向量场由神经网络表示。我们训练这个神经网络,使它在不同时间和不同位置输出合适的速度方向。生成时,我们给定一个从高斯分布采样得到的初始点 X 0 X_0 X0 ,然后在每一步中,将当前时间 t t t 和当前位置 X t X_t Xt 输入神经网络,由神经网络告诉我们应该朝哪个方向移动。

按照这个方向不断前进,最终得到的终点 X 1 X_1 X1 就是模型生成的样本。


举个实际例子:

上面这些视频实际上是由流模型生成的。该模型使用的采样过程,本质上就是前面介绍的 ODE 模拟算法。

因此,一旦模型已经训练完成,采样本身其实并不复杂。我们只需要从初始噪声分布中采样,然后用训练好的向量场模拟 ODE,就可以得到生成结果。

换句话说,到目前为止,我们已经知道了如何使用一个训练好的流模型来生成样本。真正更困难的问题在于:如何训练这个神经网络向量场,使得它能够把初始分布正确地变换为数据分布。这将是后续课程要重点解决的问题。


Q & A

Q:在流模型中,神经网络给出的是向量场吗?

A:是的。神经网络给出的就是向量场。

更准确地说,对于一组固定参数 θ \theta θ ,神经网络 u t θ u_t^\theta utθ 定义了一个具体的向量场。由于参数 θ \theta θ 可以取不同的值,因此神经网络参数空间中实际上对应着许多可能的向量场。训练的目标就是在这些可能的向量场中,找到一个合适的向量场,使它能够把初始分布变换为目标数据分布。


4.2 Diffusion Models

到目前为止,我们主要讨论的是流模型。接下来,我们要把这些思想从流模型扩展到扩散模型。二者的核心区别在于:流模型使用的是常微分方程(ODE),而扩散模型使用的是 随机微分方程(SDE)

需要先说明的是,随机微分方程在数学上比常微分方程更复杂,也更加形式化。不过,它的核心直觉仍然与前面讲过的 "流" 密切相关。也就是说,我们仍然关心一个样本如何随时间演化,只不过这一次演化过程不再是完全确定的,而是带有随机性。

从实用角度来看,如果暂时觉得扩散模型中的随机过程和 SDE 比较难理解,也可以先把重点放在流模型部分。流模型已经能够覆盖很多重要思想,而且相对更容易理解。扩散模型可以看作是在这个基础上进一步引入随机噪声后的推广。

下面正式开始讨论扩散模型。

首先,我们需要找到 ODE 中 "轨迹" 的对应物。

在流模型中,轨迹是一个确定性的时间函数:

X : 0 , 1 → R d X : 0,1\rightarrow \mathbb{R}^d X:0,1→Rd

给定初始点和向量场之后,每个时间 t t t 对应的位置 X t X_t Xt 都是确定的。

但在扩散模型中,我们使用的是随机微分方程。因此,轨迹本身也变成了随机的。更准确地说,我们现在考虑的是一个随机过程:

( X t ) 0 ≤ t ≤ 1 (X_t)_{0\leq t\leq 1} (Xt)0≤t≤1

这里的 X t X_t Xt 不再只是一个普通向量,而是一个随机变量,或者更准确地说,是一个随机向量。

可以这样理解:随机过程是一条 "随机轨迹"。如果我们从这个随机过程中采样一次,就会得到一条具体的轨迹:

X : 0 , 1 → R d X : 0,1\rightarrow \mathbb{R}^d X:0,1→Rd

但如果重新采样一次,则可能得到另一条不同的轨迹。也就是说,随机过程不是只对应一条固定路径,而是对应许多可能的路径。

下面是一个随机过程的可视化例子:

在这个例子中,即使我们从同一个起点出发,多次采样也不会得到完全相同的轨迹。每一次采样都会产生一条不同的路径。因此,随机过程描述的是一族可能轨迹的分布,而不是单一确定轨迹。

这是理解扩散模型时非常重要的一点:随机过程可以产生许多不同轨迹,每条轨迹都是一次随机采样的结果。

接下来,我们仍然需要向量场:

u t ( x ) u_t(x) ut(x)

这个对象和流模型中是一样的。它表示在时间 t t t 、位置 x x x 处的确定性运动方向和速度。

不过,在 SDE 中,我们还需要一个新的对象,这也是随机微分方程区别于常微分方程的关键:扩散系数(diffusion coefficient)

扩散系数通常写作:

σ t : 0 , 1 → R ≥ 0 \sigma_t : 0,1\rightarrow \mathbb{R}_{\geq 0} σt:0,1→R≥0

它是一个依赖于时间的非负函数。也就是说,对于每一个时间 t t t , σ t \sigma_t σt 都会给出一个非负数。

直观上, σ t \sigma_t σt 表示在时间 t t t 时,系统中应该加入多少随机噪声。它控制了随机性的强弱:

  • 如果 σ t \sigma_t σt 很大,说明这一时刻加入的噪声较强;
  • 如果 σ t \sigma_t σt 很小,说明这一时刻加入的噪声较弱;
  • 如果 σ t = 0 \sigma_t=0 σt=0,那么这一时刻就没有随机噪声,系统退化为确定性演化。

下面我们正式写出 SDE。

在此之前,先稍微改变一下 ODE 的记法。前面我们把 ODE 写作:

d d t X t = u t θ ( X t ) \frac{d}{dt}X_t = u_t^\theta(X_t) dtdXt=utθ(Xt)

现在我们将它改写为:

d X t = u t θ ( X t ) d t dX_t = u_t^\theta(X_t)dt dXt=utθ(Xt)dt

这只是记号上的变化,数学含义没有改变。它表达的仍然是: X t X_t Xt 随时间的变化由向量场 u t θ ( X t ) u_t^\theta(X_t) utθ(Xt) 决定。

之所以采用这种写法,是因为 SDE 通常用这种微分形式表示。

随机微分方程可以写作:

d X t = u t ( X t ) d t + σ t d W t dX_t = u_t(X_t)dt + \sigma_t dW_t dXt=ut(Xt)dt+σtdWt

它包含两部分:

第一部分是 u t ( X t ) d t u_t(X_t)dt ut(Xt)dt 。这是确定性的 ODE 部分,描述了样本在向量场作用下的确定性运动。

第二部分是 σ t d W t \sigma_t dW_t σtdWt 。这是随机项,用来描述演化过程中的噪声。这里的 σ t \sigma_t σt 控制噪声强度,而 W t W_t Wt 是 布朗运动(Brownian motion)

因此,SDE 可以理解为:

确定性的 ODE 演化 + 随机噪声扰动。

如果扩散系数 σ t = 0 \sigma_t=0 σt=0 ,那么随机项消失,SDE 就退化为普通的 ODE。

接下来,我们需要理解什么是布朗运动。

布朗运动通常记作:

( W t ) t ≥ 0 (W_t)_{t\geq 0} (Wt)t≥0

它是一个定义在 R d \mathbb{R}^d Rd 中的随机过程。直观上,布朗运动可以看作连续时间、连续空间中的随机游走。

普通随机游走可以理解为:每一步以一定概率向前或向后移动。而布朗运动则是这种随机游走在连续极限下的形式。它不是一步一步跳动的离散过程,而是一条连续但随机的路径。

更形式化地说,布朗运动满足以下几个条件。

第一个条件是初始值为零:

W 0 = 0 W_0=0 W0=0

这只是一个约定,表示布朗运动从原点开始。

第二个条件是 高斯增量(Gaussian increments)

对于两个时间点 s < t s<t s<t ,布朗运动的增量满足:

W t − W s ∼ N ( 0 , ( t − s ) I d ) W_t-W_s \sim \mathcal{N}(0,(t-s)I_d) Wt−Ws∼N(0,(t−s)Id)

这意味着,从时间 s s s 到时间 t t t 的变化量是一个高斯随机变量,其均值为零,协方差为 ( t − s ) I d (t-s)I_d (t−s)Id 。

这里的关键是:方差随时间间隔线性增长。如果 t = s t=s t=s ,那么时间间隔为零,方差也为零,因此没有变化;如果时间间隔越长,那么方差越大,说明可能偏离得越远。这和我们对随机运动的直觉是一致的:时间越久,随机过程走得越远的可能性越大。

第三个条件是 独立增量(independent increments)

对于任意时间划分:

0 ≤ t 0 < t 1 < ⋯ < t n = 1 0 \leq t_0 < t_1 < \cdots < t_n = 1 0≤t0<t1<⋯<tn=1

这些增量:

W t 1 − W t 0 , ... , W t n − W t n − 1 W_{t_1}-W_{t_0},\dots,W_{t_n}-W_{t_{n-1}} Wt1−Wt0,...,Wtn−Wtn−1

彼此相互独立。

这意味着,早期时间段内的随机变化不会决定后续时间段内的随机变化。换句话说,如果我们想采样未来的增量,就不需要知道之前的增量具体是多少。

这里的 "独立" 指的是概率意义上的独立。如果对概率论还不熟悉,可以暂时把它理解为:每一段时间里的随机扰动都是重新采样的,不会被前一段随机扰动直接决定。


Q & A

Q:你怎么知道布朗运动一定存在?

A:这是一个很好的问题。布朗运动的严格构造需要在随机过程或随机微积分课程中完成,它并不是一个显然存在的对象。

上面这些条件其实非常特殊,并不是随便写出来的。例如,如果我们把高斯增量中的协方差从:

( t − s ) I d (t-s)I_d (t−s)Id

改成:

( t − s ) 2 I d (t-s)^2I_d (t−s)2Id

那么对应的过程可能就不再满足我们想要的布朗运动性质,甚至无法构造出这样的过程。因此,布朗运动的定义条件是非常精确的。

在本课程中,我们不需要深入讨论它的严格构造,只需要理解布朗运动是一种连续时间随机过程,并且它的增量是独立的高斯随机变量。


那么,如何模拟布朗运动呢?

虽然布朗运动的严格定义比较形式化,但它的数值模拟非常直观。给定一个步长 h h h ,我们可以用下面的方式近似模拟:

W t + h = W t + h ϵ t , ϵ t ∼ N ( 0 , I d ) W_{t+h}=W_t+\sqrt{h}\epsilon_t,\qquad\epsilon_t\sim \mathcal{N}(0,I_d) Wt+h=Wt+h ϵt,ϵt∼N(0,Id)

也就是说,从当前状态 W t W_t Wt 出发,下一步的位置等于当前状态加上一个高斯噪声项。这个高斯噪声 ϵ t \epsilon_t ϵt 服从标准正态分布,然后再乘以 h \sqrt{h} h 进行缩放。

因此,模拟布朗运动本质上就是不断加入独立的高斯噪声。步长 h h h 控制每一步的时间间隔,而 h \sqrt{h} h 保证噪声增量具有正确的方差尺度。


Q & A

Q :为什么这里是乘以步长的平方根 h \sqrt{h} h ,而不是直接乘以步长 h h h ?

A:原因在于布朗运动要求方差随时间线性增长。

如果:

ϵ t ∼ N ( 0 , I d ) \epsilon_t\sim \mathcal{N}(0,I_d) ϵt∼N(0,Id)

那么:

h ϵ t ∼ N ( 0 , h I d ) \sqrt{h}\epsilon_t \sim \mathcal{N}(0,hI_d) h ϵt∼N(0,hId)

也就是说,乘以 h \sqrt{h} h 之后,增量的协方差正好变成 h I d hI_d hId ,这与布朗运动的定义:

W t + h − W t ∼ N ( 0 , h I d ) W_{t+h}-W_t\sim \mathcal{N}(0,hI_d) Wt+h−Wt∼N(0,hId)

完全一致。

如果我们直接乘以 h h h ,那么增量方差会变成 h 2 I d h^2I_d h2Id ,这就不符合布朗运动 "方差随时间线性增长" 的要求。

从另一个角度看,独立随机变量的方差具有可加性。也就是说,多个独立噪声增量累积时,它们的方差会相加,而不是标准差相加。因此,为了让总方差随着时间线性增长,每一步噪声的标准差必须与 h \sqrt{h} h 成正比,而不是与 h h h 成正比。


前面我们已经引入了布朗运动。下面通过一个可视化例子来看它的直观效果:

实际上,图中展示的随机过程就是布朗运动。它是一个完全随机的过程,在每个位置都没有确定的运动方向。它不会记住过去的路径,而是在每个小时间步中继续加入新的高斯噪声。

这里展示的是二维布朗运动,但同样的概念可以推广到任意维度。

从数学上看,布朗运动还有很多非常有趣的性质。例如,它的路径是连续的,也就是说,如果我们画出一条布朗运动轨迹,可以在不抬笔的情况下连续地画完这条路径。

但另一方面,布朗运动的路径又具有非常反直觉的性质:它几乎处处不可微。也就是说,虽然它是连续的,但它的路径非常粗糙,以至于我们不能像普通光滑曲线那样对它求导。

这对我们来说很重要。因为到目前为止,我们一直在讨论微分方程,而微分方程通常依赖于导数。但布朗运动本身不可微,因此如果我们想定义一种包含布朗运动的演化方程,就不能再简单地依赖普通导数。接下来我们需要用另一种方式来理解 SDE 中的符号。


Q & A

Q :我们如何设置 σ t \sigma_t σt ?

A :在当前阶段, σ t \sigma_t σt 是一个可以自由选择的设计对象。

也就是说,扩散系数并不是由理论唯一决定的,而是我们在构建模型时做出的设计选择。它控制随机噪声在不同时间的强弱。后续如果具体训练扩散模型或设计噪声调度,就会进一步讨论如何选择它。


前面我们定义了布朗运动,现在可以解释 SDE 中的符号到底是什么意思。

回顾一下,ODE 可以写作:

d X t = u t ( X t ) d t dX_t=u_t(X_t)dt dXt=ut(Xt)dt

这只是前面形式:

d d t X t = u t ( X t ) \frac{d}{dt}X_t=u_t(X_t) dtdXt=ut(Xt)

的另一种写法。它表示 X t X_t Xt 的变化由向量场 u t ( X t ) u_t(X_t) ut(Xt) 决定。

如果我们从一个很小的步长 h h h 来看,这个 ODE 等价于:

X t + h = X t + h u t ( X t ) + R t ( h ) X_{t+h}=X_t+h u_t(X_t)+R_t(h) Xt+h=Xt+hut(Xt)+Rt(h)

其中, R t ( h ) R_t(h) Rt(h) 是误差项,并且满足:

lim ⁡ h → 0 R t ( h ) h = 0 \lim_{h\to 0}\frac{R_t(h)}{h}=0 h→0limhRt(h)=0

这表示误差项比 h h h 更快趋近于零。换句话说,当步长 h h h 很小时, X t X_t Xt 的变化主要由 h u t ( X t ) h u_t(X_t) hut(Xt) 决定,而误差项可以忽略不计。

这种写法很重要,因为它不直接依赖导数,而是用 "小时间步内的增量" 来描述演化过程。对于 ODE 来说,这只是另一种等价表述;但对于 SDE 来说,这种增量视角更加自然。

现在来看 SDE:

d X t = u t ( X t ) d t + σ t d W t dX_t=u_t(X_t)dt+\sigma_t dW_t dXt=ut(Xt)dt+σtdWt

它可以理解为下面这种小步长形式:

X t + h = X t + h u t ( X t ) + σ t ( W t + h − W t ) + R t ( h ) X_{t+h}=X_t+h u_t(X_t)+\sigma_t(W_{t+h}-W_t)+R_t(h) Xt+h=Xt+hut(Xt)+σt(Wt+h−Wt)+Rt(h)

也就是说,下一个状态由三部分组成:

第一部分是当前状态 X t X_t Xt ;

第二部分是沿着向量场方向移动的一小步 h u t ( X t ) h u_t(X_t) hut(Xt) ;

第三部分是由布朗运动带来的随机增量 σ t ( W t + h − W t ) \sigma_t(W_{t+h}-W_t) σt(Wt+h−Wt) ,其中, σ t \sigma_t σt 控制噪声强度。

由于布朗运动的增量满足:

W t + h − W t ∼ N ( 0 , h I d ) W_{t+h}-W_t \sim \mathcal{N}(0,hI_d) Wt+h−Wt∼N(0,hId)

所以在实际模拟中,我们可以写成:

W t + h − W t = h ϵ t , ϵ t ∼ N ( 0 , I d ) W_{t+h}-W_t=\sqrt{h}\epsilon_t,\qquad\epsilon_t\sim \mathcal{N}(0,I_d) Wt+h−Wt=h ϵt,ϵt∼N(0,Id)

因此,SDE 的一步模拟可以直观理解为:

X t + h ≈ X t + h u t ( X t ) + σ t h ϵ t X_{t+h} \approx X_t + h u_t(X_t) + \sigma_t\sqrt{h}\epsilon_t Xt+h≈Xt+hut(Xt)+σth ϵt

也就是说,SDE 的每一步演化都是:

沿着向量场方向前进一步,同时加入一小段高斯噪声。

这里同样存在误差项 R t ( h ) R_t(h) Rt(h)。不过,因为现在过程是随机的,所以误差的刻画方式也要使用随机意义下的大小。我们不再要求误差本身按确定性方式趋于零,而是要求它在均方意义下足够小:

lim ⁡ h → 0 E ∣ R t ( h ) ∣ 2 1 / 2 h = 0 \lim_{h\to 0} \frac{\mathbb{E}\|R_t(h)\|\^2^{1/2}}{h} =0 h→0limhE∣Rt(h)∣21/2=0

直观上,这仍然表示误差项比主导的一阶项更小,因此在足够小的步长下可以忽略。


Q & A

Q:我们如何设置误差项?

A:我们并不手动设置误差项。

误差项只是数学分析中的一个对象,用来描述真实连续过程和小步长近似之间的差异。我们只需要知道,当步长 h h h 足够小时,这个误差项相对于主要项可以忽略。因此,在实际模拟时,我们不会显式计算它。

Q:SDE 和 ODE 部分的区别是什么?

A:区别就在于 SDE 多了一个随机增量项:

σ t ( W t + h − W t ) \sigma_t(W_{t+h}-W_t) σt(Wt+h−Wt)

或者在模拟时写作:

σ t h ϵ t \sigma_t \sqrt{h }\epsilon_t σth ϵt

ODE 只沿着向量场确定性地移动;而 SDE 在沿着向量场移动的同时,还会加入高斯噪声。因此,SDE 的轨迹不再是确定的,而是随机的。

Q :为什么误差项要除以 h h h,而不是只看误差项本身是否趋于零?

A:因为我们希望误差项相对于主要的一阶项可以忽略。

在 ODE 中,主要变化量是:

h u t ( X t ) h u_t(X_t) hut(Xt)

它本身是 h h h 量级的。如果我们只要求误差项趋于零,那还不够,因为它可能和 h h h 是同一量级,从而仍然会影响主要变化。

因此,我们要求:

R t ( h ) h → 0 \frac{R_t(h)}{h} \to 0 hRt(h)→0

这说明误差项比 h h h 更小,确实是高阶小量。这样在小步长近似中,主要贡献才是 h u t ( X t ) h u_t(X_t) hut(Xt) 。

Q:这里的区别是否可以理解为希望向演化中加入噪声?

A:是的。当前阶段,SDE 可以理解为在确定性演化的基础上加入随机性。

这种随机性目前只是扩展动力学的一种工具。后面我们会看到,它在训练和采样中都有重要作用。但需要记住的是,核心仍然是向量场。扩散项只是给动力学增加了一部分随机扰动。


当然,和 ODE 一样,我们也需要问:SDE 的解是否存在?

答案是,在合适条件下,SDE 的解是存在的。类似于 ODE,如果向量场足够光滑,例如连续可微且导数有界,那么我们可以保证 SDE 具有良好的解。

因此,出于本课程的实际目的,我们会假设 SDE 的解存在,并且可以像前面处理 ODE 那样继续使用它。


Q & A

Q:SDE 有唯一解是什么意思?

A:对于 ODE 来说,唯一解意味着给定初始条件后,轨迹是唯一的。

但对于 SDE 来说,轨迹本身是随机的,因此 "唯一解" 的含义不再是只有一条确定轨迹,而是说由这个 SDE 定义出的 轨迹分布 是唯一的。

换句话说,如果我们从同一个 SDE 出发,那么它在整个时间区间上诱导出的随机轨迹的联合分布是确定的。虽然每次采样得到的轨迹可能不同,但这些轨迹服从的整体概率分布是唯一确定的。

严格地说,这涉及随机过程上的概率测度,需要用随机微积分和测度论来精确定义。在本课程中,我们不需要深入这些细节,只需要知道:在合适条件下,SDE 可以良好地定义一个随机演化过程。

Q : σ t \sigma_t σt 是否也可以依赖于位置?

A:原则上可以。

也就是说,扩散系数不一定只能依赖时间,也可以依赖当前位置 x x x,写成类似:

σ t ( x ) \sigma_t(x) σt(x)

这样它就变成了状态相关的扩散项。不过在本课程和许多常见扩散模型中,通常会使用只依赖时间、不依赖状态的扩散系数。这种设定更简单,也更常见。


那么,如何模拟 SDE 呢?

基本思想其实很简单:沿着向量场方向移动,同时加入高斯噪声。

给定向量场 u t u_t ut 、扩散系数 σ t \sigma_t σt 、步长 h h h 和高斯噪声 ϵ ∼ N ( 0 , I d ) \epsilon \sim \mathcal{N}(0,I_d) ϵ∼N(0,Id) ,SDE 的一步模拟可以写成:

X t + h = X t + h u t ( X t ) + σ t h ϵ X_{t+h} = X_t + h u_t(X_t) + \sigma_t\sqrt{h}\epsilon Xt+h=Xt+hut(Xt)+σth ϵ

这就是最基本的 Euler-Maruyama 方法,可以看作欧拉法在 SDE 情况下的对应版本。

如果扩散系数为零,即 σ t = 0 \sigma_t=0 σt=0 ,那么随机项:

σ t h ϵ \sigma_t\sqrt{h}\epsilon σth ϵ

就会消失,SDE 退化为 ODE:

X t + h = X t + h u t ( X t ) X_{t+h}=X_t+h u_t(X_t) Xt+h=Xt+hut(Xt)

因此,从模拟角度看,SDE 并不神秘。它本质上就是在 ODE 的每一步模拟中额外加入了一项高斯噪声。前面的数学形式化只是为了严格描述这个直观过程,并为后续训练算法打下基础。


Q & A

Q:对于 ODE 有高阶数值方法,那么对于 SDE 是否也有类似方法?

A:有的。

ODE 的基本定义只涉及一阶导数,但在数值模拟时,我们可以使用更高阶的方法来减小误差。类似地,SDE 也存在更高阶的数值模拟方法。

不过,在本课程中,我们主要关注最基本的 SDE 模拟方法,因为它已经足够表达扩散模型中的核心采样思想。实际扩散模型中,也经常围绕采样器设计更高效的近似方法,但这些属于更进阶的内容。

Q:我们能否为 SDE 想象一种算法目标?

A:目前可以先把随机性理解为扩展动力学的一种手段。

在 ODE 中,给定初始点后,轨迹完全确定,只能沿着一条路径演化。而在 SDE 中,由于每一步都会注入随机噪声,所以从同一个初始点出发,也可能产生不同的轨迹。

这种随机性可以带来更多探索能力。比如,如果我们希望在生成过程中探索多种可能样本,随机演化就提供了一种自然机制。经验上,随机性也常常有助于增加生成结果的多样性。后续课程会进一步讨论这种随机性在生成模型中的具体作用。


下面看一个 SDE 的例子:

这个过程叫做 Ornstein-Uhlenbeck 过程。它可以看作前面线性 ODE 的随机版本。

前面我们讨论过线性向量场:

u t ( x ) = − θ x u_t(x)=-\theta x ut(x)=−θx

它会把点逐渐拉向原点。现在我们在这个确定性动力系统中加入噪声,得到对应的 SDE。这里的扩散系数是一个常数,因此噪声强度不随时间变化。

如果扩散系数 σ = 0 \sigma=0 σ=0 ,那么这个过程就退化为前面讨论的线性 ODE。此时轨迹是平滑且确定的。

随着 σ \sigma σ 增大,注入到系统中的随机噪声也越来越强,轨迹会变得更加粗糙和随机。这也说明了扩散项的作用:它会不断向动力学中注入随机扰动。

现在我们回到机器学习和生成建模的设定。

在流模型中,我们使用 ODE 将初始噪声分布转换为数据分布。而在扩散模型中,我们使用 SDE 来完成这个过程。也就是说,扩散模型的目标仍然是:

p init → p data p_{\text{init}}\rightarrow p_{\text{data}} pinit→pdata

但实现方式从确定性的 ODE 演化,变成了带随机性的 SDE 演化。

具体来说,我们仍然使用一个神经网络来表示向量场 u t θ ( x ) u_t^\theta(x) utθ(x) ,同时,我们还引入一个扩散系数 σ t \sigma_t σt 。需要注意的是,扩散系数通常不是神经网络,而是我们事先设定的函数或参数,它控制在不同时间加入多少噪声。

扩散模型中的样本演化由下面的 SDE 给出:

d X t = u t θ ( X t ) d t + σ t d W t dX_t=u_t^\theta(X_t)dt+\sigma_tdW_t dXt=utθ(Xt)dt+σtdWt

其中:

  • u t θ ( X t ) u_t^\theta(X_t) utθ(Xt) 是由神经网络给出的向量场,决定确定性运动方向;
  • σ t d W t \sigma_t dW_t σtdWt 是随机扩散项,决定随机噪声的注入。

和流模型一样,我们从一个简单的初始分布出发,通常是高斯分布:

X 0 ∼ p init X_0\sim p_{\text{init}} X0∼pinit

然后通过 SDE 演化,希望最终得到:

X 1 ∼ p data X_1\sim p_{\text{data}} X1∼pdata

因此,扩散模型可以理解为:

一个由神经网络向量场和扩散系数组成的随机动力系统。

从初始噪声出发,模拟这个 SDE,最终希望得到数据分布中的样本。

这里我们只是给出了扩散模型的目标和形式,还没有说明如何训练它。如何学习合适的向量场 u t θ u_t^\theta utθ ,将是后续课程的重点。

那么,如何从扩散模型中采样呢?

具体过程可以参考下面的 Algorithm 2:

采样过程和前面模拟 SDE 的方法一致:

  1. 从初始高斯噪声中采样一个初始点;
  2. 在每一步中,沿着神经网络给出的向量场方向移动;
  3. 同时加入由扩散系数缩放的高斯噪声;
  4. 重复这个过程,直到时间演化到 t = 1 t=1 t=1 ;
  5. 最终得到一个生成样本。

一步更新公式为:

X t + h = X t + h u t θ ( X t ) + σ t h ϵ , ϵ ∼ N ( 0 , I d ) X_{t+h} = X_t + h u_t^\theta(X_t) + \sigma_t\sqrt{h}\epsilon, \qquad \epsilon\sim\mathcal{N}(0,I_d) Xt+h=Xt+hutθ(Xt)+σth ϵ,ϵ∼N(0,Id)

从实现角度看,它和流模型采样非常相似。区别只是在每一步中,扩散模型额外加入了一个高斯噪声项。

因此,扩散模型并不是完全不同的生成机制,而是流模型的一种随机化扩展。

下面是一个蛋白质结构生成的例子:

图中展示了从高斯噪声开始生成蛋白质结构的过程。左边是 ODE 形式的生成过程,右边是 SDE 形式的生成过程。

可以看到,ODE 的轨迹更加确定和平滑,而 SDE 的轨迹由于不断注入随机噪声,因此表现得更加随机。这正是二者在采样动态上的主要差异。

5. Summary

最后,我们对本节课做一个简单总结。

本节课讨论了流模型和扩散模型,并从数学上定义了它们。我们的核心目标是:从一个简单、已知、容易采样的初始分布出发,通常是高斯噪声,然后通过某种动力系统将其转换为数据分布。

对于流模型,我们使用 ODE:

d d t X t = u t θ ( X t ) \frac{d}{dt}X_t=u_t^\theta(X_t) dtdXt=utθ(Xt)

其中, u t θ u_t^\theta utθ 是由神经网络参数化的向量场。我们从初始分布中随机采样一个起点,然后沿着这个向量场确定性地演化。如果模型学习得足够好,终点就会服从数据分布。

对于扩散模型,我们使用 SDE:

d X t = u t θ ( X t ) d t + σ t d W t dX_t = u_t^\theta(X_t)dt + \sigma_tdW_t dXt=utθ(Xt)dt+σtdWt

它在 ODE 的基础上额外加入了随机噪声。这里的扩散系数 σ t \sigma_t σt 控制噪声强度,而布朗运动 W t W_t Wt 提供随机扰动。因此,扩散模型可以看作带随机性的流模型。

到目前为止,我们已经回答了一个问题:如果给定一个训练好的模型,如何用它生成样本?

答案是:从高斯噪声出发,然后模拟对应的 ODE 或 SDE。对于 ODE,我们只沿着神经网络给出的向量场前进;对于 SDE,我们还会在每一步中额外加入高斯噪声。

但是,我们还没有回答更重要的问题:如何训练这个神经网络向量场,使得最终分布变成数据分布?

这正是下一节课的主题。下一节课将重点讨论训练算法,尤其是 流匹配(Flow Matching)。这些模型真正重要的地方在于:我们可以找到一种非常简洁、高效且可扩展的训练方法,用来学习这个向量场。


Q & A

Q:为什么要建模一个流,而不是直接用一个神经网络从噪声一步输出样本?

A:这个问题非常重要。表面上看,直接训练一个神经网络,让它从噪声一步生成样本,似乎更加简单高效。因为这样只需要一次神经网络调用,而不需要反复模拟 ODE 或 SDE。

但真正的困难在于训练。

如果直接一步从噪声映射到数据,我们需要一个稳定、可扩展的训练算法来实现这一点。目前来看,这件事情非常困难。GANs 等模型在某种程度上可以实现一步生成,但它们的训练通常不够稳定,也较难扩展到当前大规模生成任务。

相比之下,流模型和扩散模型虽然采样时需要多步模拟,但它们对应的训练目标可以设计得非常简洁和稳定。后面我们会看到,流匹配提供了一种高效的方式来学习向量场,这也是这类模型成功的重要原因之一。

因此,我们并不是因为多步模拟本身更理想才使用流模型或扩散模型,而是因为这种形式带来了更可训练、更稳定、更可扩展的学习问题。

Q:最终分布是什么?ODE 和 SDE 生成的分布在熵上是否不同?

A:从形式化目标上看,无论使用 ODE 还是 SDE,我们都希望最终分布是数据分布:

X 1 ∼ p data X_1\sim p_{\text{data}} X1∼pdata

因此,理想情况下,它们的终点分布应该相同,也就具有相同的熵。

不过在实际中,模型训练误差、数值模拟误差以及采样近似误差都会导致最终生成分布与真实数据分布存在偏差。因此,理论目标是相同的,但实际模型生成出的分布可能会有所不同。后续课程中也会继续讨论这些误差来源。


下一节课将进入训练部分,重点讨论 Flow Matching。本节课主要完成了生成模型的形式化:我们已经知道如何定义流模型和扩散模型,也知道在模型训练好之后如何进行采样。真正的核心问题,即如何学习这个向量场,将在下一节课中展开。

结语

在本次课程中,我们系统地介绍了生成模型的核心概念,并从数学视角理解了流模型(Flow Models)与扩散模型(Diffusion Models)。核心思想是:从一个简单的初始分布(通常是高斯噪声)出发,通过连续动力系统或带随机扰动的动力系统,将样本逐步转换为目标数据分布。

对于流模型,我们使用常微分方程(ODE)来描述样本沿向量场的确定性演化,强调了向量场的唯一性和数值模拟方法,如欧拉法。在扩散模型中,我们引入随机微分方程(SDE),通过布朗运动与扩散系数加入随机性,从而实现样本的多样化和探索能力。二者在采样机制上虽有差异,但目标一致:生成符合目标分布的高质量样本。

此外,我们讨论了生成模型的训练与采样策略的重要性。虽然直接一步生成样本看似简单,但流模型和扩散模型提供的多步模拟结构,使训练更加稳定、可扩展,并便于后续算法优化,如流匹配(Flow Matching)和 Score Matching。

总的来说,本节课奠定了生成式 AI 的数学基础,使我们理解了从噪声到数据分布的连续或随机变换过程,为后续学习如何高效训练流模型和扩散模型打下坚实基础。

下一讲我们将重点讨论 Flow Matching,敬请期待🤗

参考

相关推荐
Asimov_Liu3 天前
Diffusion 与 Flow Matching 数学原理及其在 VLA Action 生成中的应用
stable diffusion·自动驾驶·具身智能·vla·flow matching
*JOKER3 个月前
Flow Matching&生成算法
人工智能·深度学习·机器学习·大模型·生成模型·flow matching
阿杰学AI4 个月前
AI核心知识98——大语言模型之 Generative AI(简洁且通俗易懂版)
人工智能·语言模型·自然语言处理·aigc·生成式ai·generative ai
Beth_Chan4 个月前
Generative AI: RAG, AI Agents & Deployment
ai·aigc·agent·rag·genai·mcp·generative ai
阿杰学AI6 个月前
AI核心知识35——大语言模型之Generative AI(简洁且通俗易懂版)
人工智能·ai·语言模型·chatgpt·aigc·生成式ai·generative ai
千禧皓月8 个月前
【Diffusion Model】发展历程
人工智能·深度学习·diffusion model·1024程序员节
_Meilinger_8 个月前
碎片笔记|生成模型原理解读:AutoEncoder、GAN 与扩散模型图像生成机制
人工智能·生成对抗网络·gan·扩散模型·图像生成·diffusion model
归去_来兮1 年前
扩散模型(Diffusion Model)原理概述
扩散模型·diffusion model