├── .gitignore ├── cover.jpg ├── remove_code_blocks.py ├── PROJECT_STATUS.md ├── README.md ├── index.md ├── CLAUDE.md ├── html ├── assets │ ├── highlight.css │ ├── script.js │ └── style.css ├── PROJECT_STATUS.html ├── index.html ├── README.html ├── CLAUDE.html ├── appendix-b.html ├── appendix-c.html └── appendix-a.html ├── appendix-b.md ├── appendix-c.md ├── appendix-a.md ├── add_latex_spaces.py ├── chapter1.md ├── chapter3.md └── chapter2.md /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsc/diffusion_tutorial/HEAD/cover.jpg -------------------------------------------------------------------------------- /remove_code_blocks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import re 3 | import sys 4 | 5 | def remove_code_blocks(content): 6 | """Remove all ```python code blocks and replace with descriptions.""" 7 | 8 | # Pattern to match code blocks with context 9 | # This captures text before the code block to understand context 10 | pattern = r'(\*\*[^*]+\*\*:\s*\n)(```python\n[\s\S]*?```)' 11 | 12 | def replace_code_block(match): 13 | context = match.group(1) 14 | # Keep the context header but remove the code 15 | return context + "\n[代码实现已转换为数学公式和文字描述]" 16 | 17 | # First pass: replace code blocks that have clear context headers 18 | content = re.sub(pattern, replace_code_block, content) 19 | 20 | # Second pass: remove any remaining standalone code blocks 21 | content = re.sub(r'```python\n[\s\S]*?```', '[代码块已移除]', content) 22 | 23 | return content 24 | 25 | def process_file(filepath): 26 | with open(filepath, 'r', encoding='utf-8') as f: 27 | content = f.read() 28 | 29 | # Remove code blocks 30 | new_content = remove_code_blocks(content) 31 | 32 | # Write back 33 | with open(filepath, 'w', encoding='utf-8') as f: 34 | f.write(new_content) 35 | 36 | # Count how many blocks were removed 37 | original_count = content.count('```python') 38 | new_count = new_content.count('```python') 39 | removed = original_count - new_count 40 | 41 | print(f"Removed {removed} Python code blocks from {filepath}") 42 | 43 | if __name__ == "__main__": 44 | if len(sys.argv) > 1: 45 | filepath = sys.argv[1] 46 | else: 47 | filepath = "chapter10.md" 48 | 49 | process_file(filepath) -------------------------------------------------------------------------------- /PROJECT_STATUS.md: -------------------------------------------------------------------------------- 1 | # 扩散模型教程项目状态 2 | 3 | ## 项目完成情况 4 | 5 | ### ✅ 已完成的任务 6 | 7 | 1. **章节编写(14章全部完成)** 8 | - 第1章:扩散模型导论 9 | - 第2章:神经网络架构:U-Net与ViT 10 | - 第3章:去噪扩散概率模型 (DDPM) 11 | - 第4章:基于分数的生成模型 12 | - 第5章:连续时间扩散模型 (PDE/SDE) 13 | - 第6章:流匹配 (Flow Matching) 14 | - 第7章:扩散Transformer (DiT) 15 | - 第8章:采样算法与加速技术 16 | - 第9章:条件生成与引导技术 17 | - 第10章:潜在扩散模型 (LDM) 18 | - 第11章:视频扩散模型 19 | - 第12章:文本扩散模型 20 | - 第13章:扩散模型的应用 21 | - 第14章:前沿研究与未来方向 22 | 23 | 2. **代码块移除** 24 | - 所有Python代码块已成功移除 25 | - 代码内容已转换为数学公式和文字描述 26 | - 使用自动化脚本 `remove_code_blocks.py` 处理 27 | 28 | 3. **LaTeX格式优化** 29 | - 创建并优化了 `add_latex_spaces.py` 脚本 30 | - 确保单个 $ 的行内公式有适当空格 31 | - 确保 32 | 33 | $$ 的显示公式前有换行 34 | 35 | 4. **项目文件完善** 36 | - 更新了 `index.md`,标记所有章节为已完成 37 | - 创建了验证脚本 `validate_tutorial.py` 38 | - 所有章节包含丰富的练习题和研究线索 39 | 40 | ## 教程特色 41 | 42 | 1. **由浅入深的结构设计** 43 | - 从基础概念逐步过渡到前沿研究 44 | - 每章都有清晰的学习目标和章节大纲 45 | 46 | 2. **大量习题和参考答案** 47 | - 每个重要概念都配有练习题 48 | - 练习题包含理论推导和实践任务 49 | - 答案使用 `
` 标签默认折叠 50 | 51 | 3. **丰富的研究线索** 52 | - 使用 🔬 和 🌟 标记研究方向 53 | - 提供开放性问题供深入探索 54 | - 连接相关的数学理论和前沿论文 55 | 56 | 4. **数学严谨性** 57 | - 使用LaTeX格式的数学公式 58 | - 提供完整的推导过程 59 | - 平衡直观理解和理论深度 60 | 61 | ## 统计信息 62 | 63 | - 总行数:8,045行 64 | - 总字符数:155,944字符 65 | - 平均每章:574行,11,138字符 66 | - 最长章节:第14章(1,292行) 67 | - 最短章节:第5章(115行) 68 | 69 | ## 待完成项目(可选) 70 | 71 | 1. **附录编写** 72 | - 附录A:测度论与随机过程速成 73 | - 附录B:倒向随机微分方程 (BSDE) 速成 74 | 75 | 2. **交互式元素** 76 | - 可以添加可视化demo链接 77 | - 集成Jupyter notebook示例 78 | 79 | 3. **进一步优化** 80 | - 添加章节间的交叉引用 81 | - 创建术语表和索引 82 | - 设计统一的练习题难度标记系统 83 | 84 | ## 使用建议 85 | 86 | 1. **阅读顺序** 87 | - 初学者:按章节顺序阅读 88 | - 有基础者:可以跳过前3章 89 | - 研究者:重点关注5-7章和14章 90 | 91 | 2. **练习策略** 92 | - 每章至少完成一个练习题 93 | - 尝试拓展练习中的研究问题 94 | - 记录自己的理解和疑问 95 | 96 | 3. **深入学习** 97 | - 跟随研究线索查阅相关论文 98 | - 实现简化版本的算法 99 | - 参与开源项目实践 100 | 101 | ## 项目维护 102 | 103 | - 定期更新最新研究进展 104 | - 收集读者反馈改进内容 105 | - 添加更多实际应用案例 106 | - 保持数学符号的一致性 107 | 108 | --- 109 | 110 | 最后更新:2025-07-27 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 扩散模型教程 2 | 3 | ## Diffusion Models: From Theory to Practice 4 | 5 | 欢迎来到扩散模型教程!本教程将带你从基础理论逐步深入到实际应用,帮助你全面理解和掌握扩散模型这一强大的生成模型技术。 6 | 7 | 每个章节包含: 8 | 9 | - 理论基础与数学推导 10 | - 可视化演示和交互式示例 11 | - 编程练习与实践项目 12 | - 习题与参考答案(默认折叠) 13 | 14 | ## 前置知识要求 15 | 16 | 本教程假设读者已具备以下基础知识: 17 | 18 | - **概率论与统计**:随机变量、概率分布、期望、方差、贝叶斯定理 19 | - **线性代数**:矩阵运算、特征值分解、向量空间 20 | - **微积分**:多元微积分、偏导数、链式法则、泰勒展开 21 | - **深度学习基础**:神经网络、反向传播、卷积网络、Transformer 22 | - **PyTorch 编程**:张量操作、自动微分、模型训练流程 23 | 24 | 如果对某些概念不熟悉,建议先补充相关知识再开始学习。附录部分提供了部分高级数学概念的速成指南。 25 | 26 | ## 课程章节 27 | 28 | ### [第1章:扩散模型导论](chapter1.md) 29 | *已完成* 30 | 31 | 介绍扩散模型的基本概念、历史发展、与其他生成模型的比较,以及前向扩散过程的数学基础。 32 | 33 | ### [第2章:神经网络架构:U-Net与ViT](chapter2.md) 34 | *已完成* 35 | 36 | 探索去噪网络的历史发展,从医学图像分割到生成模型,深入理解U-Net架构演进和Vision Transformer的崛起。 37 | 38 | ### [第3章:去噪扩散概率模型 (DDPM)](chapter3.md) 39 | *已完成* 40 | 41 | 深入理解DDPM的核心原理,包括前向过程、反向过程、变分下界推导、训练算法和完整实现。 42 | 43 | ### [第4章:基于分数的生成模型](chapter4.md) 44 | *已完成* 45 | 46 | 探索score matching和Langevin dynamics,理解扩散模型与分数函数的深层联系。 47 | 48 | ### [第5章:连续时间扩散模型 (PDE/SDE)](chapter5.md) 49 | *已完成* 50 | 51 | 从随机微分方程(SDE)和偏微分方程(PDE)角度理解扩散模型,包括概率流ODE、Fokker-Planck方程等连续时间框架。 52 | 53 | ### [第6章:流匹配 (Flow Matching)](chapter6.md) 54 | *已完成* 55 | 56 | 连续正则化流、最优传输视角、与扩散模型的联系。 57 | 58 | ### [第7章:扩散Transformer (DiT)](chapter7.md) 59 | *已完成* 60 | 61 | Diffusion Transformer架构、与U-Net的对比、可扩展性分析。 62 | 63 | ### [第8章:采样算法与加速技术](chapter8.md) 64 | *已完成* 65 | 66 | 学习DDIM、DPM-Solver等快速采样方法,以及如何优化生成质量与速度的平衡。 67 | 68 | ### [第9章:条件生成与引导技术](chapter9.md) 69 | *已完成* 70 | 71 | 掌握classifier guidance、classifier-free guidance等条件生成技术,实现可控生成。 72 | 73 | ### [第10章:潜在扩散模型 (LDM)](chapter10.md) 74 | *已完成* 75 | 76 | 理解Stable Diffusion的架构,学习如何在潜在空间中进行高效的扩散建模。 77 | 78 | ### [第11章:视频扩散模型](chapter11.md) 79 | *已完成* 80 | 81 | 时序建模、3D U-Net、视频生成的挑战与方法。 82 | 83 | ### [第12章:文本扩散模型](chapter12.md) 84 | *已完成* 85 | 86 | 探索离散域上的扩散模型,包括D3PM、Diffusion-LM等文本生成方法,以及embedding空间的扩散技术。 87 | 88 | ### [第13章:扩散模型的应用](chapter13.md) 89 | *已完成* 90 | 91 | 探索图像生成、图像编辑、超分辨率、3D生成等实际应用场景。 92 | 93 | ### [第14章:前沿研究与未来方向](chapter14.md) 94 | *已完成* 95 | 96 | 了解最新研究进展,包括一致性模型、扩散模型的未来发展趋势。 97 | 98 | ## 附录 99 | 100 | ### [附录A:测度论与随机过程速成](appendix-a.md) 101 | *已完成* 102 | 103 | 为第5章PDE/SDE内容提供数学基础,包括σ-代数、测度、布朗运动等核心概念。 104 | 105 | ### [附录B:倒向随机微分方程 (BSDE) 速成](appendix-b.md) 106 | *已完成* 107 | 108 | 理解扩散模型反向过程的数学工具,包括BSDE基本理论、Feynman-Kac公式等。 109 | 110 | ### [附录C:信息几何与分数函数的力学解释](appendix-c.md) 111 | *已完成* 112 | 113 | 从信息几何角度理解扩散模型,揭示分数函数作为"力"的物理意义,建立与能量优化的联系。 114 | 115 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | # 扩散模型教程 2 | 3 | ## Diffusion Models: From Theory to Practice 4 | 5 | 欢迎来到扩散模型教程!本教程将带你从基础理论逐步深入到实际应用,帮助你全面理解和掌握扩散模型这一强大的生成模型技术。 6 | 7 | 每个章节包含: 8 | 9 | - 理论基础与数学推导 10 | - 可视化演示和交互式示例 11 | - 编程练习与实践项目 12 | - 习题与参考答案(默认折叠) 13 | 14 | ## 前置知识要求 15 | 16 | 本教程假设读者已具备以下基础知识: 17 | 18 | - **概率论与统计**:随机变量、概率分布、期望、方差、贝叶斯定理 19 | - **线性代数**:矩阵运算、特征值分解、向量空间 20 | - **微积分**:多元微积分、偏导数、链式法则、泰勒展开 21 | - **深度学习基础**:神经网络、反向传播、卷积网络、Transformer 22 | - **PyTorch 编程**:张量操作、自动微分、模型训练流程 23 | 24 | 如果对某些概念不熟悉,建议先补充相关知识再开始学习。附录部分提供了部分高级数学概念的速成指南。 25 | 26 | ## 课程章节 27 | 28 | ### [第1章:扩散模型导论](chapter1.md) 29 | *已完成* 30 | 31 | 介绍扩散模型的基本概念、历史发展、与其他生成模型的比较,以及前向扩散过程的数学基础。 32 | 33 | ### [第2章:神经网络架构:U-Net与ViT](chapter2.md) 34 | *已完成* 35 | 36 | 探索去噪网络的历史发展,从医学图像分割到生成模型,深入理解U-Net架构演进和Vision Transformer的崛起。 37 | 38 | ### [第3章:去噪扩散概率模型 (DDPM)](chapter3.md) 39 | *已完成* 40 | 41 | 深入理解DDPM的核心原理,包括前向过程、反向过程、变分下界推导、训练算法和完整实现。 42 | 43 | ### [第4章:基于分数的生成模型](chapter4.md) 44 | *已完成* 45 | 46 | 探索score matching和Langevin dynamics,理解扩散模型与分数函数的深层联系。 47 | 48 | ### [第5章:连续时间扩散模型 (PDE/SDE)](chapter5.md) 49 | *已完成* 50 | 51 | 从随机微分方程(SDE)和偏微分方程(PDE)角度理解扩散模型,包括概率流ODE、Fokker-Planck方程等连续时间框架。 52 | 53 | ### [第6章:流匹配 (Flow Matching)](chapter6.md) 54 | *已完成* 55 | 56 | 连续正则化流、最优传输视角、与扩散模型的联系。 57 | 58 | ### [第7章:扩散Transformer (DiT)](chapter7.md) 59 | *已完成* 60 | 61 | Diffusion Transformer架构、与U-Net的对比、可扩展性分析。 62 | 63 | ### [第8章:采样算法与加速技术](chapter8.md) 64 | *已完成* 65 | 66 | 学习DDIM、DPM-Solver等快速采样方法,以及如何优化生成质量与速度的平衡。 67 | 68 | ### [第9章:条件生成与引导技术](chapter9.md) 69 | *已完成* 70 | 71 | 掌握classifier guidance、classifier-free guidance等条件生成技术,实现可控生成。 72 | 73 | ### [第10章:潜在扩散模型 (LDM)](chapter10.md) 74 | *已完成* 75 | 76 | 理解Stable Diffusion的架构,学习如何在潜在空间中进行高效的扩散建模。 77 | 78 | ### [第11章:视频扩散模型](chapter11.md) 79 | *已完成* 80 | 81 | 时序建模、3D U-Net、视频生成的挑战与方法。 82 | 83 | ### [第12章:文本扩散模型](chapter12.md) 84 | *已完成* 85 | 86 | 探索离散域上的扩散模型,包括D3PM、Diffusion-LM等文本生成方法,以及embedding空间的扩散技术。 87 | 88 | ### [第13章:扩散模型的应用](chapter13.md) 89 | *已完成* 90 | 91 | 探索图像生成、图像编辑、超分辨率、3D生成等实际应用场景。 92 | 93 | ### [第14章:前沿研究与未来方向](chapter14.md) 94 | *已完成* 95 | 96 | 了解最新研究进展,包括一致性模型、扩散模型的未来发展趋势。 97 | 98 | ## 附录 99 | 100 | ### [附录A:测度论与随机过程速成](appendix-a.md) 101 | *已完成* 102 | 103 | 为第5章PDE/SDE内容提供数学基础,包括σ-代数、测度、布朗运动等核心概念。 104 | 105 | ### [附录B:倒向随机微分方程 (BSDE) 速成](appendix-b.md) 106 | *已完成* 107 | 108 | 理解扩散模型反向过程的数学工具,包括BSDE基本理论、Feynman-Kac公式等。 109 | 110 | ### [附录C:信息几何与分数函数的力学解释](appendix-c.md) 111 | *已完成* 112 | 113 | 从信息几何角度理解扩散模型,揭示分数函数作为"力"的物理意义,建立与能量优化的联系。 114 | 115 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | (交流可以用英文,本文档中文,保留这句) 2 | 3 | # 扩散模型教程项目说明 4 | 5 | ## 项目目标 6 | 编写一份 扩散模型设计的由浅入深的教程markdown,要包含大量的习题和参考答案(答案默认折叠)。合适时提及相关 pytorch 函数名但不写代码。 7 | 项目特色是,包含大量的可继续研究的线索 8 | 9 | ## 工具说明 10 | 当需要时,可以通过 `gemini -p "深入回答:<要问的问题> -m gemini-2.5-pro"` 来获取 gemini-2.5-pro 的参考意见(gemini 系只问 gemini-2.5-pro 不问别人) 11 | 当需要时,可以通过 `echo "<要问的问题>"|llm -m 4.1 来获取 gpt-4.1 的参考意见 12 | 13 | ## 教程大纲 14 | 15 | ### 最终章节结构(14章 + 附录) 16 | 17 | 1. **第1章:扩散模型导论** - 基本概念、历史发展、前向扩散过程 18 | 2. **第2章:神经网络架构:U-Net与ViT** - 扩散模型中的去噪网络架构,U-Net详解,Vision Transformer在扩散模型中的应用 19 | 3. **第3章:去噪扩散概率模型 (DDPM)** - 核心原理、变分下界、训练算法 20 | 4. **第4章:基于分数的生成模型** - Score matching、Langevin dynamics 21 | 5. **第5章:连续时间扩散模型 (PDE/SDE)** - 随机微分方程、概率流ODE、Fokker-Planck方程 22 | 6. **第6章:流匹配 (Flow Matching)** - 连续正则化流、最优传输视角、与扩散模型的联系 23 | 7. **第7章:扩散Transformer (DiT)** - Diffusion Transformer架构、与U-Net的对比、可扩展性分析 24 | 8. **第8章:采样算法与加速技术** - DDIM、DPM-Solver等快速采样方法 25 | 9. **第9章:条件生成与引导技术** - Classifier guidance、classifier-free guidance 26 | 10. **第10章:潜在扩散模型 (LDM)** - Stable Diffusion架构 27 | 11. **第11章:视频扩散模型** - 时序建模、3D U-Net、视频生成的挑战与方法 28 | 12. **第12章:文本扩散模型** - D3PM、Diffusion-LM、embedding空间扩散 29 | 13. **第13章:扩散模型的应用** - 图像生成、编辑、超分辨率、3D生成 30 | 14. **第14章:前沿研究与未来方向** - 一致性模型、扩散模型的未来发展趋势 31 | 32 | **附录A:测度论与随机过程速成** - 为第5章PDE/SDE内容提供数学基础 33 | **附录B:倒向随机微分方程 (BSDE) 速成** - 理解扩散模型反向过程的数学工具 34 | 35 | ### 内容设计原则 36 | 37 | 1. **PDE/SDE章节方法**: 38 | - 先介绍直觉和实际实现 39 | - 然后进行完整推导,包括reverse SDE 40 | - 测度论和随机微积分速成课程放在附录 41 | 42 | 2. **文本扩散模型重点**: 43 | - 离散状态空间扩散(如D3PM) 44 | - 连续embedding空间扩散(如Diffusion-LM) 45 | - 两者并重 46 | 47 | 3. **交互元素**: 48 | - 保持简单,先用静态图像 49 | - 逐步增加交互性 50 | 51 | 4. **编程语言和框架**: 52 | - Python/PyTorch(不用JAX) 53 | - 方法可以高级,但限于toy data 54 | 55 | 5. **章节依赖性**: 56 | - 每章尽量自包含 57 | - 文本扩散模型章节(第8章)设计为独立可读 58 | 59 | 6. **练习设计**: 60 | - 理论和实现混合 61 | - 包含挑战题 62 | - 难度递进 63 | 64 | 7. **代码框架**: 65 | - 逐章构建mini-library 66 | - 提供skeleton code让学生填充 67 | 68 | 8. **前置知识**: 69 | - 假设学生已有概率论、神经网络基础、PyTorch经验 70 | - 在首页明确说明这些前置要求 71 | 72 | ## 章节格式要求 73 | 74 | 每个章节应包含: 75 | 76 | 1. **开篇段落** - 引入本章主题,说明学习目标 77 | 2. **丰富的文字描述** - 不仅是公式,要有充分的文字解释和直观说明 78 | 3. **本章小结** - 总结要点,预告下一章内容 79 | 80 | ## 输出大小控制 81 | 82 | **重要原则**: 83 | - 输入可以是章节级别的请求(如"创建第2章") 84 | - 但输出必须限制在一个小节(section)的大小,不超过 85 | - 有时甚至要在子小节(subsection)级别工作 86 | - 这样确保每次生成的内容精炼且高质量 87 | 88 | ### 统一样式要求 89 | 90 | 1. **使用共享CSS/JS文件** - 将通用样式抽取到 `common.css` 和 `common.js` 91 | 2. **长代码和练习答案默认折叠** - 使用统一的折叠/展开机制 92 | 3. **响应式设计** - 确保移动端友好 93 | 4. **数学公式** - 使用KaTeX渲染 94 | 5. **代码高亮** - 使用Prism.js或类似库 95 | 96 | # important-instruction-reminders 97 | Do what has been asked; nothing more, nothing less. 98 | NEVER create files unless they're absolutely necessary for achieving your goal. 99 | ALWAYS prefer editing an existing file to creating a new one. 100 | NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User. 101 | -------------------------------------------------------------------------------- /html/assets/highlight.css: -------------------------------------------------------------------------------- 1 | .codehilite { background: #f8f8f8; } 2 | .codehilite .hll { background-color: #ffffcc } 3 | .codehilite .c { color: #999988; font-style: italic } /* Comment */ 4 | .codehilite .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 5 | .codehilite .k { color: #000000; font-weight: bold } /* Keyword */ 6 | .codehilite .o { color: #000000; font-weight: bold } /* Operator */ 7 | .codehilite .cm { color: #999988; font-style: italic } /* Comment.Multiline */ 8 | .codehilite .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */ 9 | .codehilite .c1 { color: #999988; font-style: italic } /* Comment.Single */ 10 | .codehilite .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ 11 | .codehilite .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 12 | .codehilite .ge { color: #000000; font-style: italic } /* Generic.Emph */ 13 | .codehilite .gr { color: #aa0000 } /* Generic.Error */ 14 | .codehilite .gh { color: #999999 } /* Generic.Heading */ 15 | .codehilite .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 16 | .codehilite .go { color: #888888 } /* Generic.Output */ 17 | .codehilite .gp { color: #555555 } /* Generic.Prompt */ 18 | .codehilite .gs { font-weight: bold } /* Generic.Strong */ 19 | .codehilite .gu { color: #aaaaaa } /* Generic.Subheading */ 20 | .codehilite .gt { color: #aa0000 } /* Generic.Traceback */ 21 | .codehilite .kc { color: #000000; font-weight: bold } /* Keyword.Constant */ 22 | .codehilite .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */ 23 | .codehilite .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */ 24 | .codehilite .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */ 25 | .codehilite .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */ 26 | .codehilite .kt { color: #445588; font-weight: bold } /* Keyword.Type */ 27 | .codehilite .m { color: #009999 } /* Literal.Number */ 28 | .codehilite .s { color: #dd1144 } /* Literal.String */ 29 | .codehilite .na { color: #008080 } /* Name.Attribute */ 30 | .codehilite .nb { color: #0086B3 } /* Name.Builtin */ 31 | .codehilite .nc { color: #445588; font-weight: bold } /* Name.Class */ 32 | .codehilite .no { color: #008080 } /* Name.Constant */ 33 | .codehilite .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */ 34 | .codehilite .ni { color: #800080 } /* Name.Entity */ 35 | .codehilite .ne { color: #990000; font-weight: bold } /* Name.Exception */ 36 | .codehilite .nf { color: #990000; font-weight: bold } /* Name.Function */ 37 | .codehilite .nl { color: #990000; font-weight: bold } /* Name.Label */ 38 | .codehilite .nn { color: #555555 } /* Name.Namespace */ 39 | .codehilite .nt { color: #000080 } /* Name.Tag */ 40 | .codehilite .nv { color: #008080 } /* Name.Variable */ 41 | .codehilite .ow { color: #000000; font-weight: bold } /* Operator.Word */ 42 | .codehilite .w { color: #bbbbbb } /* Text.Whitespace */ 43 | .codehilite .mf { color: #009999 } /* Literal.Number.Float */ 44 | .codehilite .mh { color: #009999 } /* Literal.Number.Hex */ 45 | .codehilite .mi { color: #009999 } /* Literal.Number.Integer */ 46 | .codehilite .mo { color: #009999 } /* Literal.Number.Oct */ 47 | .codehilite .sb { color: #dd1144 } /* Literal.String.Backtick */ 48 | .codehilite .sc { color: #dd1144 } /* Literal.String.Char */ 49 | .codehilite .sd { color: #dd1144 } /* Literal.String.Doc */ 50 | .codehilite .s2 { color: #dd1144 } /* Literal.String.Double */ 51 | .codehilite .se { color: #dd1144 } /* Literal.String.Escape */ 52 | .codehilite .sh { color: #dd1144 } /* Literal.String.Heredoc */ 53 | .codehilite .si { color: #dd1144 } /* Literal.String.Interpol */ 54 | .codehilite .sx { color: #dd1144 } /* Literal.String.Other */ 55 | .codehilite .sr { color: #009926 } /* Literal.String.Regex */ 56 | .codehilite .s1 { color: #dd1144 } /* Literal.String.Single */ 57 | .codehilite .ss { color: #990073 } /* Literal.String.Symbol */ 58 | .codehilite .bp { color: #999999 } /* Name.Builtin.Pseudo */ 59 | .codehilite .vc { color: #008080 } /* Name.Variable.Class */ 60 | .codehilite .vg { color: #008080 } /* Name.Variable.Global */ 61 | .codehilite .vi { color: #008080 } /* Name.Variable.Instance */ 62 | .codehilite .il { color: #009999 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /appendix-b.md: -------------------------------------------------------------------------------- 1 | [← 附录A](appendix-a.md) | 附录B | [附录C →](appendix-c.md) 2 | 3 | # 附录B:倒向随机微分方程 (BSDE) 速成 4 | 5 | 倒向随机微分方程(Backward Stochastic Differential Equations, BSDE)是理解扩散模型反向过程,特别是其与最优控制和经济学联系的重要数学工具。本附录将快速介绍BSDE的核心概念,旨在为读者提供一个更深刻的理论视角。 6 | 7 | ## B.1 从前向到倒向:问题的提出 8 | 9 | 标准的前向SDE(FSDE)从一个已知的初始状态 `X_0` 出发,描述系统如何演化到未来。然而,在许多问题中,我们关心的是一个“目标导向”的问题:给定一个在未来时刻 `T` 的目标(或成本)`ξ`,我们想知道在当前时刻 `t` 的“价值”`Y_t` 以及为了达到该目标需要采取的“策略”`Z_t`。 10 | 11 | > **定义 B.1 (一般BSDE)** 12 | > 一个BSDE的解是一对随机过程 `(Y_t, Z_t)`,满足: 13 | > 14 | 15 | $$-dY_t = f(t, Y_t, Z_t)dt - Z_t dW_t$$ 16 | > 并满足一个**终端条件** `Y_T = ξ`。 17 | 18 | **与FSDE的核心区别**: 19 | - **信息流向**:FSDE由初始条件决定,向未来求解。BSDE由终端条件决定,向过去求解。 20 | - **解的构成**:FSDE的解是一个过程 `X_t`。BSDE的解是一对过程 `(Y_t, Z_t)`。 21 | 22 | **直观理解 `Y_t` 和 `Z_t`**: 23 | - **`Y_t` (价值过程)**: 代表在时刻 `t`,为了满足终端条件 `ξ` 所需的“价值”或“成本”。 24 | - **`Z_t` (策略/对冲过程)**: 代表在时刻 `t`,为了应对随机性 `dW_t` 而需要采取的“策略”或“控制”。在金融中,这对应于对冲组合;在扩散模型中,它与分数函数 `∇log p_t` 密切相关。 25 | 26 | ## B.2 核心理论 27 | 28 | ### B.2.1 存在唯一性 29 | 30 | BSDE理论的基石是由Pardoux和彭实戈在1990年证明的存在唯一性定理。 31 | 32 | > **定理 B.2 (Pardoux-Peng, 1990)** 33 | > 如果终端条件 `ξ` 是平方可积的,且驱动函数 `f(t, y, z)` 关于 `y` 和 `z` 满足Lipschitz连续性,那么BSDE存在唯一的平方可积解 `(Y, Z)`。 34 | 35 | 这个定理保证了我们讨论的问题是良定义的。后续的研究将条件放宽到了二次增长的驱动函数,这对于连接BSDE和某些物理或金融模型至关重要。 36 | 37 | ### B.2.2 比较定理 38 | 39 | BSDE的一个强大性质是比较定理,它允许我们比较不同BSDE的解。 40 | **简而言之**:如果一个BSDE的终端条件和驱动函数都“更大”,那么它的解 `Y_t` 在任何时刻 `t` 也都“更大”。这在风险度量和最优控制中非常有用。 41 | 42 | ### B.2.3 BSDE与PDE的联系:非线性Feynman-Kac公式 43 | 44 | BSDE与偏微分方程(PDE)之间存在深刻的对偶关系,这通过非线性Feynman-Kac公式建立。 45 | 46 | 🌟 **理论核心**:一个(半)线性抛物型PDE的解,可以表示为一个BSDE的解的期望。反之,一个BSDE的解 `Y_t` 也可以看作是某个PDE `u(t, X_t)` 沿着随机路径 `X_t` 的演化。具体来说,`Y_t = u(t, X_t)`,而 `Z_t` 与 `u` 的空间梯度 `∇u` 相关:`Z_t = σ^T * ∇u`。 47 | 48 | 这个联系是双向的: 49 | - 我们可以用概率方法(模拟BSDE)来求解高维PDE。 50 | - 我们可以用PDE的理论来分析BSDE的性质。 51 | 52 | ## B.3 BSDE在扩散模型中的应用 53 | 54 | BSDE为连续时间扩散模型提供了严格的数学描述。 55 | 56 | 1. **反向过程的刻画**:扩散模型的反向过程,即从噪声 `x_T` 生成数据 `x_0` 的过程,本质上是一个终端值问题,可以用BSDE来精确描述。 57 | 58 | 2. **分数函数的演化**:定义 `Y_t = log p_t(X_t)`,即沿着随机路径 `X_t` 的对数概率密度。可以证明,`Y_t` 满足一个驱动函数 `f` 具有二次增长的非线性BSDE。在这个BSDE中,`Z_t` 过程与分数函数 `∇log p_t(X_t)` 直接相关。 59 | 60 | 💡 **关键洞察**:这意味着,学习分数函数的过程,可以被看作是求解一个非线性BSDE的过程。这为设计新的损失函数和训练算法提供了理论依据。例如,我们可以通过最小化BSDE的残差来学习分数模型。 61 | 62 | 3. **与最优传输的联系**:连接两个分布 `p_0` 和 `p_T` 的Schrödinger桥问题,可以被转化为求解一个耦合的前向-倒向SDE(FBSDE)系统。这个系统的解给出了在两个分布之间转换的最优随机路径,为扩散模型提供了最优传输的视角。 63 | 64 | ## B.4 数值方法简介 65 | 66 | 由于大多数BSDE没有解析解,数值方法至关重要。 67 | 68 | - **时间离散化**:最常见的是向后欧拉格式。从 `Y_T = ξ` 开始,反向迭代求解 `(Y_{t_i}, Z_{t_i})`。每一步都需要计算一个条件期望,这是数值求解的难点。 69 | 70 | - **深度学习方法 (Deep BSDE)**:现代方法使用神经网络来参数化未知的 `Z_t` 过程。其核心思想是: 71 | 1. 用一个神经网络 `Z_θ(t, x)` 来近似 `Z_t`。 72 | 2. 从 `t=0` 开始,使用 `Z_θ` 和一个猜测的初始值 `Y_0`,通过离散化格式前向模拟出 `Y_T`。 73 | 3. 最小化模拟得到的 `Y_T` 和真实的终端条件 `ξ` 之间的误差 `||Y_T - ξ||^2`。 74 | 4. 通过反向传播训练网络参数 `θ` 和初始值 `Y_0`。 75 | 76 | ⚡ **实现挑战**:Deep BSDE方法将一个复杂的随机控制问题转化为了一个深度学习的优化问题,但在高维情况下,仍然面临“维度灾难”的挑战。 77 | 78 |
79 | 练习 B.1:线性BSDE的显式解 80 | 81 | 考虑线性BSDE:` -dY_t = (aY_t + f_t)dt - Z_t dW_t`,终端条件为 `Y_T = ξ`,其中 `a` 是常数,`f_t` 是确定性函数。 82 | 1. **求解**:使用积分因子 `e^{at}`,求解 `Y_t` 的表达式。 83 | 2. **分析**:解释解的表达式的金融学含义(将 `a` 视为贴现率)。 84 | 3. **开放探索**:如果 `a` 也是一个随机过程 `a_t`,解会是什么形式?这在随机利率模型中很常见。 85 | 86 | **解答思路**: 87 | 1. 对 `tilde(Y)_t = e^{at}Y_t` 应用伊藤公式,可以消去 `Y_t` 的漂移项,得到一个只包含 `dt` 和 `dW_t` 的SDE。对其积分再整理,最终得到 `Y_t = E[e^{-a(T-t)}ξ + ∫_t^T e^{-a(s-t)}f_s ds | F_t]`。 88 | 2. 这个解表示,时刻 `t` 的价值等于未来所有现金流 `f_s` 和终端价值 `ξ` 在考虑了贴现因子 `e^{-a(s-t)}` 后的条件期望。 89 | 90 |
91 | 92 |
93 | 练习 B.2:BSDE与热方程 94 | 95 | 证明热方程 `∂u/∂t + 1/2 * Δu = 0`,`u(T,x) = g(x)` 的解可以用一个BSDE表示。 96 | 1. **构造过程**:定义一个前向过程 `X_t^x = x + W_t` 和一个新过程 `Y_t = u(t, X_t^x)`。 97 | 2. **应用伊藤公式**:对 `Y_t` 应用伊藤公式。 98 | 3. **建立联系**:利用 `u` 是热方程的解这一事实,证明 `Y_t` 满足一个驱动函数 `f=0` 的BSDE。 99 | 100 | **研究思路**:这个练习展示了Feynman-Kac公式最简单的情形。思考一下,如果PDE中有一个非线性的项,例如 `∂u/∂t + 1/2 * Δu + (∇u)^2 = 0`(Hamilton-Jacobi-Bellman方程),那么对应的BSDE的驱动函数 `f` 会是什么样的? 101 | 102 |
103 | 104 | ## 本章小结 105 | 106 | - **核心定义**:BSDE是从一个未来的终端条件出发,向后求解的随机微分方程,其解为一对 `(Y_t, Z_t)` 过程。 107 | - **理论基石**:存在唯一性定理和比较定理保证了BSDE的良好性质。非线性Feynman-Kac公式建立了BSDE与PDE的深刻联系。 108 | - **扩散模型应用**:BSDE为描述扩散模型的反向过程和分数函数的演化提供了严格的数学框架,并将其与最优控制和最优传输理论联系起来。 109 | 110 | 虽然BSDE理论较为抽象,但它为我们理解“目标导向”的随机过程提供了统一而强大的语言,是连接概率论、PDE和机器学习的重要桥梁。 111 | -------------------------------------------------------------------------------- /appendix-c.md: -------------------------------------------------------------------------------- 1 | [← 附录B](appendix-b.md) | 附录C | [返回首页 →](index.md) 2 | 3 | # 附录C:信息几何与分数函数的力学解释 4 | 5 | 扩散模型的成功不仅是工程上的胜利,更是深刻数学原理的体现。本附录将从信息几何(Information Geometry)的角度重新审视扩散模型,揭示分数函数作为“力”的物理意义,并建立与能量优化的深刻联系。这种视角不仅提供了强大的理论洞察,也为设计新算法提供了直观的指导原则。 6 | 7 | ## C.1 信息几何基础 8 | 9 | 信息几何将概率分布空间 `P` 视为一个具有内在几何结构的黎曼流形(Riemannian manifold),而不是一个平坦的欧几里得空间。 10 | 11 | ### C.1.1 概率分布流形 12 | 13 | - **概率单纯形**: 对于离散分布,所有可能的概率向量构成一个单纯形。这是一个嵌入在高维空间中的弯曲子流形。 14 | - **Fisher信息度量**: 这个流形上的“距离”不是欧几里得距离,而是由**Fisher信息矩阵** `I(θ)` 定义的黎曼度量。两点之间的最短路径是测地线(geodesic)。 15 | > **定义 C.1 (Fisher信息矩阵)** 16 | > 对于参数化的概率分布族 `{p(x; θ)}`,Fisher信息矩阵定义为: 17 | > 18 | 19 | $$I_{ij}( heta) = \mathbb{E}_{p(x;\theta)}\left[\frac{\partial \log p(x;\theta)}{\partial \theta_i} \frac{\partial \log p(x;\theta)}{\partial \theta_j}\right]$$ 20 | 它衡量了当我们微小地改变参数 `θ` 时,概率分布 `p(x; θ)` 的变化有多大。信息矩阵的元素越大,表示分布对该方向的参数变化越敏感。 21 | 22 | ### C.1.2 自然梯度 (Natural Gradient) 23 | 24 | 在优化概率模型时,普通的梯度下降是在平坦的欧几里得空间中寻找最速下降方向。然而,在弯曲的概率流形上,真正的最速下降方向由**自然梯度**给出。 25 | 26 | > **定义 C.2 (自然梯度)** 27 | > 设 `L(θ)` 是关于参数 `θ` 的损失函数,普通梯度为 `g = ∇_θ L`。自然梯度 `g_nat` 定义为: 28 | > 29 | 30 | $$\tilde{g} = I(\theta)^{-1} g$$ 31 | > 优化步骤变为:`θ_{t+1} = θ_t - α * I(θ_t)^{-1} * g_t`。 32 | 33 | 💡 **关键洞察**:自然梯度下降具有**参数化不变性**。无论我们如何对模型进行重新参数化(例如,线性变换),其在概率流形上的优化路径都是相同的。而普通梯度下降的路径则会随参数化的改变而改变。这使得自然梯度在理论上是优化概率模型的更优选择。 34 | 35 | ⚡ **实现挑战**:计算完整的Fisher信息矩阵并求逆的代价非常高昂(`O(N^2)`,N为参数量)。在实践中,通常使用其对角近似、K-FAC等方法来降低计算成本。Adam等自适应优化算法也可以被看作是对自然梯度的一种简化近似。 36 | 37 |
38 | 练习 C.1:Fisher信息计算 39 | 40 | 1. **计算**:对于一维高斯分布 `N(μ, σ^2)`,其参数为 `θ = (μ, σ)`。计算其2x2的Fisher信息矩阵 `I(μ, σ)`。 41 | 2. **分析**:从矩阵的形式分析:a) 为什么估计均值 `μ` 和估计标准差 `σ` 是解耦的?b) 为什么当 `σ` 很小时,Fisher信息会变大? 42 | 3. **开放探索**:自然梯度在训练扩散模型的分数网络 `s_θ` 时有何应用?`θ` 是网络权重,此时的Fisher信息矩阵该如何定义和计算? 43 | 44 | **解答思路**: 45 | 1. 写出对数似然 `log p(x; μ, σ)`,然后计算其对 `μ` 和 `σ` 的二阶偏导数的期望。你会发现非对角线项的期望为0,对角线项分别为 `1/σ^2` 和 `2/σ^2`。 46 | 2. a) 非对角线项为0意味着参数 `μ` 和 `σ` 在Fisher度量下是正交的。b) `σ` 越小,分布越集中,从样本中推断参数位置的信息就越多,因此Fisher信息越大。 47 | 48 |
49 | 50 | ## C.2 分数函数的几何与力学解释 51 | 52 | ### C.2.1 分数函数作为切向量 53 | 54 | 从信息几何的角度看,分数函数 `s(x) = ∇_x log p(x)` 不仅仅是一个梯度,它是在数据空间 `x` 中,定义了一个指向概率密度 `p(x)` 增长最快方向的**向量场**。 55 | 56 | - **与流形的关系**:可以证明 `E_p[s(x)] = 0`,这意味着分数函数属于概率分布流形在某一点的**切空间**。 57 | - **动力学意义**:如果我们让一个粒子沿着这个向量场流动,即 `dx/dt = s(x)`,粒子最终会收敛到概率分布的局部最大值(模式)。 58 | 59 | ### C.2.2 Stein恒等式 60 | 61 | Stein恒等式是连接分数函数与概率分布的桥梁,它构成了分数匹配的理论基础。 62 | 63 | > **定理 C.3 (Stein恒等式)** 64 | > 对于一个足够光滑的测试函数 `φ(x)` 和概率密度 `p(x)`,在一定边界条件下成立: 65 | > 66 | 67 | $$\mathbb{E}_{p(x)}[\nabla_x \cdot \phi(x) + \phi(x) \cdot \nabla_x \log p(x)] = 0$$ 68 | 69 | 💡 **关键洞察**:这个恒等式只涉及分数 `∇log p(x)` 和 `p(x)` 的期望,而完全不依赖于 `p(x)` 本身及其归一化常数。这使得我们可以在只拥有 `p(x)` 的样本的情况下,通过最小化Stein恒等式的残差来学习其分数函数,这正是**分数匹配**的核心思想。 70 | 71 | ### C.2.3 分数函数作为“力场” 72 | 73 | 我们可以从物理学的角度,为分数函数建立一个非常直观的力学类比。 74 | 75 | > **定义 C.4 (能量函数与力)** 76 | > 给定一个概率分布 `p(x)`,我们可以定义一个对应的**能量函数**(或势能): 77 | > 78 | 79 | $$E(x) = -\log p(x)$$ 80 | > 那么,分数函数就变成了作用在粒子上的**力**: 81 | > 82 | 83 | $$F(x) = -\nabla E(x) = \nabla \log p(x)$$ 84 | 85 | 这是一个**保守力场**,因为它是一个标量势 `E(x)` 的梯度。 86 | 87 | **物理图像**: 88 | - **高概率区域** (`p(x)` 大) ⇔ **低能量区域** (`E(x)` 小)。 89 | - 粒子会受到一个力的作用,将它从高能量区域(低概率)推向低能量区域(高概率)。 90 | - 概率分布的模式(modes)对应于能量景观的**势阱**(potential wells)。 91 | 92 | ### C.2.4 Langevin动力学 93 | 94 | Langevin动力学描述了粒子在这个力场中,同时受到随机热噪声影响时的运动轨迹。 95 | 96 | > **定义 C.5 (Langevin SDE)** 97 | > 98 | 99 | $$dX_t = \nabla \log p(X_t) dt + \sqrt{2} dW_t$$ 100 | > - **漂移项 `∇log p(X_t)dt`**: 粒子受到分数“力”的作用,确定性地向能量更低处移动。 101 | > - **扩散项 `sqrt(2)dW_t`**: 粒子受到随机布朗运动的扰动,使其能够探索整个能量景观,而不是仅仅陷入最近的势阱。 102 | 103 | 🌟 **核心联系**:Langevin动力学的稳态分布恰好是 `p(x)`。这意味着,无论从什么初始状态开始,只要我们模拟这个SDE足够长的时间,最终得到的粒子分布就会收敛到我们想要的目标分布 `p(x)`。这为从概率分布中采样提供了一个基于物理模拟的强大方法。 104 | 105 | **扩散模型中的应用**: 106 | - **前向过程**:可以看作是一个能量景观逐渐被“抚平”的过程。`E_0(x) = -log p_data(x)` 是一个复杂、多势阱的崎岖景观,而 `E_T(x) ≈ ||x||^2 / 2` 是一个简单的、单一的抛物线势阱。 107 | - **反向过程**:学习反向SDE `dx = [f - g^2 * s_θ]dt + g d(bar(W)_t)`,本质上是在学习一个时变的力场 `s_θ(x, t)`,这个力场可以在每个时刻 `t` 将粒子有效地引导回数据所在的高概率区域。 108 | 109 |
110 | 综合练习:一维双势阱模型 111 | 112 | 考虑一个一维能量函数 `E(x) = (x^2 - 1)^2`,它在 `x=-1` 和 `x=1` 处有两个势阱。 113 | 1. **概率分布**:写出对应的概率分布 `p(x) ∝ exp(-E(x))` 的表达式。 114 | 2. **分数函数/力**:计算其分数函数 `s(x) = ∇log p(x)`。分析在 `x=0`(势垒)和 `x=-1, 1`(势阱)附近,这个“力”的方向和大小。 115 | 3. **Langevin动力学**:写出对应的Langevin SDE。如果一个粒子从 `x=0` 开始,它的长期行为会是怎样的? 116 | 4. **开放探索**:在扩散模型中,我们学习的是一个时变的分数函数 `s_θ(x, t)`。对于这个双势阱例子,`s_θ(x, t)` 在 `t` 接近 `T`(高噪声)和 `t` 接近 `0`(低噪声)时,其形状应该分别是什么样的? 117 | 118 | **解答思路**: 119 | 1. `p(x) = (1/Z) * exp(-(x^2 - 1)^2)`,`Z`是归一化常数。 120 | 2. `s(x) = -dE/dx = -2(x^2 - 1)(2x) = -4x(x^2 - 1)`。在 `x=0`,`s(0)=0`,但这是一个不稳定的平衡点。在 `x=-1, 1`,`s(x)=0`,是稳定的平衡点。在 `x` 略大于0时,`s(x)<0`,力指向左边;略小于0时,`s(x)>0`,力指向右边,因此粒子会被推离 `x=0`。 121 | 3. `dX_t = -4X_t(X_t^2 - 1)dt + sqrt(2)dW_t`。长期来看,粒子会在两个势阱 `x=-1` 和 `x=1` 之间来回跳跃,其最终分布会收敛到 `p(x)`。 122 | 4. 当 `t` 接近 `T` 时,能量景观被抚平,`s_θ(x, t)` 应该接近于一个单势阱(高斯分布)的分数函数,即 `s ≈ -x`。当 `t` 接近 `0` 时,`s_θ(x, t)` 应该精确地逼近我们计算出的 `s(x) = -4x(x^2 - 1)`,以恢复双峰结构。 123 | 124 |
125 | -------------------------------------------------------------------------------- /appendix-a.md: -------------------------------------------------------------------------------- 1 | [← 返回目录](index.md) | 附录A | [附录B →](appendix-b.md) 2 | 3 | # 附录A:测度论与随机过程速成 4 | 5 | 本附录为理解第5章(连续时间扩散模型)提供必要的数学基础。我们将快速回顾测度论的核心概念,介绍布朗运动和随机微分方程(SDE)的基本知识。这不是一门完整的数学课程,而是为理解扩散模型所需的最小知识集,旨在建立直觉并熟悉核心工具。 6 | 7 | ## A.1 测度论基础 8 | 9 | ### A.1.1 为什么需要测度论? 10 | 11 | 让我们从一个简单但深刻的问题开始:**在区间[0,1]上随机选一个点,这个点恰好是有理数的概率是多少?** 12 | 13 | 直觉可能会说:“有理数有无穷多个,所以概率应该不为零。”但实际上,这个概率是0。这个反直觉的结果揭示了我们需要一个比传统集合论更精细的数学框架来处理“无穷”。测度论正是为此而生,它严格定义了“长度”、“面积”、“体积”乃至“概率”等概念。 14 | 15 | ### A.1.2 σ-代数与测度 16 | 17 | - **σ-代数 (σ-algebra)**: 在一个样本空间 `Ω` 中,并非所有子集都能被合理地赋予概率。σ-代数 `F` 是 `Ω` 的一个子集族,它包含了我们所有感兴趣的“事件”,并对补、可数并等运算封闭。 18 | - **测度 (Measure)**: 测度 `μ` 是一个定义在σ-代数 `F` 上的函数,它为每个事件赋予一个非负的“大小”。当 `μ(Ω) = 1` 时,这个测度就是一个**概率测度** `P`。 19 | 20 | > **定义 A.1 (概率空间)** 21 | > 一个概率空间是一个三元组 `(Ω, F, P)`,其中: 22 | > - `Ω` 是样本空间(所有可能结果的集合)。 23 | > - `F` 是 `Ω` 上的一个σ-代数(所有可测事件的集合)。 24 | > - `P` 是定义在 `F` 上的一个概率测度。 25 | 26 | 💡 **关键洞察**:有理数集的勒贝格测度(长度)为0,是因为虽然有理数是可数无穷的,但每个单点的测度都是0。根据测度的可数可加性,可数个0相加仍然是0。 27 | 28 | ### A.1.3 随机变量与条件期望 29 | 30 | - **随机变量 (Random Variable)**: 一个随机变量 `X` 是一个从样本空间 `Ω` 到实数 `R` 的函数,它必须是“可测的”,即对于任何数值区间,我们都能找到其在样本空间中对应的事件。 31 | - **滤波 (Filtration)**: 滤波 `{F_t}` 是一个随时间 `t` 递增的σ-代数序列,`F_s ⊆ F_t` 对所有 `s ≤ t` 成立。它代表了信息的累积过程,`F_t` 包含了到时刻 `t` 为止所有已知的信息。 32 | - **条件期望 (Conditional Expectation)**: `E[X | F_t]` 代表在已知时刻 `t` 信息 `F_t` 的情况下,对随机变量 `X` 的最优估计。 33 | 34 |
35 | **练习 A.1:σ-代数** 36 | 37 | 设 `Ω = {1, 2, 3, 4}`。 38 | 1. 构造包含事件 `A = {1, 2}` 的最小σ-代数 `σ(A)`。 39 | 2. 如果再加入事件 `B = {2, 3}`,最小σ-代数 `σ(A, B)` 是什么? 40 | 41 | **解答:** 42 | 1. `σ(A)` 必须对补运算封闭,所以必须包含 `A^c = {3, 4}`。同时必须包含全集和空集。因此 `σ(A) = {∅, {1, 2}, {3, 4}, {1, 2, 3, 4}}`。 43 | 2. `σ(A, B)` 必须包含 `A` 和 `B`,以及它们的所有交、并、补运算的组合。例如 `A ∩ B = {2}`,`A ∪ B = {1, 2, 3}`,`(A ∪ B)^c = {4}` 等。最终可以生成 `Ω` 的幂集(所有16个子集)。 44 | 45 |
46 | 47 | ## A.2 布朗运动 (Brownian Motion) 48 | 49 | 布朗运动是随机过程理论的基石,也是扩散模型的数学核心。 50 | 51 | > **定义 A.2 (标准布朗运动)** 52 | > 一个随机过程 `{B_t}` 称为标准布朗运动(或维纳过程),如果: 53 | > 1. **起点确定**: `B_0 = 0`。 54 | > 2. **独立增量**: 对任意 `0 ≤ s < t`,增量 `B_t - B_s` 独立于过去的路径 `{B_u : u ≤ s}`。 55 | > 3. **高斯增量**: `B_t - B_s` 服从均值为0,方差为 `t-s` 的正态分布,即 `B_t - B_s ~ N(0, t-s)`。 56 | > 4. **路径连续**: 路径 `t ↦ B_t` 是连续函数。 57 | 58 | **布朗运动的深刻性质**: 59 | - **无处可微**: 布朗运动的路径虽然连续,但在任何一点都是不可微的。它的“速度”是无穷的。 60 | - **二次变差非零**: 在普通微积分中 `(dt)^2 = 0`,但在随机微积分中,`(dB_t)^2 = dt`。这是两者最核心的区别,也是伊藤公式中出现修正项的根源。 61 | - **鞅 (Martingale)**: 布朗运动是一个鞅,即 `E[B_t | F_s] = B_s` for `s < t`。这意味着对未来的最优预测就是当前的值。 62 | 63 | ## A.3 随机积分与伊藤公式 64 | 65 | 由于布朗运动的奇异性质,传统的黎曼积分不适用。我们需要一种新的积分理论——随机积分。 66 | 67 | ### A.3.1 伊藤积分 (Itô Integral) 68 | 69 | 伊藤积分 `∫f_s dB_s` 的定义在黎曼和中,总是取被积函数在区间的**左端点**的值。这个选择保证了被积函数 `f_s` 不会“预见”到噪声 `dB_s` 的未来,从而使得积分结果仍然是一个鞅。 70 | 71 | ⚡ **理论要点**:伊藤积分和另一种常见的斯特拉托诺维奇(Stratonovich)积分(取中点)会导致不同的结果。物理学中常用后者,因为它遵循普通的链式法则。金融和概率论中常用前者,因为它具有鞅性质。扩散模型理论建立在伊藤积分之上。 72 | 73 | ### A.3.2 伊藤公式 (Itô's Formula) 74 | 75 | 伊藤公式是随机微积分的链式法则,是处理SDE最重要的工具。 76 | 77 | > **定理 A.3 (伊藤公式)** 78 | > 设 `X_t` 满足SDE `dX_t = μ_t dt + σ_t dB_t`,`f(x, t)` 是一个足够光滑的函数,则: 79 | > 80 | 81 | $$df(X_t, t) = \left(\frac{\partial f}{\partial t} + \mu_t \frac{\partial f}{\partial x} + \frac{1}{2}\sigma_t^2 \frac{\partial^2 f}{\partial x^2}\right)dt + \sigma_t \frac{\partial f}{\partial x} dB_t$$ 82 | > 核心区别在于比普通链式法则多出的一项:`1/2 * σ_t^2 * ∂^2f/∂x^2`,这被称为**伊藤修正项**,它正是来源于 `(dB_t)^2 = dt`。 83 | 84 |
85 | **练习 A.2:伊藤公式的应用** 86 | 87 | 1. **推导**:设 `B_t` 是标准布朗运动,使用伊藤公式计算 `d(B_t^3)`。 88 | 2. **证明**:证明 `M_t = exp(B_t - t/2)` 是一个鞅。 89 | 3. **研究思路**: 90 | * **问题1**:对 `f(x) = x^3` 应用伊藤公式,其中 `μ_t=0, σ_t=1`。`df = (1/2 * 1^2 * 6B_t)dt + (3B_t^2 * 1)dB_t = 3B_t dt + 3B_t^2 dB_t`。 91 | * **问题2**:对 `f(x,t) = exp(x - t/2)` 应用伊藤公式。`df = (-1/2 * f)dt + (0)dt + (1/2 * 1^2 * f)dt + (f * 1)dB_t = f dB_t`。由于结果的 `dt` 项(漂移项)为0,所以它是一个鞅。 92 | 93 |
94 | 95 | ## A.4 随机微分方程 (SDEs) 96 | 97 | SDE描述了受随机扰动影响的动态系统,是扩散模型的数学语言。 98 | 99 | > **定义 A.4 (SDE)** 100 | > 一个典型的SDE具有形式: 101 | > 102 | 103 | $$dX_t = b(X_t, t)dt + \sigma(X_t, t)dB_t$$ 104 | > - **漂移项 `b(X_t, t)`**: 描述系统的确定性平均行为。 105 | > - **扩散项 `σ(X_t, t)`**: 描述随机波动的强度。 106 | 107 | **存在唯一性**:如果漂移和扩散系数满足Lipschitz连续性和线性增长条件,那么SDE存在唯一的强解。这保证了我们讨论的扩散过程是良定义的。 108 | 109 | ## A.5 数值方法简介 110 | 111 | 大多数SDE没有解析解,需要数值方法来模拟。 112 | 113 | - **Euler-Maruyama方法**: 最简单的数值格式,直接将SDE离散化: 114 | `X_{n+1} = X_n + b(X_n)Δt + σ(X_n) * sqrt(Δt) * Z_n`,其中 `Z_n ~ N(0, 1)`。 115 | - **Milstein方法**: 更高阶的方法,通过加入一个修正项来获得更高的收敛精度,特别是当扩散系数 `σ` 不为常数时。 116 | 117 | 💡 **实践洞察**:数值模拟显示,对于扩散系数依赖于状态 `X_t` 的SDE(例如金融中的一些模型),Milstein方法比Euler-Maruyama方法能更精确地收敛到真实解。对于扩散模型中常见的 `σ` 只依赖于时间 `t` 的情况,两种方法的差别不大。 118 | 119 | ## A.6 与扩散模型的深层联系 120 | 121 | 现在,我们可以将这些数学工具与扩散模型联系起来。 122 | 123 | ### A.6.1 前向与反向SDE 124 | 125 | - **前向SDE**: 精心设计的、将数据 `x_0` 转化为噪声 `x_T` 的过程。例如VP-SDE: 126 | `dx = -1/2 * β(t) * x dt + sqrt(β(t)) * dB_t` 127 | - **反向SDE**: Anderson定理告诉我们,存在一个对应的反向过程,其漂移项必须由分数函数 `∇log p_t(x)` 来修正: 128 | `dx = [f(x, t) - g(t)^2 * ∇log p_t(x)] dt + g(t) d(bar(W)_t)` 129 | 这揭示了**学习生成模型等价于学习分数函数**。 130 | 131 | ### A.6.2 概率流ODE 132 | 133 | - 每个SDE都对应一个确定性的ODE,称为概率流ODE,它描述了概率密度的平均流动方向: 134 | `dx = [f(x, t) - 1/2 * g(t)^2 * ∇log p_t(x)] dt` 135 | - 由于没有随机项,可以使用高效的ODE数值求解器进行快速、确定性的采样。这是DDIM等快速采样算法的理论基础。 136 | 137 | ### A.6.3 Fokker-Planck方程 138 | 139 | - 这是一个偏微分方程(PDE),它从宏观上描述了概率密度 `p(x, t)` 随时间的演化。 140 | - 它将微观的粒子运动(SDE)与宏观的密度变化(PDE)联系起来,是进行理论分析的强大工具。 141 | 142 |
143 | **综合练习:统一视角** 144 | 145 | 考虑一个简单的一维Ornstein-Uhlenbeck过程:`dX_t = -θX_t dt + σdB_t`。 146 | 1. **稳态分布**:使用Fokker-Planck方程,证明其稳态分布为 `N(0, σ^2/(2θ))`。 147 | 2. **分数函数**:写出其稳态分布的分数函数。 148 | 3. **反向SDE**:写出在稳态下的反向SDE。 149 | 4. **概率流ODE**:写出在稳态下的概率流ODE。 150 | 151 | **解答思路**: 152 | 1. 在Fokker-Planck方程中令 `∂p/∂t = 0`,得到一个关于 `p(x)` 的常微分方程,求解可得高斯分布。 153 | 2. 对于高斯分布 `N(μ, Σ^2)`,分数函数为 `-(x-μ)/Σ^2`。 154 | 3. 将分数函数代入Anderson定理的公式。 155 | 4. 将分数函数代入概率流ODE的公式。你会发现,在稳态下,ODE的漂移项恰好是前向SDE漂移项的两倍。 156 | 157 |
158 | 159 | ## A.7 进一步学习资源 160 | 161 | - **Øksendal, B. "Stochastic Differential Equations"**: SDE的经典入门教材,理论与应用并重。 162 | - **Evans, L.C. "An Introduction to Stochastic Differential Equations"**: 更侧重于PDE方法的SDE介绍,适合数学背景较强的读者。 163 | - **Särkkä, S., & Solin, A. "Applied Stochastic Differential Equations"**: 侧重于数值方法和实际应用的优秀书籍。 164 | -------------------------------------------------------------------------------- /add_latex_spaces.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """Add spaces around single dollar LaTeX expressions and ensure newlines before $$ blocks in markdown files.""" 3 | 4 | import re 5 | import sys 6 | 7 | def add_spaces_around_latex(content, escape_underscores=False): 8 | """Add spaces around single dollar LaTeX expressions and ensure newline before $$ blocks. 9 | 10 | Examples: 11 | "我$a+b$," -> "我 $a+b$ ," 12 | "其中$x$是" -> "其中 $x$ 是" 13 | "文字$$公式$$" -> "文字\n$$公式$$" 14 | 15 | If escape_underscores=True, also escapes underscores in LaTeX contexts: 16 | "$x_i$" -> "$x\\_i$" 17 | """ 18 | # First, handle $$ blocks - ensure newline before starting $$ 19 | # New approach: Find all $$ positions and process them correctly 20 | # We need to identify which $$ are starts and which are ends 21 | 22 | result = content 23 | 24 | # Find all $$ positions 25 | dollar_positions = [] 26 | i = 0 27 | while i < len(result) - 1: 28 | if result[i:i+2] == '$$': 29 | dollar_positions.append(i) 30 | i += 2 31 | else: 32 | i += 1 33 | 34 | # Process $$ pairs from right to left (to avoid position shifts) 35 | # Every odd-indexed $$ is a start, even-indexed is an end 36 | for idx in range(len(dollar_positions) - 1, -1, -1): 37 | if idx % 2 == 0: # This is a start $$ 38 | pos = dollar_positions[idx] 39 | # Check if there's a newline before this $$ 40 | if pos > 0 and result[pos-1] != '\n': 41 | # Insert newline before $$ 42 | result = result[:pos] + '\n' + result[pos:] 43 | 44 | # Now handle single $ inline math 45 | # Pattern to match single dollar signs with content between them 46 | # Negative lookbehind and lookahead to avoid matching double dollars 47 | pattern = r'(? 0 else '' 57 | after_char = result[end_pos] if end_pos < len(result) else '' 58 | 59 | # Build replacement with appropriate spaces 60 | latex_expr = match.group(0) 61 | replacement = latex_expr 62 | 63 | # Add space before if needed 64 | if before_char and before_char not in ' \n\t': 65 | replacement = ' ' + replacement 66 | 67 | # Add space after if needed 68 | if after_char and after_char not in ' \n\t': 69 | replacement = replacement + ' ' 70 | 71 | # Replace in result 72 | result = result[:start_pos] + replacement + result[end_pos:] 73 | 74 | # Optionally escape underscores within LaTeX contexts 75 | if escape_underscores: 76 | # First, handle display math blocks $$...$$ 77 | display_blocks = [] 78 | i = 0 79 | while i < len(result) - 1: 80 | if result[i:i+2] == '$$': 81 | start = i 82 | i += 2 83 | # Find the closing $$ 84 | while i < len(result) - 1: 85 | if result[i:i+2] == '$$': 86 | end = i + 2 87 | display_blocks.append((start, end)) 88 | i += 2 89 | break 90 | i += 1 91 | else: 92 | i += 1 93 | 94 | # Process display blocks from end to beginning to avoid position shifts 95 | for start, end in reversed(display_blocks): 96 | block_content = result[start+2:end-2] 97 | # Replace unescaped underscores 98 | escaped_content = re.sub(r'(? 2 | 3 | 4 | 5 | 6 | 7 | 扩散模型教程项目状态 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

扩散模型教程项目状态

199 |

项目完成情况

200 |

✅ 已完成的任务

201 |
    202 |
  1. 203 |

    章节编写(14章全部完成) 204 | - 第1章:扩散模型导论 205 | - 第2章:神经网络架构:U-Net与ViT 206 | - 第3章:去噪扩散概率模型 (DDPM) 207 | - 第4章:基于分数的生成模型 208 | - 第5章:连续时间扩散模型 (PDE/SDE) 209 | - 第6章:流匹配 (Flow Matching) 210 | - 第7章:扩散Transformer (DiT) 211 | - 第8章:采样算法与加速技术 212 | - 第9章:条件生成与引导技术 213 | - 第10章:潜在扩散模型 (LDM) 214 | - 第11章:视频扩散模型 215 | - 第12章:文本扩散模型 216 | - 第13章:扩散模型的应用 217 | - 第14章:前沿研究与未来方向

    218 |
  2. 219 |
  3. 220 |

    代码块移除 221 | - 所有Python代码块已成功移除 222 | - 代码内容已转换为数学公式和文字描述 223 | - 使用自动化脚本 remove_code_blocks.py 处理

    224 |
  4. 225 |
  5. 226 |

    LaTeX格式优化 227 | - 创建并优化了 add_latex_spaces.py 脚本 228 | - 确保单个 $ 的行内公式有适当空格 229 | - 确保

    230 |
  6. 231 |
232 |

$$ 的显示公式前有换行

233 |
    234 |
  1. 项目文件完善 235 | - 更新了 index.md,标记所有章节为已完成 236 | - 创建了验证脚本 validate_tutorial.py 237 | - 所有章节包含丰富的练习题和研究线索
  2. 238 |
239 |

教程特色

240 |
    241 |
  1. 242 |

    由浅入深的结构设计 243 | - 从基础概念逐步过渡到前沿研究 244 | - 每章都有清晰的学习目标和章节大纲

    245 |
  2. 246 |
  3. 247 |

    大量习题和参考答案 248 | - 每个重要概念都配有练习题 249 | - 练习题包含理论推导和实践任务 250 | - 答案使用 <details markdown="1"> 标签默认折叠

    251 |
  4. 252 |
  5. 253 |

    丰富的研究线索 254 | - 使用 🔬 和 🌟 标记研究方向 255 | - 提供开放性问题供深入探索 256 | - 连接相关的数学理论和前沿论文

    257 |
  6. 258 |
  7. 259 |

    数学严谨性 260 | - 使用LaTeX格式的数学公式 261 | - 提供完整的推导过程 262 | - 平衡直观理解和理论深度

    263 |
  8. 264 |
265 |

统计信息

266 |
    267 |
  • 总行数:8,045行
  • 268 |
  • 总字符数:155,944字符
  • 269 |
  • 平均每章:574行,11,138字符
  • 270 |
  • 最长章节:第14章(1,292行)
  • 271 |
  • 最短章节:第5章(115行)
  • 272 |
273 |

待完成项目(可选)

274 |
    275 |
  1. 276 |

    附录编写 277 | - 附录A:测度论与随机过程速成 278 | - 附录B:倒向随机微分方程 (BSDE) 速成

    279 |
  2. 280 |
  3. 281 |

    交互式元素 282 | - 可以添加可视化demo链接 283 | - 集成Jupyter notebook示例

    284 |
  4. 285 |
  5. 286 |

    进一步优化 287 | - 添加章节间的交叉引用 288 | - 创建术语表和索引 289 | - 设计统一的练习题难度标记系统

    290 |
  6. 291 |
292 |

使用建议

293 |
    294 |
  1. 295 |

    阅读顺序 296 | - 初学者:按章节顺序阅读 297 | - 有基础者:可以跳过前3章 298 | - 研究者:重点关注5-7章和14章

    299 |
  2. 300 |
  3. 301 |

    练习策略 302 | - 每章至少完成一个练习题 303 | - 尝试拓展练习中的研究问题 304 | - 记录自己的理解和疑问

    305 |
  4. 306 |
  5. 307 |

    深入学习 308 | - 跟随研究线索查阅相关论文 309 | - 实现简化版本的算法 310 | - 参与开源项目实践

    311 |
  6. 312 |
313 |

项目维护

314 |
    315 |
  • 定期更新最新研究进展
  • 316 |
  • 收集读者反馈改进内容
  • 317 |
  • 添加更多实际应用案例
  • 318 |
  • 保持数学符号的一致性
  • 319 |
320 |
321 |

最后更新:2025-07-27

322 |
323 | 324 | 325 |
326 |
327 | 328 | -------------------------------------------------------------------------------- /html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 扩散模型教程 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

扩散模型教程

199 |

Diffusion Models: From Theory to Practice

200 |

欢迎来到扩散模型教程!本教程将带你从基础理论逐步深入到实际应用,帮助你全面理解和掌握扩散模型这一强大的生成模型技术。

201 |

每个章节包含:

202 |
    203 |
  • 理论基础与数学推导
  • 204 |
  • 可视化演示和交互式示例
  • 205 |
  • 编程练习与实践项目
  • 206 |
  • 习题与参考答案(默认折叠)
  • 207 |
208 |

前置知识要求

209 |

本教程假设读者已具备以下基础知识:

210 |
    211 |
  • 概率论与统计:随机变量、概率分布、期望、方差、贝叶斯定理
  • 212 |
  • 线性代数:矩阵运算、特征值分解、向量空间
  • 213 |
  • 微积分:多元微积分、偏导数、链式法则、泰勒展开
  • 214 |
  • 深度学习基础:神经网络、反向传播、卷积网络、Transformer
  • 215 |
  • PyTorch 编程:张量操作、自动微分、模型训练流程
  • 216 |
217 |

如果对某些概念不熟悉,建议先补充相关知识再开始学习。附录部分提供了部分高级数学概念的速成指南。

218 |

课程章节

219 |

第1章:扩散模型导论

220 |

已完成

221 |

介绍扩散模型的基本概念、历史发展、与其他生成模型的比较,以及前向扩散过程的数学基础。

222 |

第2章:神经网络架构:U-Net与ViT

223 |

已完成

224 |

探索去噪网络的历史发展,从医学图像分割到生成模型,深入理解U-Net架构演进和Vision Transformer的崛起。

225 |

第3章:去噪扩散概率模型 (DDPM)

226 |

已完成

227 |

深入理解DDPM的核心原理,包括前向过程、反向过程、变分下界推导、训练算法和完整实现。

228 |

第4章:基于分数的生成模型

229 |

已完成

230 |

探索score matching和Langevin dynamics,理解扩散模型与分数函数的深层联系。

231 |

第5章:连续时间扩散模型 (PDE/SDE)

232 |

已完成

233 |

从随机微分方程(SDE)和偏微分方程(PDE)角度理解扩散模型,包括概率流ODE、Fokker-Planck方程等连续时间框架。

234 |

第6章:流匹配 (Flow Matching)

235 |

已完成

236 |

连续正则化流、最优传输视角、与扩散模型的联系。

237 |

第7章:扩散Transformer (DiT)

238 |

已完成

239 |

Diffusion Transformer架构、与U-Net的对比、可扩展性分析。

240 |

第8章:采样算法与加速技术

241 |

已完成

242 |

学习DDIM、DPM-Solver等快速采样方法,以及如何优化生成质量与速度的平衡。

243 |

第9章:条件生成与引导技术

244 |

已完成

245 |

掌握classifier guidance、classifier-free guidance等条件生成技术,实现可控生成。

246 |

第10章:潜在扩散模型 (LDM)

247 |

已完成

248 |

理解Stable Diffusion的架构,学习如何在潜在空间中进行高效的扩散建模。

249 |

第11章:视频扩散模型

250 |

已完成

251 |

时序建模、3D U-Net、视频生成的挑战与方法。

252 |

第12章:文本扩散模型

253 |

已完成

254 |

探索离散域上的扩散模型,包括D3PM、Diffusion-LM等文本生成方法,以及embedding空间的扩散技术。

255 |

第13章:扩散模型的应用

256 |

已完成

257 |

探索图像生成、图像编辑、超分辨率、3D生成等实际应用场景。

258 |

第14章:前沿研究与未来方向

259 |

已完成

260 |

了解最新研究进展,包括一致性模型、扩散模型的未来发展趋势。

261 |

附录

262 |

附录A:测度论与随机过程速成

263 |

已完成

264 |

为第5章PDE/SDE内容提供数学基础,包括σ-代数、测度、布朗运动等核心概念。

265 |

附录B:倒向随机微分方程 (BSDE) 速成

266 |

已完成

267 |

理解扩散模型反向过程的数学工具,包括BSDE基本理论、Feynman-Kac公式等。

268 |

附录C:信息几何与分数函数的力学解释

269 |

已完成

270 |

从信息几何角度理解扩散模型,揭示分数函数作为"力"的物理意义,建立与能量优化的联系。

271 |
272 | 273 | 274 |
275 |
276 | 277 | -------------------------------------------------------------------------------- /html/README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 扩散模型教程 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

扩散模型教程

199 |

Diffusion Models: From Theory to Practice

200 |

欢迎来到扩散模型教程!本教程将带你从基础理论逐步深入到实际应用,帮助你全面理解和掌握扩散模型这一强大的生成模型技术。

201 |

每个章节包含:

202 |
    203 |
  • 理论基础与数学推导
  • 204 |
  • 可视化演示和交互式示例
  • 205 |
  • 编程练习与实践项目
  • 206 |
  • 习题与参考答案(默认折叠)
  • 207 |
208 |

前置知识要求

209 |

本教程假设读者已具备以下基础知识:

210 |
    211 |
  • 概率论与统计:随机变量、概率分布、期望、方差、贝叶斯定理
  • 212 |
  • 线性代数:矩阵运算、特征值分解、向量空间
  • 213 |
  • 微积分:多元微积分、偏导数、链式法则、泰勒展开
  • 214 |
  • 深度学习基础:神经网络、反向传播、卷积网络、Transformer
  • 215 |
  • PyTorch 编程:张量操作、自动微分、模型训练流程
  • 216 |
217 |

如果对某些概念不熟悉,建议先补充相关知识再开始学习。附录部分提供了部分高级数学概念的速成指南。

218 |

课程章节

219 |

第1章:扩散模型导论

220 |

已完成

221 |

介绍扩散模型的基本概念、历史发展、与其他生成模型的比较,以及前向扩散过程的数学基础。

222 |

第2章:神经网络架构:U-Net与ViT

223 |

已完成

224 |

探索去噪网络的历史发展,从医学图像分割到生成模型,深入理解U-Net架构演进和Vision Transformer的崛起。

225 |

第3章:去噪扩散概率模型 (DDPM)

226 |

已完成

227 |

深入理解DDPM的核心原理,包括前向过程、反向过程、变分下界推导、训练算法和完整实现。

228 |

第4章:基于分数的生成模型

229 |

已完成

230 |

探索score matching和Langevin dynamics,理解扩散模型与分数函数的深层联系。

231 |

第5章:连续时间扩散模型 (PDE/SDE)

232 |

已完成

233 |

从随机微分方程(SDE)和偏微分方程(PDE)角度理解扩散模型,包括概率流ODE、Fokker-Planck方程等连续时间框架。

234 |

第6章:流匹配 (Flow Matching)

235 |

已完成

236 |

连续正则化流、最优传输视角、与扩散模型的联系。

237 |

第7章:扩散Transformer (DiT)

238 |

已完成

239 |

Diffusion Transformer架构、与U-Net的对比、可扩展性分析。

240 |

第8章:采样算法与加速技术

241 |

已完成

242 |

学习DDIM、DPM-Solver等快速采样方法,以及如何优化生成质量与速度的平衡。

243 |

第9章:条件生成与引导技术

244 |

已完成

245 |

掌握classifier guidance、classifier-free guidance等条件生成技术,实现可控生成。

246 |

第10章:潜在扩散模型 (LDM)

247 |

已完成

248 |

理解Stable Diffusion的架构,学习如何在潜在空间中进行高效的扩散建模。

249 |

第11章:视频扩散模型

250 |

已完成

251 |

时序建模、3D U-Net、视频生成的挑战与方法。

252 |

第12章:文本扩散模型

253 |

已完成

254 |

探索离散域上的扩散模型,包括D3PM、Diffusion-LM等文本生成方法,以及embedding空间的扩散技术。

255 |

第13章:扩散模型的应用

256 |

已完成

257 |

探索图像生成、图像编辑、超分辨率、3D生成等实际应用场景。

258 |

第14章:前沿研究与未来方向

259 |

已完成

260 |

了解最新研究进展,包括一致性模型、扩散模型的未来发展趋势。

261 |

附录

262 |

附录A:测度论与随机过程速成

263 |

已完成

264 |

为第5章PDE/SDE内容提供数学基础,包括σ-代数、测度、布朗运动等核心概念。

265 |

附录B:倒向随机微分方程 (BSDE) 速成

266 |

已完成

267 |

理解扩散模型反向过程的数学工具,包括BSDE基本理论、Feynman-Kac公式等。

268 |

附录C:信息几何与分数函数的力学解释

269 |

已完成

270 |

从信息几何角度理解扩散模型,揭示分数函数作为"力"的物理意义,建立与能量优化的联系。

271 |
272 | 273 | 274 |
275 |
276 | 277 | -------------------------------------------------------------------------------- /html/assets/script.js: -------------------------------------------------------------------------------- 1 | // Sidebar toggle for mobile 2 | document.addEventListener('DOMContentLoaded', function() { 3 | const sidebar = document.getElementById('sidebar'); 4 | const sidebarToggle = document.getElementById('sidebar-toggle'); 5 | 6 | if (sidebarToggle) { 7 | sidebarToggle.addEventListener('click', function() { 8 | sidebar.classList.toggle('active'); 9 | }); 10 | } 11 | 12 | // Close sidebar when clicking outside on mobile 13 | document.addEventListener('click', function(event) { 14 | const isClickInside = sidebar.contains(event.target); 15 | const isToggleClick = sidebarToggle.contains(event.target); 16 | 17 | if (!isClickInside && !isToggleClick && sidebar.classList.contains('active')) { 18 | sidebar.classList.remove('active'); 19 | } 20 | }); 21 | 22 | // Smooth scrolling for anchor links 23 | document.querySelectorAll('a[href^="#"]').forEach(anchor => { 24 | anchor.addEventListener('click', function (e) { 25 | e.preventDefault(); 26 | const target = document.querySelector(this.getAttribute('href')); 27 | if (target) { 28 | target.scrollIntoView({ 29 | behavior: 'smooth', 30 | block: 'start' 31 | }); 32 | } 33 | }); 34 | }); 35 | 36 | // Pure CSS Tree Navigation 37 | const treeNav = document.querySelector('.tree-nav'); 38 | if (treeNav) { 39 | const TREE_STATE_KEY = 'tree-nav-state'; 40 | 41 | // Load saved state 42 | function loadTreeState() { 43 | try { 44 | const saved = localStorage.getItem(TREE_STATE_KEY); 45 | return saved ? JSON.parse(saved) : {}; 46 | } catch (e) { 47 | return {}; 48 | } 49 | } 50 | 51 | // Save tree state 52 | function saveTreeState() { 53 | const state = {}; 54 | document.querySelectorAll('.tree-folder').forEach(folder => { 55 | const header = folder.querySelector('.tree-folder-header'); 56 | if (header) { 57 | const title = header.querySelector('.tree-title'); 58 | if (title) { 59 | const folderPath = title.textContent.trim(); 60 | state[folderPath] = folder.classList.contains('expanded'); 61 | } 62 | } 63 | }); 64 | try { 65 | localStorage.setItem(TREE_STATE_KEY, JSON.stringify(state)); 66 | } catch (e) { 67 | // Ignore localStorage errors 68 | } 69 | } 70 | 71 | // Apply saved state 72 | function applyTreeState() { 73 | const state = loadTreeState(); 74 | document.querySelectorAll('.tree-folder').forEach(folder => { 75 | const header = folder.querySelector('.tree-folder-header'); 76 | if (header) { 77 | const title = header.querySelector('.tree-title'); 78 | if (title) { 79 | const folderPath = title.textContent.trim(); 80 | // Check if folder contains active item 81 | const hasActive = folder.querySelector('.tree-item.active'); 82 | 83 | if (hasActive) { 84 | // Always expand folders containing active items 85 | folder.classList.add('expanded'); 86 | } else if (state[folderPath] !== undefined) { 87 | // Apply saved state for other folders 88 | if (state[folderPath]) { 89 | folder.classList.add('expanded'); 90 | } else { 91 | folder.classList.remove('expanded'); 92 | } 93 | } 94 | } 95 | } 96 | }); 97 | } 98 | 99 | // Initialize state on page load 100 | setTimeout(() => { 101 | applyTreeState(); 102 | }, 0); 103 | 104 | // Handle folder clicks 105 | document.querySelectorAll('.tree-folder-header').forEach(header => { 106 | header.addEventListener('click', function(e) { 107 | e.preventDefault(); 108 | const folder = this.parentElement; 109 | folder.classList.toggle('expanded'); 110 | saveTreeState(); 111 | }); 112 | }); 113 | 114 | // Search functionality 115 | const searchInput = document.getElementById('sidebar-search-input'); 116 | if (searchInput) { 117 | let searchTimeout; 118 | 119 | function performTreeSearch() { 120 | const query = searchInput.value.toLowerCase().trim(); 121 | const items = document.querySelectorAll('.tree-item'); 122 | const folders = document.querySelectorAll('.tree-folder'); 123 | 124 | // Clear previous matches 125 | document.querySelectorAll('.search-match').forEach(el => { 126 | el.classList.remove('search-match'); 127 | }); 128 | 129 | if (!query) { 130 | // Show all items 131 | items.forEach(item => item.style.display = ''); 132 | folders.forEach(folder => folder.style.display = ''); 133 | applyTreeState(); 134 | return; 135 | } 136 | 137 | // Search and highlight 138 | let hasResults = false; 139 | items.forEach(item => { 140 | const title = item.querySelector('.tree-title').textContent.toLowerCase(); 141 | if (title.includes(query)) { 142 | item.style.display = ''; 143 | item.classList.add('search-match'); 144 | hasResults = true; 145 | 146 | // Expand parent folders 147 | let parent = item.parentElement; 148 | while (parent && parent !== treeNav) { 149 | if (parent.classList.contains('tree-folder')) { 150 | parent.classList.add('expanded'); 151 | parent.style.display = ''; 152 | } 153 | parent = parent.parentElement; 154 | } 155 | } else { 156 | item.style.display = 'none'; 157 | } 158 | }); 159 | 160 | // Hide empty folders 161 | folders.forEach(folder => { 162 | const visibleItems = folder.querySelectorAll('.tree-item:not([style*="none"])'); 163 | if (visibleItems.length === 0) { 164 | folder.style.display = 'none'; 165 | } 166 | }); 167 | } 168 | 169 | searchInput.addEventListener('input', function() { 170 | clearTimeout(searchTimeout); 171 | searchTimeout = setTimeout(performTreeSearch, 250); 172 | }); 173 | 174 | searchInput.addEventListener('keydown', function(e) { 175 | if (e.key === 'Escape') { 176 | this.value = ''; 177 | performTreeSearch(); 178 | } 179 | }); 180 | } 181 | } 182 | 183 | // Legacy flat list search (when jsTree is not used) 184 | const navList = document.querySelector('.nav-list:not(.jstree)'); 185 | const isTreeNav = false; // jsTree handles tree navigation now 186 | 187 | if (navList && !document.querySelector('#jstree-container ul')) { 188 | // Only use legacy search for flat lists 189 | const searchInput = document.getElementById('sidebar-search-input'); 190 | 191 | function performSearch() { 192 | const searchTerm = searchInput.value.toLowerCase().trim(); 193 | let visibleCount = 0; 194 | 195 | // Show/hide clear button 196 | searchClear.style.display = searchTerm ? 'block' : 'none'; 197 | 198 | if (isTreeNav) { 199 | // Tree navigation search for new structure 200 | const allFiles = navList.querySelectorAll('.nav-file'); 201 | const directories = navList.querySelectorAll('.nav-directory'); 202 | 203 | // Search through all file items 204 | allFiles.forEach(item => { 205 | const link = item.querySelector('a'); 206 | const text = link ? link.textContent.toLowerCase() : ''; 207 | 208 | if (!searchTerm || text.includes(searchTerm)) { 209 | item.style.display = ''; 210 | visibleCount++; 211 | // Show all parent directories 212 | let parent = item.parentElement; 213 | while (parent && parent !== navList) { 214 | if (parent.classList.contains('nav-directory')) { 215 | parent.style.display = ''; 216 | if (searchTerm) { 217 | parent.classList.add('expanded'); 218 | } 219 | } 220 | parent = parent.parentElement; 221 | } 222 | } else { 223 | item.style.display = 'none'; 224 | } 225 | }); 226 | 227 | // Handle directories visibility 228 | directories.forEach(dir => { 229 | const hasVisibleFiles = dir.querySelectorAll('.nav-file:not([style*="none"])').length > 0; 230 | const hasVisibleSubDirs = dir.querySelectorAll('.nav-directory:not([style*="none"])').length > 0; 231 | 232 | if (!searchTerm) { 233 | dir.style.display = ''; 234 | } else if (!hasVisibleFiles && !hasVisibleSubDirs) { 235 | dir.style.display = 'none'; 236 | } 237 | }); 238 | } else { 239 | // Flat navigation search 240 | const navItems = navList ? navList.querySelectorAll('li') : []; 241 | navItems.forEach(item => { 242 | const link = item.querySelector('a'); 243 | const text = link ? link.textContent.toLowerCase() : ''; 244 | 245 | if (!searchTerm || text.includes(searchTerm)) { 246 | item.style.display = ''; 247 | visibleCount++; 248 | } else { 249 | item.style.display = 'none'; 250 | } 251 | }); 252 | } 253 | 254 | // Show a message if no results found 255 | let noResultsMsg = document.getElementById('no-search-results'); 256 | if (searchTerm && visibleCount === 0) { 257 | if (!noResultsMsg) { 258 | noResultsMsg = document.createElement('div'); 259 | noResultsMsg.id = 'no-search-results'; 260 | noResultsMsg.className = 'no-results'; 261 | noResultsMsg.textContent = '没有找到匹配的结果'; 262 | navList.parentNode.insertBefore(noResultsMsg, navList); 263 | } 264 | noResultsMsg.style.display = 'block'; 265 | } else if (noResultsMsg) { 266 | noResultsMsg.style.display = 'none'; 267 | } 268 | 269 | // Restore original expanded state when search is cleared 270 | if (!searchTerm && isTreeNav) { 271 | const directories = navList.querySelectorAll('.nav-directory'); 272 | directories.forEach(dir => { 273 | // Check if directory contains active item 274 | const hasActive = dir.querySelector('.nav-subdirectory .active'); 275 | if (hasActive) { 276 | dir.classList.add('expanded'); 277 | } else { 278 | dir.classList.remove('expanded'); 279 | } 280 | }); 281 | } 282 | } 283 | 284 | if (searchInput) { 285 | // Perform search on input 286 | searchInput.addEventListener('input', performSearch); 287 | 288 | // Clear search when clicking X 289 | searchClear.addEventListener('click', function() { 290 | searchInput.value = ''; 291 | performSearch(); 292 | searchInput.focus(); 293 | }); 294 | 295 | // Clear search with Escape key 296 | searchInput.addEventListener('keydown', function(e) { 297 | if (e.key === 'Escape') { 298 | searchInput.value = ''; 299 | performSearch(); 300 | } 301 | }); 302 | } 303 | } 304 | }); -------------------------------------------------------------------------------- /html/CLAUDE.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 扩散模型教程项目说明 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

(交流可以用英文,本文档中文,保留这句)

199 |

扩散模型教程项目说明

200 |

项目目标

201 |

编写一份 扩散模型设计的由浅入深的教程markdown,要包含大量的习题和参考答案(答案默认折叠)。合适时提及相关 pytorch 函数名但不写代码。 202 | 项目特色是,包含大量的可继续研究的线索

203 |

工具说明

204 |

当需要时,可以通过 gemini -p "深入回答:<要问的问题> -m gemini-2.5-pro" 来获取 gemini-2.5-pro 的参考意见(gemini 系只问 gemini-2.5-pro 不问别人) 205 | 当需要时,可以通过 `echo "<要问的问题>"|llm -m 4.1 来获取 gpt-4.1 的参考意见

206 |

教程大纲

207 |

最终章节结构(14章 + 附录)

208 |
    209 |
  1. 第1章:扩散模型导论 - 基本概念、历史发展、前向扩散过程
  2. 210 |
  3. 第2章:神经网络架构:U-Net与ViT - 扩散模型中的去噪网络架构,U-Net详解,Vision Transformer在扩散模型中的应用
  4. 211 |
  5. 第3章:去噪扩散概率模型 (DDPM) - 核心原理、变分下界、训练算法
  6. 212 |
  7. 第4章:基于分数的生成模型 - Score matching、Langevin dynamics
  8. 213 |
  9. 第5章:连续时间扩散模型 (PDE/SDE) - 随机微分方程、概率流ODE、Fokker-Planck方程
  10. 214 |
  11. 第6章:流匹配 (Flow Matching) - 连续正则化流、最优传输视角、与扩散模型的联系
  12. 215 |
  13. 第7章:扩散Transformer (DiT) - Diffusion Transformer架构、与U-Net的对比、可扩展性分析
  14. 216 |
  15. 第8章:采样算法与加速技术 - DDIM、DPM-Solver等快速采样方法
  16. 217 |
  17. 第9章:条件生成与引导技术 - Classifier guidance、classifier-free guidance
  18. 218 |
  19. 第10章:潜在扩散模型 (LDM) - Stable Diffusion架构
  20. 219 |
  21. 第11章:视频扩散模型 - 时序建模、3D U-Net、视频生成的挑战与方法
  22. 220 |
  23. 第12章:文本扩散模型 - D3PM、Diffusion-LM、embedding空间扩散
  24. 221 |
  25. 第13章:扩散模型的应用 - 图像生成、编辑、超分辨率、3D生成
  26. 222 |
  27. 第14章:前沿研究与未来方向 - 一致性模型、扩散模型的未来发展趋势
  28. 223 |
224 |

附录A:测度论与随机过程速成 - 为第5章PDE/SDE内容提供数学基础 225 | 附录B:倒向随机微分方程 (BSDE) 速成 - 理解扩散模型反向过程的数学工具

226 |

内容设计原则

227 |
    228 |
  1. 229 |

    PDE/SDE章节方法: 230 | - 先介绍直觉和实际实现 231 | - 然后进行完整推导,包括reverse SDE 232 | - 测度论和随机微积分速成课程放在附录

    233 |
  2. 234 |
  3. 235 |

    文本扩散模型重点: 236 | - 离散状态空间扩散(如D3PM) 237 | - 连续embedding空间扩散(如Diffusion-LM) 238 | - 两者并重

    239 |
  4. 240 |
  5. 241 |

    交互元素: 242 | - 保持简单,先用静态图像 243 | - 逐步增加交互性

    244 |
  6. 245 |
  7. 246 |

    编程语言和框架: 247 | - Python/PyTorch(不用JAX) 248 | - 方法可以高级,但限于toy data

    249 |
  8. 250 |
  9. 251 |

    章节依赖性: 252 | - 每章尽量自包含 253 | - 文本扩散模型章节(第8章)设计为独立可读

    254 |
  10. 255 |
  11. 256 |

    练习设计: 257 | - 理论和实现混合 258 | - 包含挑战题 259 | - 难度递进

    260 |
  12. 261 |
  13. 262 |

    代码框架: 263 | - 逐章构建mini-library 264 | - 提供skeleton code让学生填充

    265 |
  14. 266 |
  15. 267 |

    前置知识: 268 | - 假设学生已有概率论、神经网络基础、PyTorch经验 269 | - 在首页明确说明这些前置要求

    270 |
  16. 271 |
272 |

章节格式要求

273 |

每个章节应包含:

274 |
    275 |
  1. 开篇段落 - 引入本章主题,说明学习目标
  2. 276 |
  3. 丰富的文字描述 - 不仅是公式,要有充分的文字解释和直观说明
  4. 277 |
  5. 本章小结 - 总结要点,预告下一章内容
  6. 278 |
279 |

输出大小控制

280 |

重要原则

281 |
    282 |
  • 输入可以是章节级别的请求(如"创建第2章")
  • 283 |
  • 但输出必须限制在一个小节(section)的大小,不超过
  • 284 |
  • 有时甚至要在子小节(subsection)级别工作
  • 285 |
  • 这样确保每次生成的内容精炼且高质量
  • 286 |
287 |

统一样式要求

288 |
    289 |
  1. 使用共享CSS/JS文件 - 将通用样式抽取到 common.csscommon.js
  2. 290 |
  3. 长代码和练习答案默认折叠 - 使用统一的折叠/展开机制
  4. 291 |
  5. 响应式设计 - 确保移动端友好
  6. 292 |
  7. 数学公式 - 使用KaTeX渲染
  8. 293 |
  9. 代码高亮 - 使用Prism.js或类似库
  10. 294 |
295 |

important-instruction-reminders

296 |

Do what has been asked; nothing more, nothing less. 297 | NEVER create files unless they're absolutely necessary for achieving your goal. 298 | ALWAYS prefer editing an existing file to creating a new one. 299 | NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.

300 |
301 | 302 | 303 |
304 |
305 | 306 | -------------------------------------------------------------------------------- /html/appendix-b.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 附录B:倒向随机微分方程 (BSDE) 速成 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

← 附录A | 附录B | 附录C →

199 |

附录B:倒向随机微分方程 (BSDE) 速成

200 |

倒向随机微分方程(Backward Stochastic Differential Equations, BSDE)是理解扩散模型反向过程,特别是其与最优控制和经济学联系的重要数学工具。本附录将快速介绍BSDE的核心概念,旨在为读者提供一个更深刻的理论视角。

201 |

B.1 从前向到倒向:问题的提出

202 |

标准的前向SDE(FSDE)从一个已知的初始状态 X_0 出发,描述系统如何演化到未来。然而,在许多问题中,我们关心的是一个“目标导向”的问题:给定一个在未来时刻 T 的目标(或成本)ξ,我们想知道在当前时刻 t 的“价值”Y_t 以及为了达到该目标需要采取的“策略”Z_t

203 |
204 |

定义 B.1 (一般BSDE) 205 | 一个BSDE的解是一对随机过程 (Y_t, Z_t),满足: 206 |

207 |
208 |

$$-dY_t = f(t, Y_t, Z_t)dt - Z_t dW_t$$

209 |
210 |

并满足一个终端条件 Y_T = ξ

211 |
212 |

与FSDE的核心区别

213 |
    214 |
  • 信息流向:FSDE由初始条件决定,向未来求解。BSDE由终端条件决定,向过去求解。
  • 215 |
  • 解的构成:FSDE的解是一个过程 X_t。BSDE的解是一对过程 (Y_t, Z_t)
  • 216 |
217 |

直观理解 Y_tZ_t

218 |
    219 |
  • Y_t (价值过程): 代表在时刻 t,为了满足终端条件 ξ 所需的“价值”或“成本”。
  • 220 |
  • Z_t (策略/对冲过程): 代表在时刻 t,为了应对随机性 dW_t 而需要采取的“策略”或“控制”。在金融中,这对应于对冲组合;在扩散模型中,它与分数函数 ∇log p_t 密切相关。
  • 221 |
222 |

B.2 核心理论

223 |

B.2.1 存在唯一性

224 |

BSDE理论的基石是由Pardoux和彭实戈在1990年证明的存在唯一性定理。

225 |
226 |

定理 B.2 (Pardoux-Peng, 1990) 227 | 如果终端条件 ξ 是平方可积的,且驱动函数 f(t, y, z) 关于 yz 满足Lipschitz连续性,那么BSDE存在唯一的平方可积解 (Y, Z)

228 |
229 |

这个定理保证了我们讨论的问题是良定义的。后续的研究将条件放宽到了二次增长的驱动函数,这对于连接BSDE和某些物理或金融模型至关重要。

230 |

B.2.2 比较定理

231 |

BSDE的一个强大性质是比较定理,它允许我们比较不同BSDE的解。 232 | 简而言之:如果一个BSDE的终端条件和驱动函数都“更大”,那么它的解 Y_t 在任何时刻 t 也都“更大”。这在风险度量和最优控制中非常有用。

233 |

B.2.3 BSDE与PDE的联系:非线性Feynman-Kac公式

234 |

BSDE与偏微分方程(PDE)之间存在深刻的对偶关系,这通过非线性Feynman-Kac公式建立。

235 |

🌟 理论核心:一个(半)线性抛物型PDE的解,可以表示为一个BSDE的解的期望。反之,一个BSDE的解 Y_t 也可以看作是某个PDE u(t, X_t) 沿着随机路径 X_t 的演化。具体来说,Y_t = u(t, X_t),而 Z_tu 的空间梯度 ∇u 相关:Z_t = σ^T * ∇u

236 |

这个联系是双向的:

237 |
    238 |
  • 我们可以用概率方法(模拟BSDE)来求解高维PDE。
  • 239 |
  • 我们可以用PDE的理论来分析BSDE的性质。
  • 240 |
241 |

B.3 BSDE在扩散模型中的应用

242 |

BSDE为连续时间扩散模型提供了严格的数学描述。

243 |
    244 |
  1. 245 |

    反向过程的刻画:扩散模型的反向过程,即从噪声 x_T 生成数据 x_0 的过程,本质上是一个终端值问题,可以用BSDE来精确描述。

    246 |
  2. 247 |
  3. 248 |

    分数函数的演化:定义 Y_t = log p_t(X_t),即沿着随机路径 X_t 的对数概率密度。可以证明,Y_t 满足一个驱动函数 f 具有二次增长的非线性BSDE。在这个BSDE中,Z_t 过程与分数函数 ∇log p_t(X_t) 直接相关。

    249 |

    💡 关键洞察:这意味着,学习分数函数的过程,可以被看作是求解一个非线性BSDE的过程。这为设计新的损失函数和训练算法提供了理论依据。例如,我们可以通过最小化BSDE的残差来学习分数模型。

    250 |
  4. 251 |
  5. 252 |

    与最优传输的联系:连接两个分布 p_0p_T 的Schrödinger桥问题,可以被转化为求解一个耦合的前向-倒向SDE(FBSDE)系统。这个系统的解给出了在两个分布之间转换的最优随机路径,为扩散模型提供了最优传输的视角。

    253 |
  6. 254 |
255 |

B.4 数值方法简介

256 |

由于大多数BSDE没有解析解,数值方法至关重要。

257 |
    258 |
  • 259 |

    时间离散化:最常见的是向后欧拉格式。从 Y_T = ξ 开始,反向迭代求解 (Y_{t_i}, Z_{t_i})。每一步都需要计算一个条件期望,这是数值求解的难点。

    260 |
  • 261 |
  • 262 |

    深度学习方法 (Deep BSDE):现代方法使用神经网络来参数化未知的 Z_t 过程。其核心思想是:

    263 |
      264 |
    1. 用一个神经网络 Z_θ(t, x) 来近似 Z_t
    2. 265 |
    3. t=0 开始,使用 Z_θ 和一个猜测的初始值 Y_0,通过离散化格式前向模拟出 Y_T
    4. 266 |
    5. 最小化模拟得到的 Y_T 和真实的终端条件 ξ 之间的误差 ||Y_T - ξ||^2
    6. 267 |
    7. 通过反向传播训练网络参数 θ 和初始值 Y_0
    8. 268 |
    269 |
  • 270 |
271 |

实现挑战:Deep BSDE方法将一个复杂的随机控制问题转化为了一个深度学习的优化问题,但在高维情况下,仍然面临“维度灾难”的挑战。

272 |
273 | 练习 B.1:线性BSDE的显式解 274 |

考虑线性BSDE:-dY_t = (aY_t + f_t)dt - Z_t dW_t,终端条件为 Y_T = ξ,其中 a 是常数,f_t 是确定性函数。

275 |
    276 |
  1. 求解:使用积分因子 e^{at},求解 Y_t 的表达式。
  2. 277 |
  3. 分析:解释解的表达式的金融学含义(将 a 视为贴现率)。
  4. 278 |
  5. 开放探索:如果 a 也是一个随机过程 a_t,解会是什么形式?这在随机利率模型中很常见。
  6. 279 |
280 |

解答思路

281 |
    282 |
  1. tilde(Y)_t = e^{at}Y_t 应用伊藤公式,可以消去 Y_t 的漂移项,得到一个只包含 dtdW_t 的SDE。对其积分再整理,最终得到 Y_t = E[e^{-a(T-t)}ξ + ∫_t^T e^{-a(s-t)}f_s ds | F_t]
  2. 283 |
  3. 这个解表示,时刻 t 的价值等于未来所有现金流 f_s 和终端价值 ξ 在考虑了贴现因子 e^{-a(s-t)} 后的条件期望。
  4. 284 |
285 |
286 |
287 | 练习 B.2:BSDE与热方程 288 |

证明热方程 ∂u/∂t + 1/2 * Δu = 0u(T,x) = g(x) 的解可以用一个BSDE表示。

289 |
    290 |
  1. 构造过程:定义一个前向过程 X_t^x = x + W_t 和一个新过程 Y_t = u(t, X_t^x)
  2. 291 |
  3. 应用伊藤公式:对 Y_t 应用伊藤公式。
  4. 292 |
  5. 建立联系:利用 u 是热方程的解这一事实,证明 Y_t 满足一个驱动函数 f=0 的BSDE。
  6. 293 |
294 |

研究思路:这个练习展示了Feynman-Kac公式最简单的情形。思考一下,如果PDE中有一个非线性的项,例如 ∂u/∂t + 1/2 * Δu + (∇u)^2 = 0(Hamilton-Jacobi-Bellman方程),那么对应的BSDE的驱动函数 f 会是什么样的?

295 |
296 |

本章小结

297 |
    298 |
  • 核心定义:BSDE是从一个未来的终端条件出发,向后求解的随机微分方程,其解为一对 (Y_t, Z_t) 过程。
  • 299 |
  • 理论基石:存在唯一性定理和比较定理保证了BSDE的良好性质。非线性Feynman-Kac公式建立了BSDE与PDE的深刻联系。
  • 300 |
  • 扩散模型应用:BSDE为描述扩散模型的反向过程和分数函数的演化提供了严格的数学框架,并将其与最优控制和最优传输理论联系起来。
  • 301 |
302 |

虽然BSDE理论较为抽象,但它为我们理解“目标导向”的随机过程提供了统一而强大的语言,是连接概率论、PDE和机器学习的重要桥梁。

303 |
304 | 305 | 306 |
307 |
308 | 309 | -------------------------------------------------------------------------------- /html/appendix-c.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 附录C:信息几何与分数函数的力学解释 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

← 附录B | 附录C | 返回首页 →

199 |

附录C:信息几何与分数函数的力学解释

200 |

扩散模型的成功不仅是工程上的胜利,更是深刻数学原理的体现。本附录将从信息几何(Information Geometry)的角度重新审视扩散模型,揭示分数函数作为“力”的物理意义,并建立与能量优化的深刻联系。这种视角不仅提供了强大的理论洞察,也为设计新算法提供了直观的指导原则。

201 |

C.1 信息几何基础

202 |

信息几何将概率分布空间 P 视为一个具有内在几何结构的黎曼流形(Riemannian manifold),而不是一个平坦的欧几里得空间。

203 |

C.1.1 概率分布流形

204 |
    205 |
  • 概率单纯形: 对于离散分布,所有可能的概率向量构成一个单纯形。这是一个嵌入在高维空间中的弯曲子流形。
  • 206 |
  • Fisher信息度量: 这个流形上的“距离”不是欧几里得距离,而是由Fisher信息矩阵 I(θ) 定义的黎曼度量。两点之间的最短路径是测地线(geodesic)。
    207 |

    定义 C.1 (Fisher信息矩阵) 208 | 对于参数化的概率分布族 {p(x; θ)},Fisher信息矩阵定义为: 209 |

    210 |
    211 |
  • 212 |
213 |

$$I_{ij}( heta) = \mathbb{E}_{p(x;\theta)}\left[\frac{\partial \log p(x;\theta)}{\partial \theta_i} \frac{\partial \log p(x;\theta)}{\partial \theta_j}\right]$$ 214 | 它衡量了当我们微小地改变参数 θ 时,概率分布 p(x; θ) 的变化有多大。信息矩阵的元素越大,表示分布对该方向的参数变化越敏感。

215 |

C.1.2 自然梯度 (Natural Gradient)

216 |

在优化概率模型时,普通的梯度下降是在平坦的欧几里得空间中寻找最速下降方向。然而,在弯曲的概率流形上,真正的最速下降方向由自然梯度给出。

217 |
218 |

定义 C.2 (自然梯度) 219 | 设 L(θ) 是关于参数 θ 的损失函数,普通梯度为 g = ∇_θ L。自然梯度 g_nat 定义为:

220 |

$$\tilde{g} = I(\theta)^{-1} g$$ 221 | 优化步骤变为:θ_{t+1} = θ_t - α * I(θ_t)^{-1} * g_t

222 |
223 |

💡 关键洞察:自然梯度下降具有参数化不变性。无论我们如何对模型进行重新参数化(例如,线性变换),其在概率流形上的优化路径都是相同的。而普通梯度下降的路径则会随参数化的改变而改变。这使得自然梯度在理论上是优化概率模型的更优选择。

224 |

实现挑战:计算完整的Fisher信息矩阵并求逆的代价非常高昂(O(N^2),N为参数量)。在实践中,通常使用其对角近似、K-FAC等方法来降低计算成本。Adam等自适应优化算法也可以被看作是对自然梯度的一种简化近似。

225 |
226 | 练习 C.1:Fisher信息计算 227 |
    228 |
  1. 计算:对于一维高斯分布 N(μ, σ^2),其参数为 θ = (μ, σ)。计算其2x2的Fisher信息矩阵 I(μ, σ)
  2. 229 |
  3. 分析:从矩阵的形式分析:a) 为什么估计均值 μ 和估计标准差 σ 是解耦的?b) 为什么当 σ 很小时,Fisher信息会变大?
  4. 230 |
  5. 开放探索:自然梯度在训练扩散模型的分数网络 s_θ 时有何应用?θ 是网络权重,此时的Fisher信息矩阵该如何定义和计算?
  6. 231 |
232 |

解答思路

233 |
    234 |
  1. 写出对数似然 log p(x; μ, σ),然后计算其对 μσ 的二阶偏导数的期望。你会发现非对角线项的期望为0,对角线项分别为 1/σ^22/σ^2
  2. 235 |
  3. a) 非对角线项为0意味着参数 μσ 在Fisher度量下是正交的。b) σ 越小,分布越集中,从样本中推断参数位置的信息就越多,因此Fisher信息越大。
  4. 236 |
237 |
238 |

C.2 分数函数的几何与力学解释

239 |

C.2.1 分数函数作为切向量

240 |

从信息几何的角度看,分数函数 s(x) = ∇_x log p(x) 不仅仅是一个梯度,它是在数据空间 x 中,定义了一个指向概率密度 p(x) 增长最快方向的向量场

241 |
    242 |
  • 与流形的关系:可以证明 E_p[s(x)] = 0,这意味着分数函数属于概率分布流形在某一点的切空间
  • 243 |
  • 动力学意义:如果我们让一个粒子沿着这个向量场流动,即 dx/dt = s(x),粒子最终会收敛到概率分布的局部最大值(模式)。
  • 244 |
245 |

C.2.2 Stein恒等式

246 |

Stein恒等式是连接分数函数与概率分布的桥梁,它构成了分数匹配的理论基础。

247 |
248 |

定理 C.3 (Stein恒等式) 249 | 对于一个足够光滑的测试函数 φ(x) 和概率密度 p(x),在一定边界条件下成立:

250 |

$$\mathbb{E}_{p(x)}[\nabla_x \cdot \phi(x) + \phi(x) \cdot \nabla_x \log p(x)] = 0$$ 251 | 💡 关键洞察:这个恒等式只涉及分数 ∇log p(x)p(x) 的期望,而完全不依赖于 p(x) 本身及其归一化常数。这使得我们可以在只拥有 p(x) 的样本的情况下,通过最小化Stein恒等式的残差来学习其分数函数,这正是分数匹配的核心思想。

252 |
253 |

C.2.3 分数函数作为“力场”

254 |

我们可以从物理学的角度,为分数函数建立一个非常直观的力学类比。

255 |
256 |

定义 C.4 (能量函数与力) 257 | 给定一个概率分布 p(x),我们可以定义一个对应的能量函数(或势能):

258 |

$$E(x) = -\log p(x)$$ 259 | 那么,分数函数就变成了作用在粒子上的

260 |

$$F(x) = -\nabla E(x) = \nabla \log p(x)$$ 261 | 这是一个保守力场,因为它是一个标量势 E(x) 的梯度。

262 |
263 |

物理图像

264 |
    265 |
  • 高概率区域 (p(x) 大) ⇔ 低能量区域 (E(x) 小)。
  • 266 |
  • 粒子会受到一个力的作用,将它从高能量区域(低概率)推向低能量区域(高概率)。
  • 267 |
  • 概率分布的模式(modes)对应于能量景观的势阱(potential wells)。
  • 268 |
269 |

C.2.4 Langevin动力学

270 |

Langevin动力学描述了粒子在这个力场中,同时受到随机热噪声影响时的运动轨迹。

271 |
272 |

定义 C.5 (Langevin SDE)

273 |

$$dX_t = \nabla \log p(X_t) dt + \sqrt{2} dW_t$$

274 |
    275 |
  • 漂移项 ∇log p(X_t)dt: 粒子受到分数“力”的作用,确定性地向能量更低处移动。
  • 276 |
  • 扩散项 sqrt(2)dW_t: 粒子受到随机布朗运动的扰动,使其能够探索整个能量景观,而不是仅仅陷入最近的势阱。
  • 277 |
278 |
279 |

🌟 核心联系:Langevin动力学的稳态分布恰好是 p(x)。这意味着,无论从什么初始状态开始,只要我们模拟这个SDE足够长的时间,最终得到的粒子分布就会收敛到我们想要的目标分布 p(x)。这为从概率分布中采样提供了一个基于物理模拟的强大方法。

280 |

扩散模型中的应用

281 |
    282 |
  • 前向过程:可以看作是一个能量景观逐渐被“抚平”的过程。E_0(x) = -log p_data(x) 是一个复杂、多势阱的崎岖景观,而 E_T(x) ≈ ||x||^2 / 2 是一个简单的、单一的抛物线势阱。
  • 283 |
  • 反向过程:学习反向SDE dx = [f - g^2 * s_θ]dt + g d(bar(W)_t),本质上是在学习一个时变的力场 s_θ(x, t),这个力场可以在每个时刻 t 将粒子有效地引导回数据所在的高概率区域。
  • 284 |
285 |
286 | 综合练习:一维双势阱模型 287 |

考虑一个一维能量函数 E(x) = (x^2 - 1)^2,它在 x=-1x=1 处有两个势阱。

288 |
    289 |
  1. 概率分布:写出对应的概率分布 p(x) ∝ exp(-E(x)) 的表达式。
  2. 290 |
  3. 分数函数/力:计算其分数函数 s(x) = ∇log p(x)。分析在 x=0(势垒)和 x=-1, 1(势阱)附近,这个“力”的方向和大小。
  4. 291 |
  5. Langevin动力学:写出对应的Langevin SDE。如果一个粒子从 x=0 开始,它的长期行为会是怎样的?
  6. 292 |
  7. 开放探索:在扩散模型中,我们学习的是一个时变的分数函数 s_θ(x, t)。对于这个双势阱例子,s_θ(x, t)t 接近 T(高噪声)和 t 接近 0(低噪声)时,其形状应该分别是什么样的?
  8. 293 |
294 |

解答思路

295 |
    296 |
  1. p(x) = (1/Z) * exp(-(x^2 - 1)^2)Z是归一化常数。
  2. 297 |
  3. s(x) = -dE/dx = -2(x^2 - 1)(2x) = -4x(x^2 - 1)。在 x=0s(0)=0,但这是一个不稳定的平衡点。在 x=-1, 1s(x)=0,是稳定的平衡点。在 x 略大于0时,s(x)<0,力指向左边;略小于0时,s(x)>0,力指向右边,因此粒子会被推离 x=0
  4. 298 |
  5. dX_t = -4X_t(X_t^2 - 1)dt + sqrt(2)dW_t。长期来看,粒子会在两个势阱 x=-1x=1 之间来回跳跃,其最终分布会收敛到 p(x)
  6. 299 |
  7. t 接近 T 时,能量景观被抚平,s_θ(x, t) 应该接近于一个单势阱(高斯分布)的分数函数,即 s ≈ -x。当 t 接近 0 时,s_θ(x, t) 应该精确地逼近我们计算出的 s(x) = -4x(x^2 - 1),以恢复双峰结构。
  8. 300 |
301 |
302 |
303 | 304 | 305 |
306 |
307 | 308 | -------------------------------------------------------------------------------- /html/assets/style.css: -------------------------------------------------------------------------------- 1 | /* Reset and base styles */ 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | 8 | :root { 9 | --primary-color: #2c3e50; 10 | --secondary-color: #3498db; 11 | --text-color: #333; 12 | --bg-color: #fff; 13 | --sidebar-bg: #f8f9fa; 14 | --border-color: #e0e0e0; 15 | --code-bg: #f4f4f4; 16 | --link-color: #3498db; 17 | --link-hover: #2980b9; 18 | } 19 | 20 | body { 21 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 22 | font-size: 16px; 23 | line-height: 1.6; 24 | color: var(--text-color); 25 | background-color: var(--bg-color); 26 | } 27 | 28 | /* Container layout */ 29 | .container { 30 | display: flex; 31 | min-height: 100vh; 32 | } 33 | 34 | /* Sidebar */ 35 | .sidebar { 36 | width: 300px; 37 | background-color: var(--sidebar-bg); 38 | border-right: 1px solid var(--border-color); 39 | padding: 20px; 40 | overflow-y: auto; 41 | position: fixed; 42 | height: 100vh; 43 | left: 0; 44 | top: 0; 45 | transition: transform 0.3s ease; 46 | } 47 | 48 | .sidebar-header { 49 | display: flex; 50 | justify-content: space-between; 51 | align-items: center; 52 | margin-bottom: 20px; 53 | padding-bottom: 10px; 54 | border-bottom: 1px solid var(--border-color); 55 | } 56 | 57 | .sidebar-header h3 { 58 | color: var(--primary-color); 59 | font-size: 1.2rem; 60 | } 61 | 62 | /* Search input styles */ 63 | .sidebar-search { 64 | position: relative; 65 | margin-bottom: 20px; 66 | } 67 | 68 | #sidebar-search-input { 69 | width: 100%; 70 | padding: 8px 30px 8px 12px; 71 | border: 1px solid var(--border-color); 72 | border-radius: 4px; 73 | font-size: 14px; 74 | background-color: var(--bg-color); 75 | color: var(--text-color); 76 | transition: border-color 0.2s; 77 | } 78 | 79 | #sidebar-search-input:focus { 80 | outline: none; 81 | border-color: var(--secondary-color); 82 | } 83 | 84 | .search-clear { 85 | position: absolute; 86 | right: 8px; 87 | top: 50%; 88 | transform: translateY(-50%); 89 | cursor: pointer; 90 | color: #999; 91 | font-size: 18px; 92 | display: none; 93 | user-select: none; 94 | padding: 4px; 95 | } 96 | 97 | .search-clear:hover { 98 | color: var(--text-color); 99 | } 100 | 101 | .no-results { 102 | padding: 12px; 103 | text-align: center; 104 | color: #666; 105 | font-size: 14px; 106 | border: 1px dashed var(--border-color); 107 | border-radius: 4px; 108 | margin-bottom: 20px; 109 | background-color: rgba(0, 0, 0, 0.02); 110 | } 111 | 112 | .sidebar-toggle { 113 | display: none; 114 | background: none; 115 | border: none; 116 | cursor: pointer; 117 | padding: 5px; 118 | width: 30px; 119 | height: 30px; 120 | position: relative; 121 | } 122 | 123 | .sidebar-toggle span { 124 | display: block; 125 | width: 20px; 126 | height: 2px; 127 | background-color: var(--primary-color); 128 | margin: 4px 0; 129 | transition: 0.3s; 130 | } 131 | 132 | .nav-list { 133 | list-style: none; 134 | } 135 | 136 | .nav-list li { 137 | margin-bottom: 8px; 138 | } 139 | 140 | .nav-list a { 141 | color: var(--text-color); 142 | text-decoration: none; 143 | display: block; 144 | padding: 8px 12px; 145 | border-radius: 4px; 146 | transition: background-color 0.2s; 147 | } 148 | 149 | .nav-list a:hover { 150 | background-color: rgba(52, 152, 219, 0.1); 151 | color: var(--link-color); 152 | } 153 | 154 | .nav-list .active a { 155 | background-color: var(--secondary-color); 156 | color: white; 157 | } 158 | 159 | /* Pure CSS Tree Navigation */ 160 | #tree-container { 161 | height: calc(100% - 120px); 162 | overflow-y: auto; 163 | overflow-x: hidden; 164 | padding: 8px; 165 | } 166 | 167 | .tree-nav { 168 | font-size: 14px; 169 | line-height: 1.6; 170 | } 171 | 172 | /* Tree items */ 173 | .tree-item { 174 | margin: 2px 0; 175 | } 176 | 177 | .tree-link { 178 | display: flex; 179 | align-items: center; 180 | padding: 8px 12px; 181 | border-radius: 6px; 182 | text-decoration: none; 183 | color: var(--text-color); 184 | transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); 185 | } 186 | 187 | .tree-link:hover { 188 | background-color: rgba(52, 152, 219, 0.08); 189 | transform: translateX(2px); 190 | } 191 | 192 | .tree-item.active .tree-link { 193 | background-color: var(--secondary-color); 194 | color: white; 195 | font-weight: 500; 196 | } 197 | 198 | /* Tree folders */ 199 | .tree-folder { 200 | margin: 4px 0; 201 | } 202 | 203 | .tree-folder-header { 204 | display: flex; 205 | align-items: center; 206 | padding: 8px 12px; 207 | border-radius: 6px; 208 | cursor: pointer; 209 | user-select: none; 210 | transition: background-color 0.2s ease; 211 | } 212 | 213 | .tree-folder-header:hover { 214 | background-color: rgba(0, 0, 0, 0.04); 215 | } 216 | 217 | .tree-folder-content { 218 | margin-left: 24px; 219 | max-height: 0; 220 | overflow: hidden; 221 | opacity: 0; 222 | transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), 223 | opacity 0.2s ease, 224 | padding 0.2s ease; 225 | } 226 | 227 | .tree-folder.expanded .tree-folder-content { 228 | max-height: 2000px; 229 | opacity: 1; 230 | padding: 4px 0; 231 | } 232 | 233 | /* Icons and arrows */ 234 | .tree-arrow { 235 | display: inline-block; 236 | width: 20px; 237 | height: 20px; 238 | margin-right: 4px; 239 | transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1); 240 | font-size: 12px; 241 | color: #666; 242 | } 243 | 244 | .tree-folder.expanded .tree-arrow { 245 | transform: rotate(90deg); 246 | } 247 | 248 | .tree-icon { 249 | display: inline-flex; 250 | align-items: center; 251 | justify-content: center; 252 | width: 20px; 253 | height: 20px; 254 | margin-right: 8px; 255 | font-size: 16px; 256 | } 257 | 258 | .tree-folder.expanded .tree-folder-header .tree-icon { 259 | font-size: 0; 260 | } 261 | 262 | .tree-folder.expanded .tree-folder-header .tree-icon::after { 263 | content: "📂"; 264 | font-size: 16px; 265 | } 266 | 267 | .tree-folder:not(.expanded) .tree-folder-header .tree-icon { 268 | font-size: 0; 269 | } 270 | 271 | .tree-folder:not(.expanded) .tree-folder-header .tree-icon::after { 272 | content: "📁"; 273 | font-size: 16px; 274 | } 275 | 276 | .tree-title { 277 | flex: 1; 278 | white-space: nowrap; 279 | overflow: hidden; 280 | text-overflow: ellipsis; 281 | } 282 | 283 | /* Search results highlight */ 284 | .tree-item.search-match, 285 | .tree-folder.search-match .tree-folder-header { 286 | background-color: #fff3cd; 287 | } 288 | 289 | /* Mobile optimizations */ 290 | @media (max-width: 768px) { 291 | .tree-link, 292 | .tree-folder-header { 293 | min-height: 44px; 294 | padding: 12px; 295 | } 296 | 297 | .tree-nav { 298 | font-size: 16px; 299 | } 300 | 301 | .tree-icon { 302 | width: 24px; 303 | height: 24px; 304 | font-size: 18px; 305 | } 306 | } 307 | 308 | /* Modern Tree Navigation (for legacy non-jstree) */ 309 | .nav-tree-container { 310 | height: 100%; 311 | overflow-y: auto; 312 | overflow-x: hidden; 313 | padding: 4px; 314 | } 315 | 316 | .nav-tree { 317 | padding: 0; 318 | margin: 0; 319 | font-size: 14px; 320 | line-height: 1.5; 321 | } 322 | 323 | .nav-tree li { 324 | list-style: none; 325 | margin: 0; 326 | padding: 0; 327 | position: relative; 328 | } 329 | 330 | /* File items */ 331 | .nav-file { 332 | display: flex; 333 | align-items: center; 334 | padding: 4px 8px; 335 | margin: 1px 0; 336 | border-radius: 4px; 337 | transition: all 0.2s ease; 338 | cursor: pointer; 339 | } 340 | 341 | .nav-file:hover { 342 | background-color: rgba(52, 152, 219, 0.08); 343 | } 344 | 345 | .nav-file.active { 346 | background-color: var(--secondary-color); 347 | color: white; 348 | } 349 | 350 | .nav-file a { 351 | flex: 1; 352 | color: inherit; 353 | text-decoration: none; 354 | padding: 0 4px; 355 | white-space: nowrap; 356 | overflow: hidden; 357 | text-overflow: ellipsis; 358 | display: block; 359 | } 360 | 361 | .nav-file.active a { 362 | color: white; 363 | } 364 | 365 | /* Directory items */ 366 | .nav-directory { 367 | margin: 2px 0; 368 | } 369 | 370 | .nav-directory-toggle { 371 | display: flex; 372 | align-items: center; 373 | padding: 4px 8px; 374 | margin: 1px 0; 375 | border-radius: 4px; 376 | cursor: pointer; 377 | user-select: none; 378 | transition: background-color 0.2s; 379 | font-weight: 500; 380 | } 381 | 382 | .nav-directory-toggle:hover { 383 | background-color: rgba(0, 0, 0, 0.04); 384 | } 385 | 386 | /* Icons */ 387 | .toggle-icon { 388 | display: inline-flex; 389 | align-items: center; 390 | justify-content: center; 391 | width: 16px; 392 | height: 16px; 393 | margin-right: 2px; 394 | transition: transform 0.2s ease; 395 | font-size: 10px; 396 | color: #666; 397 | } 398 | 399 | .nav-directory.expanded .toggle-icon { 400 | transform: rotate(0deg); 401 | } 402 | 403 | .nav-directory:not(.expanded) .toggle-icon { 404 | transform: rotate(-90deg); 405 | } 406 | 407 | .folder-icon, .file-icon { 408 | display: inline-flex; 409 | align-items: center; 410 | justify-content: center; 411 | width: 18px; 412 | height: 18px; 413 | margin-right: 6px; 414 | font-size: 14px; 415 | flex-shrink: 0; 416 | } 417 | 418 | .nav-directory.expanded .folder-icon { 419 | content: "📂"; 420 | } 421 | 422 | .directory-name { 423 | flex: 1; 424 | font-weight: 500; 425 | color: var(--primary-color); 426 | white-space: nowrap; 427 | overflow: hidden; 428 | text-overflow: ellipsis; 429 | } 430 | 431 | /* Subdirectory */ 432 | .nav-subdirectory { 433 | list-style: none; 434 | margin: 0; 435 | padding: 0 0 0 12px; 436 | overflow: hidden; 437 | max-height: 0; 438 | opacity: 0; 439 | transition: max-height 0.3s ease, opacity 0.2s ease; 440 | } 441 | 442 | .nav-directory.expanded .nav-subdirectory { 443 | max-height: none; 444 | opacity: 1; 445 | } 446 | 447 | /* Indentation for nested levels */ 448 | .nav-tree li[data-level="1"] { 449 | padding-left: 16px; 450 | } 451 | 452 | .nav-tree li[data-level="2"] { 453 | padding-left: 32px; 454 | } 455 | 456 | .nav-tree li[data-level="3"] { 457 | padding-left: 48px; 458 | } 459 | 460 | /* Tree lines (optional, for CHM-like appearance) */ 461 | .nav-tree li::before { 462 | content: ""; 463 | position: absolute; 464 | left: 8px; 465 | top: 0; 466 | bottom: 0; 467 | width: 1px; 468 | background: linear-gradient(to bottom, transparent, #ddd 20%, #ddd 80%, transparent); 469 | } 470 | 471 | .nav-tree li[data-level="0"]::before { 472 | display: none; 473 | } 474 | 475 | /* Smooth scrollbar */ 476 | .nav-tree-container::-webkit-scrollbar { 477 | width: 6px; 478 | } 479 | 480 | .nav-tree-container::-webkit-scrollbar-track { 481 | background: transparent; 482 | } 483 | 484 | .nav-tree-container::-webkit-scrollbar-thumb { 485 | background: rgba(0, 0, 0, 0.2); 486 | border-radius: 3px; 487 | } 488 | 489 | .nav-tree-container::-webkit-scrollbar-thumb:hover { 490 | background: rgba(0, 0, 0, 0.3); 491 | } 492 | 493 | /* Main content */ 494 | .content { 495 | flex: 1; 496 | margin-left: 300px; 497 | padding: 40px; 498 | max-width: 900px; 499 | width: 100%; 500 | } 501 | 502 | article { 503 | margin-bottom: 40px; 504 | } 505 | 506 | /* Typography */ 507 | h1, h2, h3, h4, h5, h6 { 508 | color: var(--primary-color); 509 | margin-top: 1.5em; 510 | margin-bottom: 0.5em; 511 | font-weight: 600; 512 | } 513 | 514 | h1 { font-size: 2.2em; border-bottom: 2px solid var(--border-color); padding-bottom: 0.3em; } 515 | h2 { font-size: 1.8em; } 516 | h3 { font-size: 1.5em; } 517 | h4 { font-size: 1.3em; } 518 | h5 { font-size: 1.1em; } 519 | h6 { font-size: 1em; } 520 | 521 | p { 522 | margin-bottom: 1em; 523 | } 524 | 525 | a { 526 | color: var(--link-color); 527 | text-decoration: none; 528 | } 529 | 530 | a:hover { 531 | color: var(--link-hover); 532 | text-decoration: underline; 533 | } 534 | 535 | /* Lists */ 536 | ul, ol { 537 | margin-bottom: 1em; 538 | padding-left: 2em; 539 | } 540 | 541 | li { 542 | margin-bottom: 0.5em; 543 | } 544 | 545 | /* Code blocks */ 546 | pre { 547 | background-color: var(--code-bg); 548 | border: 1px solid var(--border-color); 549 | border-radius: 4px; 550 | padding: 16px; 551 | overflow-x: auto; 552 | margin-bottom: 1em; 553 | } 554 | 555 | code { 556 | background-color: var(--code-bg); 557 | padding: 2px 6px; 558 | border-radius: 3px; 559 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 560 | font-size: 0.9em; 561 | } 562 | 563 | pre code { 564 | background-color: transparent; 565 | padding: 0; 566 | } 567 | 568 | /* Tables */ 569 | table { 570 | width: 100%; 571 | border-collapse: collapse; 572 | margin-bottom: 1em; 573 | } 574 | 575 | th, td { 576 | border: 1px solid var(--border-color); 577 | padding: 8px 12px; 578 | text-align: left; 579 | } 580 | 581 | th { 582 | background-color: var(--sidebar-bg); 583 | font-weight: 600; 584 | } 585 | 586 | tr:nth-child(even) { 587 | background-color: rgba(0, 0, 0, 0.02); 588 | } 589 | 590 | /* Blockquotes */ 591 | blockquote { 592 | border-left: 4px solid var(--secondary-color); 593 | padding-left: 20px; 594 | margin: 1em 0; 595 | color: #666; 596 | } 597 | 598 | /* Page navigation */ 599 | .page-nav { 600 | display: flex; 601 | justify-content: space-between; 602 | margin-top: 60px; 603 | padding-top: 20px; 604 | border-top: 1px solid var(--border-color); 605 | } 606 | 607 | .nav-link { 608 | display: inline-block; 609 | padding: 10px 20px; 610 | background-color: var(--sidebar-bg); 611 | border-radius: 4px; 612 | transition: background-color 0.2s; 613 | } 614 | 615 | .nav-link:hover { 616 | background-color: rgba(52, 152, 219, 0.1); 617 | text-decoration: none; 618 | } 619 | 620 | .nav-link.prev { 621 | margin-right: auto; 622 | } 623 | 624 | .nav-link.next { 625 | margin-left: auto; 626 | } 627 | 628 | /* Mobile responsive */ 629 | @media (max-width: 768px) { 630 | .sidebar { 631 | transform: translateX(-100%); 632 | z-index: 1000; 633 | width: 85vw; 634 | max-width: 350px; 635 | box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1); 636 | } 637 | 638 | .sidebar.active { 639 | transform: translateX(0); 640 | } 641 | 642 | .sidebar-toggle { 643 | display: block; 644 | position: fixed; 645 | top: 10px; 646 | right: 10px; 647 | z-index: 1001; 648 | background: var(--bg-color); 649 | border: 1px solid var(--border-color); 650 | border-radius: 4px; 651 | padding: 8px; 652 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); 653 | } 654 | 655 | .content { 656 | margin-left: 0; 657 | padding: 20px; 658 | } 659 | 660 | .page-nav { 661 | flex-direction: column; 662 | gap: 10px; 663 | } 664 | 665 | .nav-link { 666 | width: 100%; 667 | text-align: center; 668 | } 669 | 670 | /* Larger touch targets for mobile */ 671 | .nav-file, .nav-directory-toggle { 672 | padding: 8px 12px; 673 | min-height: 44px; 674 | } 675 | 676 | .toggle-icon, .folder-icon, .file-icon { 677 | width: 24px; 678 | height: 24px; 679 | font-size: 16px; 680 | } 681 | 682 | .nav-tree { 683 | font-size: 16px; 684 | } 685 | 686 | /* Overlay when sidebar is open */ 687 | .sidebar.active::before { 688 | content: ""; 689 | position: fixed; 690 | top: 0; 691 | left: 0; 692 | right: 0; 693 | bottom: 0; 694 | background: rgba(0, 0, 0, 0.3); 695 | z-index: -1; 696 | } 697 | 698 | h1 { font-size: 1.8em; } 699 | h2 { font-size: 1.5em; } 700 | h3 { font-size: 1.3em; } 701 | } 702 | 703 | /* Dark mode preparation */ 704 | @media (prefers-color-scheme: dark) { 705 | :root { 706 | --primary-color: #ecf0f1; 707 | --secondary-color: #3498db; 708 | --text-color: #ecf0f1; 709 | --bg-color: #1a1a1a; 710 | --sidebar-bg: #2c3e50; 711 | --border-color: #34495e; 712 | --code-bg: #2c3e50; 713 | } 714 | } 715 | 716 | /* Math display */ 717 | .MathJax_Display { 718 | overflow-x: auto; 719 | overflow-y: hidden; 720 | } -------------------------------------------------------------------------------- /chapter1.md: -------------------------------------------------------------------------------- 1 | [← 返回目录](index.md) | 第1章 / 共14章 | [下一章 →](chapter2.md) 2 | 3 | # 第1章:扩散模型导论 4 | 5 | 欢迎来到扩散模型的世界。本章将为您打开一扇通往现代生成模型前沿的大门。我们将从最基本的概念出发,探索扩散模型如何通过模拟一个有序到无序、再从无序中恢复有序的优雅过程,实现惊人的生成效果。您将学习到其背后的核心数学原理,包括前向加噪和反向去噪过程,并初步接触到该领域激动人心的开放性研究问题。本章旨在为您后续深入学习DDPM、分数模型和更高级的主题奠定坚实的直觉和理论基础。 6 | 7 | ## 1.1 什么是扩散模型? 8 | 9 | 扩散模型(Diffusion Models)是一类强大的生成模型,它通过学习数据的逐步去噪过程来生成高质量的样本。这个过程可以类比为物理学中的扩散现象:就像墨水在水中逐渐扩散直至均匀分布,扩散模型将数据逐步添加噪声直至变成纯噪声,然后学习如何反转这个过程。 10 | 11 | 让我们从一个直观的例子开始。想象你有一张清晰的照片,现在你要对它进行一系列操作:第一步,添加一点点噪声,图像变得略微模糊;第二步,再添加一些噪声,细节开始消失;如此反复,经过足够多的步骤后,原始图像完全被噪声淹没,变成了纯粹的随机像素。这就是扩散模型的前向过程——一个逐渐破坏信息的过程。 12 | 13 | 神奇的是,如果我们能学会如何在每一步精确地去除添加的噪声,那么就可以从纯噪声开始,一步步恢复出原始图像。更重要的是,一旦学会了这种去噪能力,我们就可以从任意的随机噪声开始,生成全新的、从未见过但却逼真的图像。这就是扩散模型的核心思想:通过学习破坏的逆过程来实现创造。 14 | 15 | ### 从布朗运动到扩散模型:一段跨越百年的科学之旅 16 | 17 | 扩散模型的数学根源可以追溯到1827年罗伯特·布朗(Robert Brown)对花粉微粒在水中无规则运动的观察。当时,布朗用显微镜观察悬浮在水中的花粉颗粒,发现它们在不停地做着看似毫无规律的运动。这种现象困扰了科学界近80年,直到1905年,爱因斯坦(Einstein)在其奇迹之年中不仅发表了相对论,还给出了布朗运动的严格数学描述。 18 | 19 | 爱因斯坦的洞察是革命性的:他意识到这种无规则运动源于水分子对花粉的不断碰撞。由于分子运动的随机性,花粉在各个方向受到的撞击力不平衡,导致了观察到的随机运动。他通过扩散方程 $\frac{\partial p}{\partial t} = D\nabla^2 p$ 刻画了粒子密度的演化,其中 $p$ 是粒子的概率密度, $D$ 是扩散系数。这个方程告诉我们,粒子会从高浓度区域向低浓度区域扩散,最终达到均匀分布。 20 | 21 | 值得注意的是,这里的扩散过程遵循菲克定律(Fick's law),描述的是浓度梯度驱动的纯扩散现象,而非Navier-Stokes方程中的对流-扩散耦合过程。在机器学习的扩散模型中,我们关注的正是这种纯粹的随机扩散:没有外力驱动的定向流动,只有随机热运动导致的均匀化过程。这种纯扩散的特性使得数学处理更加优雅,也保证了前向过程的可逆性。 22 | 23 | 三年后的1908年,保罗·朗之万(Paul Langevin)提出了另一种描述布朗运动的方法——不再关注粒子群体的密度演化,而是追踪单个粒子的轨迹。他提出的随机微分方程: $d\mathbf{x}\_t = -\nabla U(\mathbf{x}\_t)dt + \sqrt{2D}d\mathbf{W}\_t$ ,其中第一项 $-\nabla U(\mathbf{x}\_t)dt$ 是确定性的漂移项,表示粒子在势能场 $U$ 中受到的力;第二项 $\sqrt{2D}d\mathbf{W}\_t$ 是随机的扩散项,表示分子碰撞带来的随机扰动, $\mathbf{W}\_t$ 是维纳过程(Wiener process)。 24 | 25 | 这个方程奠定了随机过程理论的基础,也成为了现代扩散模型的理论支柱。从朗之万动力学到今天的去噪扩散概率模型(DDPM),核心思想一脉相承:通过在数据上添加精心设计的噪声(对应朗之万方程中的随机项),并学习反向的去噪过程(对应漂移项),我们可以从简单的噪声分布生成复杂的数据分布。这种优雅的对称性不仅在数学上令人着迷,更在实践中展现出了惊人的生成能力。 26 | 27 | ### 扩散模型的本质:时间的可逆性 28 | 29 | 扩散模型最深刻的洞察在于对时间可逆性的利用。在物理学中,许多微观过程都是时间可逆的——如果你能精确地知道系统的状态,理论上可以逆转时间的流向。扩散模型将这一物理直觉转化为算法:如果我们知道噪声是如何一步步添加的,那么就能学会如何一步步去除它。 30 | 31 | 这种可逆性并非显而易见。在宏观世界中,我们看到的大多是不可逆过程:墨水滴入水中会扩散,但扩散的墨水不会自发聚集;玻璃杯摔碎了不会自动复原。这是因为宏观过程涉及的粒子数量巨大,精确逆转每个粒子的运动在实践中是不可能的。但在扩散模型的数学框架中,我们处理的是概率分布的演化,而非单个粒子的轨迹。通过学习分布之间的映射关系,我们可以实现宏观上的"时间逆转"。 32 | 33 | 🔬 **研究线索:物理扩散与概率扩散的深层联系** 34 | 扩散模型与物理扩散方程的联系不仅仅是类比。实际上,Fokker-Planck方程和Schrödinger桥问题揭示了两者的数学等价性。Fokker-Planck方程描述了概率密度在朗之万动力学下的演化,而Schrödinger桥问题寻找连接两个概率分布的最优随机过程。这种联系在最优传输理论中有深刻体现,但目前仍缺乏统一的几何理论框架。特别是,如何从信息几何的角度理解扩散过程在概率流形上的测地线性质?PyTorch中的`torchdiffeq.odeint`可用于探索连续时间扩散的数值实现。 35 | 36 | > **定义 1.1(扩散模型)** 37 | > 扩散模型是一类概率生成模型,它定义了两个马尔可夫过程: 38 | > - **前向过程(Forward Process)**:一个固定的马尔可夫链,将数据分布 $q(\mathbf{x}_0)$ 通过逐步添加高斯噪声转换为已知的先验分布(通常是标准高斯分布)。 39 | > - **反向过程(Reverse Process)**:一个参数化的马尔可夫链,学习前向过程的逆过程,从先验分布开始逐步去噪,最终生成数据分布的样本。 40 | > 41 | > 模型的训练目标是最大化数据的对数似然下界,这等价于学习在每个时间步精确预测和去除噪声的能力。 42 | 43 | ## 1.2 扩散模型的数学基础 44 | 45 | 在理解了扩散模型的直观概念后,让我们深入其数学原理。扩散模型的数学框架优雅而深刻,它将看似复杂的生成过程分解为一系列简单的概率变换。我们将从前向扩散过程开始,逐步揭示这个框架的精妙之处。 46 | 47 | ### 1.2.1 前向扩散过程 48 | 49 | 前向过程是扩散模型的第一个关键组成部分。它定义了如何将数据逐步转化为噪声,这个过程必须满足两个关键要求:首先,它必须是可控的,让我们能够精确知道每一步发生了什么;其次,它必须最终将任何数据都转化为相同的简单分布(通常是标准高斯分布)。 50 | 51 | #### 马尔可夫链:一步一步走向混沌 52 | 53 | 给定数据点 $\mathbf{x}\_0 \sim q(\mathbf{x}\_0)$ ,前向过程通过 $T$ 步逐渐添加高斯噪声,定义为一个马尔可夫链: 54 | 55 | $$q(\mathbf{x}\_t | \mathbf{x}\_{t-1}) = \mathcal{N}(\mathbf{x}\_t; \sqrt{1-\beta\_t}\mathbf{x}\_{t-1}, \beta\_t\mathbf{I})$$ 56 | 57 | 让我们仔细解析这个公式的含义。这个条件分布告诉我们,给定第 $t-1$ 步的状态 $\mathbf{x}\_{t-1}$ ,第 $t$ 步的状态 $\mathbf{x}\_t$ 是如何生成的: 58 | 59 | - **均值部分** $\sqrt{1-\beta\_t}\mathbf{x}\_{t-1}$ :我们保留了前一步状态的一部分信息,保留的比例是 $\sqrt{1-\beta\_t}$ 。注意这里使用平方根是为了保持方差的正确缩放。 60 | - **方差部分** $\beta\_t\mathbf{I}$ :我们添加了方差为 $\beta\_t$ 的各向同性高斯噪声。 61 | 62 | 其中 $\{\beta\_t\}\_{t=1}^T$ 是预先设定的噪声调度(noise schedule),控制每一步添加噪声的量。通常 $\beta\_t$ 的值很小(如0.0001到0.02之间),这保证了相邻时间步之间的变化是渐进的。 63 | 64 | 这种设计的巧妙之处在于,它在每一步都在做两件事:削弱原始信号(通过乘以小于1的系数)和添加随机噪声。经过足够多的步骤后,原始信号的影响会指数级衰减,而累积的噪声会主导整个分布。 65 | 66 | #### 重参数化技巧:时间旅行的捷径 67 | 68 | 在实际训练中,如果要采样 $\mathbf{x}\_t$ ,按照马尔可夫链的定义需要从 $\mathbf{x}\_0$ 开始逐步计算到 $\mathbf{x}\_t$ ,这会非常低效。幸运的是,高斯分布的良好性质允许我们使用重参数化技巧,直接从 $\mathbf{x}\_0$ "跳跃"到任意时刻 $t$ : 69 | 70 | $$ \mathbf{x}\_t = \sqrt{\bar{\alpha}\_t}\mathbf{x}\_0 + \sqrt{1-\bar{\alpha}\_t}\boldsymbol{\epsilon}, \quad \boldsymbol{\epsilon} \sim \mathcal{N}(0, \mathbf{I})$$ 71 | 72 | 这个公式的推导基于高斯分布的可加性。让我们通过一个简单的例子来理解:如果 $X \sim \mathcal{N}(\mu\_1, \sigma\_1^2)$ 和 $Y \sim \mathcal{N}(\mu\_2, \sigma\_2^2)$ 是独立的高斯随机变量,那么 $aX + bY \sim \mathcal{N}(a\mu\_1 + b\mu\_2, a^2\sigma\_1^2 + b^2\sigma\_2^2)$ 。 73 | 74 | 应用这个性质,我们可以证明上述重参数化公式等价于条件概率: 75 | 76 | $$q(\mathbf{x}\_t | \mathbf{x}\_0) = \mathcal{N}(\mathbf{x}\_t; \sqrt{\bar{\alpha}\_t}\mathbf{x}\_0, (1-\bar{\alpha}\_t)\mathbf{I})$$ 77 | 78 | 其中 $\alpha\_t = 1 - \beta\_t$ 表示每一步保留的信息比例, $\bar{\alpha}\_t = \prod\_{s=1}^{t}\alpha\_s$ 表示从初始状态到时刻 $t$ 累积保留的信息比例。 79 | 80 | #### 信噪比的演化:从清晰到模糊的定量描述 81 | 82 | 理解前向过程的一个关键视角是信噪比(Signal-to-Noise Ratio, SNR)。在时刻 $t$ ,数据的信噪比可以定义为: 83 | 84 | $$\text{SNR}(t) = \frac{\text{Signal Power}}{\text{Noise Power}} = \frac{\bar{\alpha}\_t}{1-\bar{\alpha}\_t}$$ 85 | 86 | 这个比值直观地刻画了原始信号和噪声的相对强度。当 $t=0$ 时, $\text{SNR}(0) = \infty$ (纯信号,无噪声);当 $t \to T$ 且 $\bar{\alpha}\_T \to 0$ 时, $\text{SNR}(T) \to 0$ (纯噪声,无信号)。 87 | 88 | 在对数尺度下观察SNR特别有意义: $\log \text{SNR}(t) = \log \bar{\alpha}\_t - \log(1-\bar{\alpha}\_t)$ 。好的噪声调度应该使得 $\log \text{SNR}(t)$ 近似线性下降,这样可以保证: 89 | 1. 模型在各个时间步面临相似难度的去噪任务 90 | 2. 训练过程中各个时间步的梯度贡献较为均衡 91 | 3. 避免某些时间步的信息损失过快或过慢 92 | 93 | 当 $t \to T$ 时,若设计得当使 $\bar{\alpha}\_T \to 0$ ,则 $\mathbf{x}\_T$ 的分布将趋向于各向同性的标准高斯分布 $\mathcal{N}(0, \mathbf{I})$ ,完全独立于原始数据 $\mathbf{x}\_0$ 。这正是我们想要的:无论起点是什么样的复杂数据,终点都是相同的简单分布。 94 | 95 | 💡 **开放问题:最优噪声调度的理论基础** 96 | 虽然实践中余弦调度效果良好,但缺乏理论指导原则。信息论视角下,噪声调度应该如何与数据的固有维度相适应?是否存在数据相关的自适应调度算法? 97 | 98 | 🌟 **理论空白:扩散速度的几何含义** 99 | 前向扩散过程在数据流形上的速度场有何几何意义?与Ricci流的联系如何?这个联系源于两者都描述了几何结构的演化:Ricci流通过 $\frac{\partial g\_{ij}}{\partial t} = -2R\_{ij}$ 使流形曲率均匀化,最终趋向常曲率空间;而扩散过程使数据分布从复杂流形逐渐"展平"到各向同性高斯分布。两者都涉及从复杂几何到简单几何的演化,且都可用PDE描述。理解这种深层联系可能启发新的采样算法,例如利用流形的曲率信息来设计自适应的噪声调度。 100 | 101 |
102 | **练习 1.1:分析噪声调度** 103 | 104 | 考虑一个线性噪声调度: $\beta\_t = \beta\_{min} + \frac{t-1}{T-1}(\beta\_{max} - \beta\_{min})$ ,其中 $T=1000$ , $\beta\_{min}=10^{-4}$ , $\beta\_{max}=0.02$ 。 105 | 106 | 1. **推导与分析**:推导信噪比 (Signal-to-Noise Ratio, SNR) $\text{SNR}(t) = \frac{\bar{\alpha}\_t}{1-\bar{\alpha}\_t}$ 的表达式。分析其随时间 $t$ 的变化趋势,并解释为什么在对数尺度下观察SNR更有意义。 107 | 2. **开放探索**:比较线性和余弦调度对整个扩散过程中信息损失速率的影响。哪种调度在过程的早期/晚期损失更多信息?这如何影响模型的学习难度和最终生成质量? 108 | 3. **研究思路**: 109 | * **信息瓶颈视角的噪声调度分析**:信息瓶颈(Information Bottleneck)理论最小化 $\mathcal{L} = I(X;Z) - \beta I(Z;Y)$ ,其中 $Z$ 是压缩表示。在扩散模型中, $\mathbf{x}\_t$ 可视为 $\mathbf{x}\_0$ 的压缩表示,互信息 $I(\mathbf{x}\_0; \mathbf{x}\_t) = \frac{1}{2}\log\frac{1}{1-\bar{\alpha}\_t}$ 随时间递减。理想的噪声调度应该:(1) 在早期保留语义信息(高层特征),在后期才丢失细节;(2) 使信息损失率 $-\frac{dI}{dt}$ 尽可能恒定,避免某些时刻的学习困难;(3) 考虑数据的固有维度 $d\_{intrinsic}$ ,高维数据可能需要更平缓的调度。这启发我们设计自适应调度: $\beta\_t = f(I(\mathbf{x}\_0; \mathbf{x}\_t), d\_{intrinsic})$ 。 110 | * 研究噪声调度与模型架构(如U-Net的不同层)之间的相互作用。 111 | * 探索变分方法,将噪声调度本身作为可学习的参数。 112 | 113 |
114 | 115 | ### 1.2.2 反向去噪过程 116 | 117 | 如果前向过程是将数据逐步转化为噪声的"破坏"过程,那么反向过程就是扩散模型的"创造"过程——它学习如何从纯噪声中逐步恢复出有意义的数据。这个过程的数学描述既优雅又富有挑战性。 118 | 119 | #### 时间的逆转:从噪声到数据的旅程 120 | 121 | 反向过程的目标是学习条件分布 $p\_\theta(\mathbf{x}\_{t-1} | \mathbf{x}\_t)$ ,即给定时刻 $t$ 的状态,如何推断时刻 $t-1$ 的状态。整个反向过程从纯噪声 $\mathbf{x}\_T \sim \mathcal{N}(0, \mathbf{I})$ 开始,逐步去除噪声,最终生成数据样本 $\mathbf{x}\_0$ 。 122 | 123 | 数学上,反向过程的联合分布可以写作: 124 | 125 | $$p\_\theta(\mathbf{x}\_{0:T}) = p(\mathbf{x}\_T) \prod\_{t=1}^T p\_\theta(\mathbf{x}\_{t-1} | \mathbf{x}\_t)$$ 126 | 127 | 这里的关键洞察是:虽然真实的反向条件分布 $q(\mathbf{x}\_{t-1} | \mathbf{x}\_t)$ 很难直接计算(它依赖于整个数据分布),但我们可以用神经网络来学习近似它。 128 | 129 | #### 高斯假设:简化但不简单 130 | 131 | 为了使问题可解,我们假设每一步的反向过程仍然是高斯分布: 132 | 133 | $$p\_\theta(\mathbf{x}\_{t-1} | \mathbf{x}\_t) = \mathcal{N}(\mathbf{x}\_{t-1}; \boldsymbol{\mu}\_\theta(\mathbf{x}\_t, t), \sigma\_t^2\mathbf{I})$$ 134 | 135 | 这个假设看似限制性很强,但实际上有深刻的理论基础: 136 | 1. 当 $\beta\_t$ 足够小时,真实的反向过程确实近似高斯分布 137 | 2. 高斯分布的参数化简单,只需要学习均值和方差 138 | 3. 高斯分布的采样高效,这对生成过程至关重要 139 | 140 | 其中,均值 $\boldsymbol{\mu}\_\theta(\mathbf{x}\_t, t)$ 由一个参数化的神经网络(通常是U-Net或Transformer)预测。这个网络接收当前的噪声图像 $\mathbf{x}\_t$ 和时间步 $t$ 作为输入,输出去噪后的均值。 141 | 142 | #### 均值参数化的艺术 143 | 144 | 有趣的是,预测均值 $\boldsymbol{\mu}\_\theta(\mathbf{x}\_t, t)$ 有多种等价的参数化方式,每种方式都有其独特的视角: 145 | 146 | 1. **直接预测均值**:网络直接输出 $\boldsymbol{\mu}\_\theta(\mathbf{x}\_t, t)$ 147 | 2. **预测原始数据**:网络预测 $\mathbf{x}\_0$ ,然后通过贝叶斯公式计算均值 148 | 3. **预测噪声**:网络预测添加的噪声 $\boldsymbol{\epsilon}$ ,这是DDPM采用的方式 149 | 150 | 第三种方式特别优雅。回忆重参数化公式 $\mathbf{x}\_t = \sqrt{\bar{\alpha}\_t}\mathbf{x}\_0 + \sqrt{1-\bar{\alpha}\_t}\boldsymbol{\epsilon}$ ,如果我们能预测出噪声 $\boldsymbol{\epsilon}$ ,就可以恢复出 $\mathbf{x}\_0$ : 151 | 152 | $$\hat{\mathbf{x}}\_0 = \frac{\mathbf{x}\_t - \sqrt{1-\bar{\alpha}\_t}\boldsymbol{\epsilon}\_\theta(\mathbf{x}\_t, t)}{\sqrt{\bar{\alpha}\_t}}$$ 153 | 154 | 这种参数化的优势在于: 155 | - 噪声预测在不同时间步的尺度较为一致 156 | - 与基于分数的生成模型有深刻联系(将在第4章详述) 157 | - 实践中训练更稳定,收敛更快 158 | 159 | #### 方差的选择:固定还是学习? 160 | 161 | 方差 $\sigma\_t^2$ 的选择是一个微妙的设计决策: 162 | 163 | **固定方差策略**(DDPM采用): 164 | - 设置 $\sigma\_t^2 = \beta\_t$ 或 $\sigma\_t^2 = \frac{1-\bar{\alpha}\_{t-1}}{1-\bar{\alpha}\_t}\beta\_t$ 165 | - 这些选择基于在已知 $\mathbf{x}\_0$ 时的真实后验方差 166 | - 简单且计算高效,不需要额外的网络输出 167 | 168 | **学习方差策略**(Improved DDPM等): 169 | - 网络同时预测均值和方差(或对数方差) 170 | - 可以更好地建模数据的不确定性 171 | - 在某些任务上可以提升生成质量,但增加了优化难度 172 | 173 | ⚡ **实现挑战:方差参数化的选择** 174 | 固定方差vs学习方差是一个未解决的权衡问题。理论上,最优的方差应该反映模型在每个位置和时间步的不确定性。但实践中,学习方差可能导致训练不稳定。一个折中方案是学习方差的插值系数:$\sigma\_t^2 = \exp(v\_\theta \log \beta\_t + (1-v\_\theta) \log \tilde{\beta}\_t)$,其中 $v\_\theta \in [0,1]$ 由网络预测。这涉及到`torch.nn.Parameter`的灵活使用和梯度流的稳定性分析。 175 | 176 | #### 贝叶斯视角:后验推断的优雅 177 | 178 | 从贝叶斯推断的角度看,反向过程实际上是在做后验推断。如果我们知道 $\mathbf{x}\_0$ ,那么真实的后验分布 $q(\mathbf{x}\_{t-1} | \mathbf{x}\_t, \mathbf{x}\_0)$ 有闭式解: 179 | 180 | $$q(\mathbf{x}\_{t-1} | \mathbf{x}\_t, \mathbf{x}\_0) = \mathcal{N}(\mathbf{x}\_{t-1}; \tilde{\boldsymbol{\mu}}\_t(\mathbf{x}\_t, \mathbf{x}\_0), \tilde{\beta}\_t \mathbf{I})$$ 181 | 182 | 其中后验均值和方差为: 183 | $$\tilde{\boldsymbol{\mu}}\_t(\mathbf{x}\_t, \mathbf{x}\_0) = \frac{\sqrt{\bar{\alpha}\_{t-1}}\beta\_t}{1-\bar{\alpha}\_t}\mathbf{x}\_0 + \frac{\sqrt{\alpha\_t}(1-\bar{\alpha}\_{t-1})}{1-\bar{\alpha}\_t}\mathbf{x}\_t$$ 184 | 185 | $$\tilde{\beta}\_t = \frac{1-\bar{\alpha}\_{t-1}}{1-\bar{\alpha}\_t} \beta\_t$$ 186 | 187 | 这个公式揭示了一个重要事实:如果我们能准确预测 $\mathbf{x}\_0$ (或等价地,预测噪声 $\boldsymbol{\epsilon}$ ),就能计算出最优的去噪方向。这正是神经网络需要学习的核心能力。 188 | 189 |
190 | **练习 1.2:探索扩散过程的数学本质** 191 | 192 | 考虑一个简单的一维扩散过程,初始数据为单点 $x\_0$ 。 193 | 194 | 1. **前向过程分析**:推导任意时刻 $t$ 的期望 $\mathbb{E}[x\_t | x\_0]$ 和方差 $\text{Var}(x\_t | x\_0)$ 。 195 | 2. **信息论视角**:推导并分析互信息 $I(x\_t; x\_0)$ 如何随时间 $t$ 衰减。这对于理解扩散过程中的信息损失有何启示? 196 | 3. **最优反向过程**:证明当 $\beta\_t \to 0$ 时,真实的反向过程条件分布 $q(\mathbf{x}\_{t-1} | \mathbf{x}\_t, \mathbf{x}\_0)$ 的均值,可以仅由 $\mathbf{x}\_t$ 和 $\nabla\_{\mathbf{x}\_t} \log q\_t(\mathbf{x}\_t)$ (即分数函数)来近似表达。这揭示了扩散模型与分数模型的深刻联系(将在第4章详细讨论)。 197 | 4. **研究思路**: 198 | * 将1D高斯情况下的解析解作为理解高维、复杂数据分布上扩散过程的"玩具模型"。 199 | * 探索非高斯噪声(如Laplace或Student's-t分布)对前向和反向过程的影响。 200 | * 研究该过程与Ornstein-Uhlenbeck过程的联系。 201 | 202 |
203 | 204 | ### 1.2.3 训练目标:变分下界的优雅 205 | 206 | 扩散模型的训练目标源于最大似然估计。给定观测数据 $\mathbf{x}_0$ ,我们希望最大化其在模型下的对数似然 $\log p_\theta(\mathbf{x}_0)$ 。由于直接计算这个似然涉及对所有可能的扩散路径进行积分,在计算上是不可行的。因此,我们转而优化其变分下界(Evidence Lower Bound, ELBO)。 207 | 208 | 通过巧妙的数学推导,ELBO可以分解为一系列更简单的项。最终,DDPM将复杂的优化问题简化为一个优雅的去噪目标: 209 | 210 | $$L_{\text{simple}} = \mathbb{E}_{t, \mathbf{x}_0, \boldsymbol{\epsilon}} \left[ \|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\|^2 \right]$$ 211 | 212 | 其中 $t$ 从 $\{1, ..., T\}$ 均匀采样, $\boldsymbol{\epsilon} \sim \mathcal{N}(0, \mathbf{I})$ 是添加的噪声, $\mathbf{x}_t$ 是通过重参数化得到的噪声数据。 213 | 214 | 这个损失函数的美妙之处在于其简单性: 215 | - **直观解释**:网络学习预测在每个时间步添加的噪声 216 | - **计算高效**:每次只需要采样一个时间步,而不是整个轨迹 217 | - **梯度稳定**:L2损失提供了平滑的梯度信号 218 | 219 | 🌟 **理论空白:扩散速度的几何含义** 220 | 前向扩散过程在数据流形上的速度场有何几何意义?与Ricci流的联系如何?这个联系源于两者都描述了几何结构的演化:Ricci流通过 $\frac{\partial g\_{ij}}{\partial t} = -2R\_{ij}$ 使流形曲率均匀化,最终趋向常曲率空间;而扩散过程使数据分布从复杂流形逐渐"展平"到各向同性高斯分布。两者都涉及从复杂几何到简单几何的演化,且都可用PDE描述。理解这种深层联系可能启发新的采样算法,例如利用流形的曲率信息来设计自适应的噪声调度。 221 | 222 | ### 1.2.4 采样过程:从理论到实践 223 | 224 | 训练完成后,我们可以通过反向过程生成新的样本。采样算法从标准高斯噪声开始,迭代应用学习到的去噪网络: 225 | 226 | 1. 采样初始噪声: $\mathbf{x}_T \sim \mathcal{N}(0, \mathbf{I})$ 227 | 2. 对于 $t = T, T-1, ..., 1$ : 228 | - 如果 $t > 1$ ,添加噪声: $\mathbf{z} \sim \mathcal{N}(0, \mathbf{I})$ 229 | - 否则: $\mathbf{z} = \mathbf{0}$ 230 | - 应用去噪步骤: $\mathbf{x}_{t-1} = \frac{1}{\sqrt{\alpha_t}}(\mathbf{x}_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)) + \sigma_t \mathbf{z}$ 231 | 232 | 这个采样过程展现了扩散模型的核心魅力:通过学习去噪,我们实现了生成。每一步去噪都在逐渐揭示数据的结构,就像雕塑家从大理石中雕刻出雕像一样。 233 | 234 | ## 1.3 扩散模型的优势 235 | 236 | 扩散模型在生成模型领域的崛起并非偶然。它解决了许多困扰早期生成模型的核心问题,同时带来了新的可能性。让我们深入分析扩散模型的独特优势,理解为什么它能够在短时间内成为生成AI的主流选择。 237 | 238 | ### 生成质量:细节的胜利 239 | 240 | 扩散模型最引人注目的优势是其卓越的生成质量。在FID(Fréchet Inception Distance)、IS(Inception Score)等标准评测指标上,扩散模型consistently超越了GAN。但更重要的是,扩散模型在生成细节方面的表现尤为出色: 241 | 242 | - **纹理保真度**:扩散模型能够生成极其精细的纹理,如皮肤的毛孔、织物的纹理、水面的涟漪等 243 | - **全局一致性**:生成的图像在全局结构上保持良好的一致性,避免了GAN常见的局部伪影 244 | - **多样性保持**:能够捕获数据分布的全部模态,而不是像某些GAN那样只关注高概率区域 245 | 246 | 这种质量优势源于扩散模型的渐进式生成过程。不同于GAN的一步到位,扩散模型通过数百甚至上千步的迭代细化,每一步都在改善生成质量。这种"慢工出细活"的方式虽然计算成本较高,但换来了无与伦比的生成质量。 247 | 248 | ### 训练稳定性:告别模式崩塌 249 | 250 | 如果你曾经训练过GAN,一定对其训练的不稳定性深有体会。生成器和判别器之间的对抗博弈常常导致: 251 | 252 | - **模式崩塌(Mode Collapse)**:生成器只学会生成少数几种样本 253 | - **梯度消失/爆炸**:判别器过强或过弱都会导致训练失败 254 | - **超参数敏感性**:微小的超参数变化可能导致完全不同的结果 255 | 256 | 扩散模型彻底改变了这一局面。其训练目标是一个简单的去噪任务,没有对抗网络的不稳定性: 257 | 258 | $$L = \mathbb{E}_{t, \mathbf{x}_0, \boldsymbol{\epsilon}} \left[ \|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\|^2 \right]$$ 259 | 260 | 这个L2损失函数: 261 | - **梯度平滑**:提供稳定的梯度信号,不会出现梯度消失或爆炸 262 | - **无需平衡**:不需要精心平衡两个网络的训练速度 263 | - **收敛可预测**:损失曲线平滑下降,训练进度清晰可见 264 | 265 | ### 理论基础:概率论的优雅 266 | 267 | 扩散模型建立在坚实的概率论基础之上。每个设计选择都有明确的理论依据: 268 | 269 | 1. **变分推断框架**:模型优化的是数据似然的变分下界(ELBO),这是一个有明确统计意义的目标 270 | 2. **与物理过程的联系**:前向过程对应于物理中的扩散现象,反向过程对应于时间反演 271 | 3. **与最优传输的联系**:扩散路径可以视为连接数据分布和噪声分布的传输路径 272 | 273 | 这种理论基础带来的好处是: 274 | - **可解释性强**:模型的每个组件都有清晰的概率解释 275 | - **改进有方向**:理论分析可以指导模型的改进方向 276 | - **与其他方法的桥梁**:容易与分数匹配、流模型等其他方法建立联系 277 | 278 | ### 灵活性:一个框架,多种应用 279 | 280 | 扩散模型的框架极其灵活,可以轻松适应各种生成任务: 281 | 282 | **条件生成**:通过在去噪网络中注入条件信息,可以实现: 283 | - 文本到图像生成(如DALL-E 2、Stable Diffusion) 284 | - 图像到图像翻译 285 | - 类别条件生成 286 | - 多模态生成 287 | 288 | **图像编辑**:利用扩散模型的迭代特性,可以实现: 289 | - 图像修复(inpainting) 290 | - 超分辨率 291 | - 风格迁移 292 | - 语义编辑 293 | 294 | **精确似然估计**:不同于GAN,扩散模型可以: 295 | - 计算数据的精确似然下界 296 | - 进行异常检测 297 | - 模型比较和选择 298 | 299 | ### 可控性:精确控制生成过程 300 | 301 | 扩散模型提供了前所未有的生成控制能力: 302 | 303 | 1. **引导强度控制**:通过调整classifier-free guidance的强度,可以在多样性和质量之间权衡 304 | 2. **中间状态访问**:可以在任意时间步查看和修改生成过程 305 | 3. **噪声控制**:通过控制初始噪声和采样随机性,可以精确控制生成结果 306 | 307 | 这种可控性在实际应用中极为重要,使得扩散模型不仅是研究工具,更是实用的生产力工具。 308 | 309 | 🔬 **研究前沿:效率与质量的平衡** 310 | 尽管扩散模型有诸多优势,但其主要劣势是采样速度慢。当前的研究热点包括: 311 | - **蒸馏方法**:将多步扩散模型蒸馏为少步模型 312 | - **并行采样**:设计可以并行执行的采样算法 313 | - **自适应步数**:根据生成难度动态调整采样步数 314 | 这些方向都试图在保持生成质量的同时提高效率,是未来发展的关键。 315 | 316 | ## 1.4 历史发展与里程碑 317 | 318 | 扩散模型的发展并非一蹴而就,而是经历了一个从理论探索到实践突破的漫长过程。 319 | 320 | - **2015年**:Sohl-Dickstein等人在论文《Deep Unsupervised Learning using Nonequilibrium Thermodynamics》中首次提出了扩散概率模型的思想,将其与非平衡热力学联系起来。 321 | - **2020年**:Ho等人提出的DDPM(Denoising Diffusion Probabilistic Models)是该领域的转折点。他们通过简化目标函数和架构设计,极大地提升了模型的生成质量和易用性,使其成为主流的生成模型。 322 | - **2021年**:Song等人提出的DDIM(Denoising Diffusion Implicit Models)通过构建非马尔可夫的前向过程,实现了比DDPM快10-100倍的采样速度,同时保持了高质量的生成结果。 323 | - **2022年**:Rombach等人提出的潜在扩散模型(Latent Diffusion Models, LDM),即Stable Diffusion的核心,通过在低维潜在空间中进行扩散,大幅降低了计算成本,使得高分辨率图像生成变得触手可及。 324 | - **2023年**:Peebles和Xie提出的DiT(Diffusion Transformer)标志着扩散模型架构的重大转变。他们证明了纯Transformer架构可以替代U-Net,并且展现出卓越的缩放特性(scaling properties)。DiT-XL/2在256×256 ImageNet上达到2.27 FID,证明了扩散模型也遵循大模型的缩放定律:随着模型参数、训练数据和计算量的增加,生成质量可预测地提升。这一发现直接推动了Sora、Stable Diffusion 3等大规模视频和图像生成模型的诞生。 325 | 326 | 🔬 **历史视角的研究机会** 327 | 早期基于热力学的方法与现代DDPM的联系尚未完全被挖掘。非平衡统计物理中的Jarzynski恒等式或Crooks涨落定理(Fluctuation Theorems)能否为理解反向过程、设计新的损失函数或采样策略提供新的理论洞察? 328 | 329 | ## 1.5 本章小结 330 | 331 | 在本章中,我们对扩散模型进行了初步的探索: 332 | 333 | - **核心概念**:理解了扩散模型通过“加噪”和“去噪”两个对称过程进行生成建模的基本思想。 334 | - **数学基础**:学习了前向过程的数学表述,特别是如何通过重参数化技巧直接对任意时间步的噪声样本进行采样。 335 | - **关键组件**:初步了解了反向去噪过程、噪声调度和网络参数化的基本概念。 336 | - **模型优势与历史**:认识到扩散模型在生成质量和训练稳定性上的优势,并回顾了其发展的关键里程碑。 337 | 338 | 通过本章的学习,我们已经掌握了扩散模型的基本词汇和核心思想。下一章,我们将深入学习U-Net和Transformer这两种在扩散模型中至关重要的神经网络架构,为后续理解模型的具体实现打下基础。 339 | 340 |
341 | **综合练习:噪声调度的理论分析** 342 | 343 | 考虑三种常见的噪声调度策略: 344 | - **线性调度**: $\beta\_t = \beta\_{\text{start}} + \frac{t-1}{T-1}(\beta\_{\text{end}} - \beta\_{\text{start}})$ 345 | - **余弦调度**: $\bar{\alpha}\_t = f(t)/f(0)$ ,其中 $f(t) = \cos\left(\frac{t/T + s}{1 + s} \cdot \frac{\pi}{2}\right)^2$ 346 | - **二次调度**: $\beta\_t$ 的增长率随 $t$ 呈二次关系。 347 | 348 | **理论分析与开放探索:** 349 | 1. **信噪比分析**:推导并绘制每种调度下信噪比 $\text{SNR}(t) = \bar{\alpha}\_t / (1 - \bar{\alpha}\_t)$ 的对数曲线。比较不同曲线的形状,并讨论其对模型学习过程可能产生的影响(例如,模型在哪些阶段需要学习更精细的细节?)。 350 | 2. **与最优传输的联系**:噪声调度定义了从数据分布到噪声分布的路径。这与最优传输(Optimal Transport)理论中的位移插值(displacement interpolation)有何联系?是否存在一个“最优”的调度方案,可以最小化某种传输成本? 351 | 3. **实现挑战:自适应噪声调度**:能否设计一个根据数据特性(如复杂度、固有维度)或训练阶段动态调整的噪声调度?这可能需要在线估计数据的局部几何性质。`torch.autograd.functional.jacobian`可用于计算此类局部几何量。 352 | 4. **理论空白:噪声调度与采样效率**:不同的噪声调度对DDIM等快速采样算法的影响机制尚不清楚。是否存在专门为快速采样(而非最优训练)设计的噪声调度?这涉及到对ODE/SDE求解器离散化误差的精细分析。 353 | 354 |
355 | 356 | [← 返回目录](index.md) | 第1章 / 共14章 | [下一章 →](chapter2.md) 357 | -------------------------------------------------------------------------------- /chapter3.md: -------------------------------------------------------------------------------- 1 | [← 上一章](chapter2.md) | 第3章 / 共14章 | [下一章 →](chapter4.md) 2 | 3 | # 第3章:去噪扩散概率模型 (DDPM) 4 | 5 | 2020年,Ho等人的论文《Denoising Diffusion Probabilistic Models》是扩散模型发展史上的一个分水岭,它不仅极大地简化了模型的训练过程,更是在多个图像生成基准上达到了与GAN相媲美的生成质量。本章将深入剖析DDPM的数学原理、训练算法和实现细节。通过本章学习,你将掌握DDPM的核心思想,并理解其背后的概率论基础是如何被巧妙地简化为一个优雅的去噪目标的。 6 | 7 | ## 3.1 DDPM的核心思想:简化与统一 8 | 9 | 在DDPM之前,扩散模型虽然理论优雅,但实践起来却充满挑战。早期的扩散模型需要精心设计的推断过程、复杂的变分边界优化,以及难以调试的训练流程。研究者们被困在理论与实践之间的鸿沟中:一方面,扩散模型在理论上具有诸多优势——可解释的概率框架、精确的似然计算、稳定的训练过程;另一方面,实际训练时却面临着收敛慢、生成质量差、超参数敏感等问题。 10 | 11 | DDPM的出现改变了这一切。它的革命性贡献在于:**将复杂的变分推断问题简化为了一个简单直观的去噪任务**。这种简化不是以牺牲理论严谨性为代价的——恰恰相反,DDPM展示了如何通过巧妙的数学变换和参数化选择,在保持理论完整性的同时,获得一个极其简洁的实践框架。 12 | 13 | 要理解DDPM的突破性,我们需要回顾一下早期扩散模型面临的具体困难。在Sohl-Dickstein等人2015年的开创性工作中,训练一个扩散模型需要同时优化多个相互耦合的组件:前向过程的扩散率、反向过程的参数化、以及连接两者的变分边界。这种复杂性不仅使得模型难以训练,更重要的是,它掩盖了扩散模型的核心洞察——**生成的本质是去噪**。 14 | 15 | DDPM的作者们意识到,如果我们愿意做一些合理的假设和简化,整个框架可以变得异常优雅。这些简化并非随意为之,而是基于对问题本质的深刻理解。让我们详细看看这些关键的设计决策: 16 | 17 | > **定义:DDPM的三个关键简化** 18 | > 1. **固定前向过程**:前向加噪过程使用一个预先设定的、固定的方差调度 $\beta_t$ ,无需学习。这避免了早期扩散模型中需要同时学习前向和反向过程的复杂性。 19 | > 2. **简化反向过程**:假设反向去噪过程也是高斯分布,且其方差也是固定的。因此,模型只需要学习高斯分布的均值,将学习目标从整个分布简化为单一参数。 20 | > 3. **重参数化目标**:将学习"去噪后的图像均值"这一困难任务,巧妙地转换为学习"添加到图像中的噪声",极大地稳定了训练过程。 21 | 22 | 这三个简化看似独立,实际上形成了一个相互支撑的体系。固定的前向过程提供了稳定的训练目标,简化的反向过程减少了模型的负担,而噪声预测的参数化则确保了训练的稳定性。它们共同将一个原本复杂的生成建模问题转化为了一个标准的监督学习问题。 23 | 24 | 让我们通过一个直观的比喻来理解这种转化的威力。想象你是一位艺术品修复师,面对一幅被时间侵蚀的古画。传统的方法是试图直接画出缺失的部分——这需要你理解画家的风格、时代背景、绘画技法等复杂知识。而DDPM的方法则是先理解"侵蚀"本身的模式——哪些地方容易褪色、裂纹如何形成、灰尘如何堆积。一旦你理解了破坏的过程,修复就变成了简单地"逆转"这个过程。 25 | 26 | 这种思路的转变带来了实际的好处。在DDPM之前,训练一个高质量的扩散模型可能需要数周的时间和大量的超参数调整。而使用DDPM框架,研究者们发现他们可以用相对简单的设置获得令人惊叹的结果。更重要的是,这种简化并没有限制模型的表达能力——相反,通过让模型专注于学习去噪这一核心任务,DDPM实际上提高了生成质量。 27 | 28 | ### 3.1.1 为什么预测噪声更好? 29 | 30 | 在理解DDPM之前,我们需要先回答一个根本性的问题:为什么预测噪声比预测清晰图像更有效?这个问题的答案涉及深度学习中的一个核心洞察:**匹配简单分布比匹配复杂分布容易得多**。 31 | 32 | 考虑这样一个类比:假设你要训练一个神经网络来完成两个任务之一:(1) 给定一幅被墨水污染的名画,预测原始画作的样子;(2) 给定同样的污染画作,预测墨水的形状和位置。虽然这两个任务在信息论上是等价的(知道其中一个就能推出另一个),但从学习的角度来看,它们的难度截然不同。预测原画需要网络理解艺术风格、构图规则、色彩理论等复杂知识,而预测墨水只需要识别那些不符合画作整体风格的异常模式。 33 | 34 | 这个看似简单的改变是DDPM成功的关键。预测原始图像 $x_0$ 意味着网络需要输出一个具有复杂结构和特定分布的物体,而预测噪声 $\epsilon$ 意味着网络只需要输出一个来自标准正态分布的样本。更深层的原因在于,噪声预测任务具有某种"局部性"——网络可以通过识别局部的不一致性来判断噪声,而无需理解整体的全局结构。 35 | 36 | 让我们从多个角度深入理解这个设计选择的智慧。首先,从**统计学角度**看,标准正态分布是所有分布中最"无信息"的——它的熵最大,没有任何特殊的结构或模式。这意味着预测噪声时,网络不需要记忆或重建任何特定的模式,只需要识别哪些部分偏离了原始数据的统计规律。这种任务的普适性使得网络能够学习到更加通用的去噪原理,而不是过拟合到特定的数据模式。 37 | 38 | 其次,从**优化角度**看,预测噪声提供了更加稳定的梯度信号。当我们训练网络预测 $x_0$ 时,特别是在高噪声水平(大的 $t$ 值)下,网络需要从几乎纯粹的噪声中重建出完整的图像。这就像要求一个人仅凭一片模糊的色块就画出蒙娜丽莎——即使对于强大的神经网络,这也是一个极其困难的任务。网络可能会产生多种合理的预测,导致训练信号混乱,梯度方向不稳定。相反,预测噪声时,网络的任务始终是明确的:识别并提取那些不属于原始数据的成分。 39 | 40 | 第三,从**信息论角度**看,这种参数化方式更好地利用了不同时间步的信息。在前向过程的早期(小的 $t$ ),图像中保留了大量原始信息,噪声相对较少,此时预测噪声相对容易。在前向过程的后期(大的 $t$ ),虽然图像已经高度退化,但噪声占主导地位,预测"大部分都是噪声"仍然是一个合理的策略。这种自然的难度曲线使得网络在所有时间步上都能获得有意义的学习信号。 41 | 42 | > **定义:预测噪声的优势** 43 | > | 方面 | 预测均值 $\mu_\theta$ | 预测噪声 $\epsilon_\theta$ | 44 | > | :--- | :--- | :--- | 45 | > | **输出范围** | 需要匹配数据的复杂分布 | 目标是标准高斯分布(已归一化) | 46 | > | **训练信号** | 随时间步 $t$ 变化剧烈 | 各时间步的训练目标相对一致 | 47 | > | **梯度流** | 在高噪声时可能梯度消失 | 梯度传播更稳定 | 48 | > | **物理意义** | 预测去噪后的图像 | 预测被添加的噪声 | 49 | > | **优化景观** | 多模态、非凸,容易陷入局部最优 | 相对平滑,更容易优化 | 50 | > | **泛化能力** | 需要记忆训练数据的具体模式 | 学习更通用的去噪原理 | 51 | 52 | 让我们从数学角度更深入地理解这种差异。当网络预测 $x_0$ 时,在时间步 $t$ 较大(噪声较多)的情况下,输入 $x_t$ 几乎是纯噪声,网络需要从几乎没有信息的输入中"凭空"生成一个有意义的图像。这就像要求网络成为一个"记忆机器",记住所有可能的图像。相反,当预测噪声 $\epsilon$ 时,网络的任务是识别和分离信号与噪声,这是一个更加well-defined的问题。 53 | 54 | 为了更具体地理解这一点,让我们考虑一个极端情况:当 $t = T$(最后一个时间步)时,$x_T$ 几乎完全是噪声。如果网络需要预测 $x_0$,它面临的是一个一对多的映射问题——同一个噪声输入可能对应无数个可能的原始图像。这种歧义性使得训练信号非常嘈杂,网络很难收敛到一个稳定的解。而如果预测噪声,网络只需要输出"这基本上都是噪声",这是一个明确且合理的答案。 55 | 56 | 更有趣的是,这种参数化选择还影响了网络的**归纳偏置**(inductive bias)。当网络学习预测噪声时,它实际上在学习数据的"负空间"——那些不应该出现在真实数据中的模式。这促使网络发展出对数据结构的隐式理解:平滑的区域不应该有高频噪声,边缘应该是锐利的而不是模糊的,纹理应该具有某种规律性等等。这种通过"排除法"学习的方式,恰好与人类视觉系统处理噪声的方式相似。 57 | 58 | 🔬 **研究线索**:DDPM预测噪声 $\epsilon$ ,而一些后续工作(如Cold Diffusion)则探索直接预测 $x_0$ 。这两种参数化方式的优劣在不同场景下仍有争议。例如,在处理视频时,预测帧间差(类似于噪声)可能比预测完整帧更有效。另一个有趣的研究方向是"v-prediction"(预测 $v = \alpha_t \epsilon - \sigma_t x_0$),它试图在两种参数化之间找到平衡点。Progressive Distillation等工作也展示了在不同的训练阶段切换参数化方式可能带来好处。 59 | 60 | ### 3.1.2 DDPM训练算法概览 61 | 62 | 得益于上述简化,DDPM的训练过程变得异常简洁。这种简洁性不仅体现在代码实现上,更重要的是概念上的清晰:整个训练过程可以被理解为学习一个"通用去噪器"。 63 | 64 | **DDPM训练伪代码** 65 | 1. 从数据集中随机抽取一批原始图像 $x_0$ 。 66 | 2. 为该批次中的每个图像随机选择一个时间步 $t$ (从1到T)。 67 | 3. 从标准正态分布中采样一个噪声 $\epsilon$ 。 68 | 4. 使用闭式解计算 $t$ 时刻的噪声图像 $x_t$ : $x_t = \sqrt{\bar{\alpha}_t} x_0 + \sqrt{1 - \bar{\alpha}_t} \epsilon$ 。 69 | 5. 将 $x_t$ 和 $t$ 输入到神经网络 $\epsilon_\theta$ 中,得到预测的噪声 $\epsilon_{pred}$ 。 70 | 6. 计算损失: $loss = \text{MSE}(\epsilon, \epsilon_{pred})$ 。 71 | 7. 使用梯度下降更新模型参数 $\theta$ 。 72 | 73 | 这个算法的优雅之处在于它的**自监督性质**。与需要配对数据的监督学习不同,DDPM只需要原始数据本身。噪声是我们人为添加的,因此我们知道"正确答案"。这使得DDPM可以充分利用大规模无标注数据集,这是其能够扩展到数十亿参数规模的关键因素之一。 74 | 75 | 这种端到端的去噪训练方式,是DDPM易于实现和训练稳定的核心原因。让我们深入理解这个算法的几个关键设计选择: 76 | 77 | **时间步的随机采样**:为什么要随机选择时间步 $t$,而不是按顺序训练?这个设计确保了网络在所有噪声水平上都能均匀地学习。如果按顺序训练,网络可能会"遗忘"早期学到的知识。随机采样还带来了另一个好处:每个批次中的样本具有不同的噪声水平,这种多样性有助于网络学习更鲁棒的特征表示。 78 | 79 | 更深层的原因涉及到**课程学习**(curriculum learning)的概念。直觉上,我们可能认为应该先让网络学习简单的任务(去除少量噪声),然后逐渐增加难度。然而,实践表明,这种策略在扩散模型中往往适得其反。原因是不同噪声水平的去噪任务需要不同的策略:低噪声时需要精细的局部调整,高噪声时需要全局的结构重建。随机采样迫使网络同时学习所有这些策略,反而产生了更好的泛化能力。 80 | 81 | **闭式解的重要性**:能够直接从 $x_0$ 计算 $x_t$ 是DDPM的一个关键优势。这避免了需要迭代地应用前向过程,大大提高了训练效率。在PyTorch中,这个操作可以通过简单的张量运算实现,如 `torch.randn_like()` 生成噪声,然后进行线性组合。 82 | 83 | 从计算的角度看,这个闭式解将原本的 $O(T)$ 复杂度降低到了 $O(1)$。但更重要的是,它避免了数值误差的累积。如果我们通过迭代应用前向过程来计算 $x_t$,每一步的浮点运算误差都会累积,最终可能导致 $x_t$ 偏离理论分布。闭式解保证了我们始终在正确的分布上进行训练。 84 | 85 | **MSE损失的简单性**:使用均方误差作为损失函数看似平凡,但它恰好对应于高斯分布下的最大似然估计。这种对应关系不是巧合,而是DDPM理论框架的自然结果。更重要的是,MSE损失在所有像素上均匀加权,这促使网络学习全局一致的去噪策略。 86 | 87 | 然而,MSE损失的选择也引发了一些有趣的讨论。在计算机视觉中,我们知道MSE往往不是感知质量的最佳度量——它倾向于产生模糊的结果。但在DDPM的框架下,这个"缺点"反而成了优点。因为网络预测的是噪声而不是图像,模糊性实际上反映了噪声的不确定性。当存在多个合理的去噪方案时,预测它们的平均值(这正是MSE损失所鼓励的)是一个合理的策略。 88 | 89 | 💡 **实践洞察**:在实际实现中,时间步 $t$ 的编码方式对模型性能有显著影响。DDPM使用正弦位置编码(类似于Transformer),将离散的时间步映射到连续的高维表示。这种编码方式不仅提供了时间信息,还隐含地编码了当前的信噪比,帮助网络理解需要去除多少噪声。 90 | 91 | 具体来说,时间编码通常采用如下形式: 92 | - 首先将时间步 $t$ 归一化到 $[0, 1]$ 区间 93 | - 然后应用一组不同频率的正弦和余弦函数 94 | - 最后通过一个小型MLP将编码映射到与特征维度匹配的表示 95 | 96 | 这种编码的好处是它能够表示时间的绝对位置和相对关系,使得网络能够学习到"在时间步200时应该去除中等强度的噪声"这样的模式,同时也能泛化到训练时未见过的时间步(例如在使用DDIM等快速采样方法时)。 97 | 98 | ## 3.2 前向过程:从数据到噪声 99 | 100 | 前向过程是扩散模型的基础,它定义了数据如何逐渐转变为噪声的数学过程。理解前向过程不仅是掌握DDPM的前提,更是洞察扩散模型本质的关键。在这一节中,我们将深入探讨前向过程的数学结构、物理直觉,以及它如何为后续的反向学习奠定基础。 101 | 102 | 从概念上讲,前向过程模拟了一个自然界中普遍存在的现象:**信息的逐渐丢失**。想象一滴墨水落入清水中,起初我们能清晰地看到墨滴的形状和位置,但随着时间推移,墨水逐渐扩散,最终与水完全混合,原始的结构信息完全消失。扩散模型的前向过程正是这个物理过程的数学抽象。 103 | 104 | 前向过程定义了一个固定的马尔可夫链,它逐步将数据分布 $q(x_0)$ 转换为一个已知的先验分布(通常是标准正态分布 $\mathcal{N}(0, I)$ )。数学上,每一步的转移概率定义为: 105 | 106 | $q(\mathbf{x}_t|\mathbf{x}_{t-1}) = \mathcal{N}(\mathbf{x}_t; \sqrt{1-\beta_t}\mathbf{x}_{t-1}, \beta_t\mathbf{I})$ 107 | 108 | 这个看似简单的公式蕴含着深刻的设计智慧。让我们逐一分析其组成部分: 109 | 110 | **均值项 $\sqrt{1-\beta_t}\mathbf{x}_{t-1}$**:这个缩放因子确保了信号在传播过程中的能量守恒。如果没有这个缩放,随着噪声的不断添加,数据的总能量会无限增长。$\sqrt{1-\beta_t}$ 的选择保证了在添加方差为 $\beta_t$ 的噪声后,总方差保持在合理范围内。 111 | 112 | 为了更深入地理解这一点,让我们考虑方差的传播。假设 $x_{t-1}$ 的方差是 $\sigma^2$,那么经过一步前向过程后: 113 | - 缩放后的信号方差:$(1-\beta_t) \cdot \sigma^2$ 114 | - 添加的噪声方差:$\beta_t$ 115 | - 总方差:$(1-\beta_t) \cdot \sigma^2 + \beta_t$ 116 | 117 | 当 $\sigma^2 = 1$(标准化的数据)时,输出的方差仍然是1。这种**方差保持**(variance preserving)的性质不仅使得数学推导更加优雅,也避免了数值计算中的溢出或下溢问题。 118 | 119 | **方差项 $\beta_t\mathbf{I}$**:各向同性的噪声假设简化了理论分析,但也限制了模型的表达能力。这是一个经典的"简单有效"vs"复杂精确"的权衡。后续研究探索了各向异性噪声、结构化噪声等更复杂的前向过程。 120 | 121 | 各向同性噪声的假设意味着我们对图像的每个像素、每个通道添加相同强度的独立噪声。这在某种程度上是不符合真实世界的——例如,图像的边缘区域可能比平滑区域对噪声更敏感,不同颜色通道的噪声特性也可能不同。然而,这种简化带来的好处远大于其局限性:它使得我们可以用单一参数 $\beta_t$ 控制整个加噪过程,极大地简化了超参数调优。 122 | 123 | **马尔可夫性质**:$x_t$ 只依赖于 $x_{t-1}$,而不依赖于更早的历史。这个性质极大地简化了理论推导,使得我们可以使用动态规划的思想来分析整个过程。 124 | 125 | 马尔可夫假设的一个重要含义是:**信息的丢失是单调的**。一旦某些细节在时间步 $t$ 被噪声掩盖,它们就永远无法在后续步骤中恢复(在前向过程中)。这种不可逆性正是我们需要学习反向过程的根本原因——如果前向过程是可逆的,我们就不需要神经网络了。 126 | 127 | ### 3.2.1 重参数化技巧 128 | 129 | DDPM的一个关键数学技巧是,我们可以直接从 $x_0$ 采样任意时刻的 $x_t$ ,而无需迭代计算。这个技巧不仅是计算效率的关键,更揭示了扩散过程的一个深刻性质:**整个前向过程可以被视为一个线性高斯系统**。 130 | 131 | > **定理:闭式采样公式** 132 | > 定义 $\alpha_t = 1 - \beta_t$ 和 $\bar{\alpha}_t = \prod_{s=1}^{t} \alpha_s$ ,则: 133 | > $q(\mathbf{x}_t|\mathbf{x}_0) = \mathcal{N}(\mathbf{x}_t; \sqrt{\bar{\alpha}_t}\mathbf{x}_0, (1-\bar{\alpha}_t)\mathbf{I})$ 134 | > 135 | > 这个公式可以等价地写成重参数化形式: 136 | > $\mathbf{x}_t = \sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}, \quad \boldsymbol{\epsilon} \sim \mathcal{N}(0, \mathbf{I})$ 137 | 138 | 这个闭式公式的推导虽然基于简单的高斯分布性质,但其意义深远。让我们通过一个具体的推导来理解这个过程: 139 | 140 | **推导过程**:从 $x_0$ 到 $x_1$:$x_1 = \sqrt{\alpha_1}x_0 + \sqrt{\beta_1}\epsilon_1$。从 $x_1$ 到 $x_2$:$x_2 = \sqrt{\alpha_2}x_1 + \sqrt{\beta_2}\epsilon_2 = \sqrt{\alpha_2}(\sqrt{\alpha_1}x_0 + \sqrt{\beta_1}\epsilon_1) + \sqrt{\beta_2}\epsilon_2$。 141 | 142 | 关键洞察是,两个独立高斯噪声的线性组合仍然是高斯噪声。通过仔细计算方差,我们可以证明:$x_2 = \sqrt{\alpha_1\alpha_2}x_0 + \sqrt{1-\alpha_1\alpha_2}\tilde{\epsilon}$,其中 $\tilde{\epsilon}$ 是一个新的标准高斯噪声。 143 | 144 | 这个推导过程揭示了一个更深层的数学结构。让我们详细展开 $x_2$ 的表达式: 145 | $x_2 = \sqrt{\alpha_2}\sqrt{\alpha_1}x_0 + \sqrt{\alpha_2}\sqrt{\beta_1}\epsilon_1 + \sqrt{\beta_2}\epsilon_2$ 146 | 147 | 由于 $\epsilon_1$ 和 $\epsilon_2$ 是独立的标准正态随机变量,我们需要找到一个等价的表示。关键是认识到: 148 | - 系数 $\sqrt{\alpha_2}\sqrt{\beta_1}$ 和 $\sqrt{\beta_2}$ 定义了两个正交方向上的噪声强度 149 | - 这两个独立噪声的组合等价于一个具有适当方差的单一噪声 150 | 151 | 通过计算总方差: 152 | $\text{Var}(x_2|x_0) = \alpha_2\beta_1 + \beta_2 = \alpha_2(1-\alpha_1) + (1-\alpha_2) = 1 - \alpha_1\alpha_2$ 153 | 154 | 这正好等于 $1 - \bar{\alpha}_2$,验证了我们的闭式公式。 155 | 156 | **物理直觉**:这个公式告诉我们,无论经过多少步扩散,$x_t$ 始终可以表示为原始信号 $x_0$ 的衰减版本加上一个适当强度的噪声。衰减因子 $\sqrt{\bar{\alpha}_t}$ 描述了信号的保留程度,而 $\sqrt{1-\bar{\alpha}_t}$ 描述了噪声的强度。当 $t \to T$ 时,$\bar{\alpha}_t \to 0$,信号完全消失,只剩下纯噪声。 157 | 158 | 从信号处理的角度看,这个过程可以理解为一个**低通滤波器**加上**白噪声**。随着时间推移,高频细节(如纹理、边缘)首先被破坏,而低频信息(如整体形状、颜色分布)保留得更久。这解释了为什么在中等噪声水平下,我们仍然能够隐约看出图像的大致轮廓。 159 | 160 | **计算优势**:在实际训练中,这个闭式公式允许我们: 161 | - 并行处理不同时间步的样本 162 | - 避免数值误差的累积 163 | - 实现高效的GPU向量化计算 164 | 165 | 更重要的是,这个公式使得训练过程具有极好的**可扩展性**。无论我们选择 $T=1000$ 还是 $T=4000$,计算任意 $x_t$ 的成本都是恒定的。这与许多其他生成模型形成鲜明对比,后者的计算成本往往随着模型复杂度呈超线性增长。 166 | 167 | ### 3.2.2 噪声调度 (Noise Schedule) 168 | 169 | 噪声调度 $\{\beta_t\}$ 的选择对模型性能有重要影响。它决定了信息在前向过程中的衰减速度,直接影响到反向过程的学习难度。一个好的噪声调度应该在以下几个方面取得平衡: 170 | 171 | 1. **信息保留**:早期步骤应该保留足够的原始信息,使得反向过程有据可依 172 | 2. **充分扩散**:最终应该充分接近先验分布,确保生成的多样性 173 | 3. **平滑过渡**:相邻时间步之间的变化应该适度,避免学习任务的突变 174 | 175 | > **定义:调度策略对比** 176 | > | 调度类型 | 特点 | 优势 | 劣势 | 177 | > | :--- | :--- | :--- | :--- | 178 | > | **线性 (Linear)** | $\beta_t$ 从 $\beta_1 = 10^{-4}$ 线性增长到 $\beta_T = 0.02$ | 简单直观,DDPM原始选择,易于实现和调试 | 过程早期破坏信息过快,后期变化又太慢,导致生成质量次优 | 179 | > | **余弦 (Cosine)** | 基于信噪比(SNR)的余弦曲线设计:$\bar{\alpha}_t = \frac{f(t)}{f(0)}$,其中 $f(t) = \cos\left(\frac{t/T + s}{1+s} \cdot \frac{\pi}{2}\right)^2$ | 过程早期缓慢加噪,保留更多结构信息,感知质量显著更好,特别适合高分辨率图像 | 理论相对复杂,超参数 $s$ 需要调整,末期可能收敛过慢 | 180 | > | **二次 (Quadratic)** | $\beta_t$ 呈二次方增长:$\beta_t = \beta_{\min} + (\beta_{\max} - \beta_{\min}) \cdot (t/T)^2$ | 在线性的基础上,进一步减缓早期加噪,中期过渡更平滑 | 后期加噪可能过于激进,需要仔细选择 $\beta_{\max}$ | 181 | > | **对数 (Logarithmic)** | $\beta_t$ 按对数规律增长 | 极其缓慢的早期加噪,适合保留细节丰富的数据 | 可能需要更多的扩散步数才能充分混合 | 182 | 183 | 让我们深入理解为什么余弦调度在实践中表现优异。关键在于**信噪比(SNR)**的概念: 184 | 185 | $\text{SNR}(t) = \frac{\bar{\alpha}_t}{1 - \bar{\alpha}_t}$ 186 | 187 | 线性调度下,log-SNR几乎是线性下降的,这意味着在对数空间中,信息的丢失速度是恒定的。然而,人类的感知系统对信息的敏感度并非线性——我们对高SNR区域(图像清晰时)的变化更敏感。余弦调度通过在高SNR区域放慢变化速度,更好地匹配了这种感知特性。 188 | 189 | **实践经验**: 190 | - 对于64×64的低分辨率图像,线性调度通常足够 191 | - 对于256×256及以上的高分辨率图像,余弦调度几乎总是更好 192 | - 对于特殊数据(如医学图像),可能需要定制调度 193 | 194 | 💡 **开放问题**:是否存在一个"最优"的噪声调度?理论上,最优调度应与数据的内在属性(如维度、复杂度)相关。目前,设计数据自适应的噪声调度或在训练中学习调度本身,仍然是一个活跃的研究领域。一些有趣的方向包括: 195 | - **学习型调度**:让网络自己学习最优的 $\beta_t$ 196 | - **内容感知调度**:根据图像的局部特征(纹理、边缘等)使用不同的噪声强度 197 | - **任务特定调度**:为不同的下游任务(生成、修复、超分)设计专门的调度 198 | 199 |
200 | 练习 3.1:设计与分析噪声调度 201 | 202 | 1. **S形调度设计**:设计一个“S形”的噪声调度,使得加噪过程满足:a) 前期缓慢;b) 中期快速;c) 后期再次放缓。写出其数学表达式。 203 | 2. **信噪比(SNR)分析**:对于线性和余弦调度,推导并绘制其信噪比 $\text{SNR}(t) = \bar{\alpha}_t / (1 - \bar{\alpha}_t)$ 的对数曲线。从曲线形状解释为什么余弦调度通常能取得更好的生成质量。 204 | 3. **研究思路**: 205 | * 从信息论的角度出发,将前向过程视为一个信息通道,分析不同调度下的信道容量变化。 206 | * 探索噪声调度与最优传输理论(Optimal Transport)的联系。前向过程可以看作是从数据分布到噪声分布的一条路径,最优调度是否对应着某种“最短”路径? 207 | 208 |
209 | 210 | ## 3.3 反向过程:从噪声到数据 211 | 212 | 如果说前向过程是将数据逐渐模糊化的过程,那么反向过程就是扩散模型的"魔法"所在——它要学习如何从纯噪声 $x_T$ 逐步恢复出清晰的数据 $x_0$ 。这个过程的优雅之处在于,虽然看似是在"逆转时间",但实际上我们是在学习一个条件概率分布,这个分布告诉我们:给定当前的噪声图像,上一个时间步的图像应该是什么样子。 213 | 214 | 反向过程的核心挑战在于:我们需要学习 $p_\theta(x_{t-1}|x_t)$ ,但这个条件分布是极其复杂的——它需要理解图像的所有可能结构,并能够推断出哪些部分是噪声,哪些部分是信号。DDPM的天才之处在于,通过巧妙的数学推导,将这个看似不可能的任务转化为一个简单的噪声预测问题。 215 | 216 | ### 3.3.1 反向条件概率的推导 217 | 218 | 这是DDPM论文中最重要的数学推导之一,也是理解整个框架的关键。我们将通过贝叶斯定理,证明在已知 $x_0$ 的条件下,反向的条件概率 $q(x_{t-1}|x_t, x_0)$ 也是一个高斯分布。这个结果不仅优雅,更重要的是它为我们的学习任务提供了明确的目标。 219 | 220 | 让我们从贝叶斯定理开始: 221 | $q(x_{t-1}|x_t, x_0) = \frac{q(x_t|x_{t-1}, x_0) q(x_{t-1}|x_0)}{q(x_t|x_0)}$ 222 | 223 | 由于前向过程的马尔可夫性质,$q(x_t|x_{t-1}, x_0) = q(x_t|x_{t-1})$。现在,所有三个项都是已知的高斯分布: 224 | - $q(x_t|x_{t-1}) = \mathcal{N}(x_t; \sqrt{\alpha_t}x_{t-1}, \beta_t I)$ 225 | - $q(x_{t-1}|x_0) = \mathcal{N}(x_{t-1}; \sqrt{\bar{\alpha}_{t-1}}x_0, (1-\bar{\alpha}_{t-1})I)$ 226 | - $q(x_t|x_0) = \mathcal{N}(x_t; \sqrt{\bar{\alpha}_t}x_0, (1-\bar{\alpha}_t)I)$ 227 | 228 | 高斯分布的一个美妙性质是:高斯分布的乘积和除法(在指数空间中)仍然是高斯分布。通过仔细的代数运算,我们可以得出: 229 | 230 | > **定理:反向过程的后验分布** 231 | > $q(\mathbf{x}_{t-1}|\mathbf{x}_t, \mathbf{x}_0) = \mathcal{N}(\mathbf{x}_{t-1}; \tilde{\boldsymbol{\mu}}_t(\mathbf{x}_t, \mathbf{x}_0), \tilde{\beta}_t\mathbf{I})$ 232 | > 233 | > 其中: 234 | > - 后验均值:$\tilde{\boldsymbol{\mu}}_t(\mathbf{x}_t, \mathbf{x}_0) = \frac{\sqrt{\bar{\alpha}_{t-1}}\beta_t}{1-\bar{\alpha}_t}\mathbf{x}_0 + \frac{\sqrt{\alpha_t}(1-\bar{\alpha}_{t-1})}{1-\bar{\alpha}_t}\mathbf{x}_t$ 235 | > - 后验方差:$\tilde{\beta}_t = \frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t$ 236 | 237 | 这个结果的深刻之处在于几个方面: 238 | 239 | 1. **线性组合**:后验均值是 $x_t$ 和 $x_0$ 的线性组合,权重只依赖于噪声调度 240 | 2. **确定性方差**:后验方差 $\tilde{\beta}_t$ 完全由前向过程决定,不依赖于数据 241 | 3. **信息融合**:这个公式可以理解为在 $x_t$(当前观察)和 $x_0$(先验知识)之间的最优贝叶斯融合 242 | 243 | 这个定理的**关键洞察**在于:如果我们能以某种方式从 $x_t$ 中估计出 $x_0$ ,我们就能近似真实的反向过程。这正是神经网络需要做的事情。但是,直接预测 $x_0$ 并不是最优的选择。 244 | 245 | **从 $x_0$ 到 $\epsilon$ 的重参数化** 246 | 247 | 利用前向过程的重参数化公式 $x_t = \sqrt{\bar{\alpha}_t}x_0 + \sqrt{1-\bar{\alpha}_t}\epsilon$,我们可以解出: 248 | $x_0 = \frac{x_t - \sqrt{1 - \bar{\alpha}_t} \epsilon}{\sqrt{\bar{\alpha}_t}}$ 249 | 250 | 将这个表达式代入后验均值公式,经过一番代数运算,我们得到: 251 | $\tilde{\boldsymbol{\mu}}_t(\mathbf{x}_t, \boldsymbol{\epsilon}) = \frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t - \frac{\beta_t}{\sqrt{1-\bar{\alpha}_t}}\boldsymbol{\epsilon}\right)$ 252 | 253 | 这个表达式优雅地揭示了:**学习反向过程等价于学习预测噪声 $\epsilon$**。这不仅是一个数学上的等价变换,更是一个概念上的突破——它将"预测去噪后的图像"这个复杂任务转化为"识别添加的噪声"这个相对简单的任务。 254 | 255 | ### 3.3.2 方差的处理:固定 vs 可学习 256 | 257 | 在确定了均值的参数化后,还有一个重要问题:如何处理反向过程的方差?DDPM采用了一个大胆的简化:固定方差。这个决定背后有深刻的理论和实践考量。 258 | 259 | **理论考量**:后验方差 $\tilde{\beta}_t$ 有一个精确的公式,它是前向过程参数的函数。然而,在实际的反向过程中,我们并不知道真实的 $x_0$,因此无法使用精确的后验方差。DDPM提出了两种近似方案: 260 | 261 | 1. **方案一**:$\sigma_t^2 = \tilde{\beta}_t = \frac{1-\bar{\alpha}_{t-1}}{1-\bar{\alpha}_t} \cdot \beta_t$ (后验方差的精确值) 262 | 2. **方案二**:$\sigma_t^2 = \beta_t$ (更简单的选择) 263 | 264 | 有趣的是,虽然方案一在理论上更精确,但实验表明两种方案的生成质量非常接近。这暗示着反向过程对方差的选择相对不敏感,均值的准确预测才是关键。 265 | 266 | **实践考量**:固定方差大大简化了训练和实现: 267 | - 训练时只需要优化一个目标(预测噪声) 268 | - 避免了多任务学习的复杂性 269 | - 减少了模型的参数量和计算开销 270 | 271 | 后续工作(如Improved DDPM)探索了让网络同时预测均值和方差: 272 | $p_\theta(x_{t-1}|x_t) = \mathcal{N}(x_{t-1}; \mu_\theta(x_t, t), \sigma_\theta^2(x_t, t))$ 273 | 274 | 这种方法可以提高模型的对数似然,但对感知质量的提升往往有限。更重要的是,学习方差引入了新的挑战: 275 | - 需要仔细设计方差的参数化方式(如预测对数方差) 276 | - 需要平衡均值和方差预测的损失权重 277 | - 可能导致训练不稳定 278 | 279 | 对于大多数应用,固定方差是一个优秀的选择,它在简单性和性能之间达到了极好的平衡。 280 | 281 |
282 | 练习 3.2:参数化的等价性与差异 283 | 284 | 1. **数学推导**:从后验均值 $\tilde{\mu}_t(x_t, x_0)$ 的表达式出发,代入 $x_0$ 与 $x_t, \epsilon$ 的关系式,推导出 $\tilde{\mu}_t(x_t, \epsilon)$ 的表达式,从而证明“预测 $x_0$ ”和“预测 $\epsilon$ ”在数学上是等价的。 285 | 2. **稳定性分析**:从优化的角度,分析为什么预测一个目标为 $\mathcal{N}(0, I)$ 的噪声 $\epsilon$ ,比预测一个目标为复杂数据分布 $q(x_0)$ 的 $x_0$ 更稳定?(提示:考虑不同时间步 $t$ 下目标函数的尺度和梯度。) 286 | 3. **开放探索**:DDPM选择固定方差。但在某些情况下,让方差可学习可能很重要。设想一个场景(例如,生成具有不同纹理区域的图像),其中自适应的去噪方差可能带来优势,并解释原因。 287 | 288 |
289 | 290 | ## 3.4 训练目标:从变分下界到简单均方误差 291 | 292 | DDPM的最终妙笔是将复杂的变分下界(Variational Lower Bound, VLB)损失函数简化为一个简单的均方误差(MSE)。 293 | 294 | 完整的VLB损失可以写成三项之和: $L_{\text{VLB}} = L_T + \sum_{t>1} L_{t-1} + L_0$ 。其中 $L_{t-1}$ 是主要的去噪匹配项,可以表示为两个高斯分布(真实后验 $q$ 和模型预测 $p_\theta$ )之间的KL散度。通过我们上面的推导,这一项可以简化为对两个均值 $\tilde{\mu}_t$ 和 $\mu_\theta$ 差值的L2损失。 295 | 296 | > **🎯 DDPM的简化训练目标** 297 | > Ho等人发现,如果忽略VLB损失中复杂的加权系数,直接优化一个更简单的目标函数,效果反而更好: 298 | > $L_{\text{simple}} = \mathbb{E}_{t,\mathbf{x}_0,\boldsymbol{\epsilon}}\left[\|\boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\|^2\right]$ 299 | > 这就是DDPM最终的训练目标:**在随机的时间步 $t$ ,让神经网络 $\epsilon_\theta$ 预测出添加到 $x_0$ 上的原始噪声 $\epsilon$ **。 300 | 301 | ⚡ **实现挑战与研究前沿**:虽然简单损失效果很好,但它对所有时间步 $t$ 的误差一视同仁。后续研究(如Min-SNR- $\gamma$ 加权策略)表明,对不同 $t$ 的损失进行加权(例如,降低高信噪比、即低噪声区域的损失权重)可以显著提高生成质量,尤其是在高分辨率生成任务中。 302 | 303 | ## 3.5 采样算法:从理论到实践 304 | 305 | 训练完成后,我们就可以从随机噪声中生成图像了。采样过程是反向过程的实际执行。 306 | 307 | **DDPM标准采样算法** 308 | 1. 从标准正态分布中采样一个初始噪声图像 $x_T$ 。 309 | 2. 从 $t = T$ 循环到 $t = 1$ : 310 | a. 将当前的 $x_t$ 和时间步 $t$ 输入模型,得到噪声预测 $\epsilon_\theta(x_t, t)$ 。 311 | b. 使用 $\epsilon_\theta$ 和 $x_t$ 计算去噪后的均值 $\mu_\theta(x_t, t)$ 。 312 | c. 从标准正态分布中采样一个随机噪声 $z$ 。 313 | d. 计算 $x_{t-1} = \mu_\theta(x_t, t) + \sigma_t z$ 。(其中 $\sigma_t$ 是固定的方差) 314 | 3. 最终得到的 $x_0$ 就是生成的图像。 315 | 316 | 这个迭代过程通常需要1000步,因此速度较慢,这是DDPM的主要缺点之一,也催生了后续大量的快速采样算法研究(将在第8章讨论)。 317 | 318 |
319 | 综合练习:DDPM的局限性与改进方向 320 | 321 | DDPM虽然强大,但并非完美。请分析其潜在的局限性,并为每个局限性提出一个可能的研究方向或改进思路。 322 | 323 | 1. **局限一:采样速度慢**。标准DDPM需要上千步迭代。 324 | * **改进思路**:?(提示:反向过程是否必须是马尔可夫的?) 325 | 2. **局限二:高斯假设**。整个框架基于高斯噪声和高斯转移核。 326 | * **改进思路**:?(提示:对于某些具有特定结构噪声的数据,如JPEG压缩伪影,非高斯噪声是否更合适?) 327 | 3. **局限三:固定的前向过程**。前向过程与数据无关。 328 | * **改进思路**:?(提示:能否设计一个依赖于数据内容的前向过程,例如,在图像的平滑区域加更多噪声,在纹理区域加更少噪声?) 329 | 4. **研究思路**: 330 | * 阅读DDIM、DEIS等快速采样算法的论文。 331 | * 查阅关于非高斯扩散或泊松流生成模型(PFGM)的研究。 332 | * 探索将扩散模型与自编码器结合(如LDM)或与最优传输理论结合的工作。 333 | 334 |
335 | 336 | ## 本章小结 337 | 338 | 在本章中,我们深入剖析了DDPM的内部工作原理: 339 | - **核心思想**:通过将复杂的变分下界目标简化为预测噪声的均方误差,DDPM极大地简化了扩散模型的训练。 340 | - **数学推导**:我们理解了前向过程的闭式解、反向过程的后验分布,以及它们如何共同导出了最终的简化损失函数。 341 | - **关键组件**:我们分析了噪声调度、网络参数化(预测噪声vs预测图像)、方差选择等关键设计决策的重要性。 342 | - **训练与采样**:我们掌握了DDPM的完整训练和采样算法流程。 343 | 344 | DDPM为后续扩散模型的发展奠定了坚实的基础。下一章,我们将从另一个角度——分数匹配(Score Matching)——来理解扩散过程,并看到这两个看似不同的框架如何最终在统一的SDE/PDE视角下完美融合。 345 | -------------------------------------------------------------------------------- /html/appendix-a.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 附录A:测度论与随机过程速成 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 |
32 | 195 | 196 |
197 |
198 |

← 返回目录 | 附录A | 附录B →

199 |

附录A:测度论与随机过程速成

200 |

本附录为理解第5章(连续时间扩散模型)提供必要的数学基础。我们将快速回顾测度论的核心概念,介绍布朗运动和随机微分方程(SDE)的基本知识。这不是一门完整的数学课程,而是为理解扩散模型所需的最小知识集,旨在建立直觉并熟悉核心工具。

201 |

A.1 测度论基础

202 |

A.1.1 为什么需要测度论?

203 |

让我们从一个简单但深刻的问题开始:在区间[0,1]上随机选一个点,这个点恰好是有理数的概率是多少?

204 |

直觉可能会说:“有理数有无穷多个,所以概率应该不为零。”但实际上,这个概率是0。这个反直觉的结果揭示了我们需要一个比传统集合论更精细的数学框架来处理“无穷”。测度论正是为此而生,它严格定义了“长度”、“面积”、“体积”乃至“概率”等概念。

205 |

A.1.2 σ-代数与测度

206 |
    207 |
  • σ-代数 (σ-algebra): 在一个样本空间 Ω 中,并非所有子集都能被合理地赋予概率。σ-代数 FΩ 的一个子集族,它包含了我们所有感兴趣的“事件”,并对补、可数并等运算封闭。
  • 208 |
  • 测度 (Measure): 测度 μ 是一个定义在σ-代数 F 上的函数,它为每个事件赋予一个非负的“大小”。当 μ(Ω) = 1 时,这个测度就是一个概率测度 P
  • 209 |
210 |
211 |

定义 A.1 (概率空间) 212 | 一个概率空间是一个三元组 (Ω, F, P),其中:

213 |
    214 |
  • Ω 是样本空间(所有可能结果的集合)。
  • 215 |
  • FΩ 上的一个σ-代数(所有可测事件的集合)。
  • 216 |
  • P 是定义在 F 上的一个概率测度。
  • 217 |
218 |
219 |

💡 关键洞察:有理数集的勒贝格测度(长度)为0,是因为虽然有理数是可数无穷的,但每个单点的测度都是0。根据测度的可数可加性,可数个0相加仍然是0。

220 |

A.1.3 随机变量与条件期望

221 |
    222 |
  • 随机变量 (Random Variable): 一个随机变量 X 是一个从样本空间 Ω 到实数 R 的函数,它必须是“可测的”,即对于任何数值区间,我们都能找到其在样本空间中对应的事件。
  • 223 |
  • 滤波 (Filtration): 滤波 {F_t} 是一个随时间 t 递增的σ-代数序列,F_s ⊆ F_t 对所有 s ≤ t 成立。它代表了信息的累积过程,F_t 包含了到时刻 t 为止所有已知的信息。
  • 224 |
  • 条件期望 (Conditional Expectation): E[X | F_t] 代表在已知时刻 t 信息 F_t 的情况下,对随机变量 X 的最优估计。
  • 225 |
226 |
227 | **练习 A.1:σ-代数** 228 |

Ω = {1, 2, 3, 4}

229 |
    230 |
  1. 构造包含事件 A = {1, 2} 的最小σ-代数 σ(A)
  2. 231 |
  3. 如果再加入事件 B = {2, 3},最小σ-代数 σ(A, B) 是什么?
  4. 232 |
233 |

解答:

234 |
    235 |
  1. σ(A) 必须对补运算封闭,所以必须包含 A^c = {3, 4}。同时必须包含全集和空集。因此 σ(A) = {∅, {1, 2}, {3, 4}, {1, 2, 3, 4}}
  2. 236 |
  3. σ(A, B) 必须包含 AB,以及它们的所有交、并、补运算的组合。例如 A ∩ B = {2}A ∪ B = {1, 2, 3}(A ∪ B)^c = {4} 等。最终可以生成 Ω 的幂集(所有16个子集)。
  4. 237 |
238 |
239 |

A.2 布朗运动 (Brownian Motion)

240 |

布朗运动是随机过程理论的基石,也是扩散模型的数学核心。

241 |
242 |

定义 A.2 (标准布朗运动) 243 | 一个随机过程 {B_t} 称为标准布朗运动(或维纳过程),如果:

244 |
    245 |
  1. 起点确定: B_0 = 0
  2. 246 |
  3. 独立增量: 对任意 0 ≤ s < t,增量 B_t - B_s 独立于过去的路径 {B_u : u ≤ s}
  4. 247 |
  5. 高斯增量: B_t - B_s 服从均值为0,方差为 t-s 的正态分布,即 B_t - B_s ~ N(0, t-s)
  6. 248 |
  7. 路径连续: 路径 t ↦ B_t 是连续函数。
  8. 249 |
250 |
251 |

布朗运动的深刻性质:

252 |
    253 |
  • 无处可微: 布朗运动的路径虽然连续,但在任何一点都是不可微的。它的“速度”是无穷的。
  • 254 |
  • 二次变差非零: 在普通微积分中 (dt)^2 = 0,但在随机微积分中,(dB_t)^2 = dt。这是两者最核心的区别,也是伊藤公式中出现修正项的根源。
  • 255 |
  • 鞅 (Martingale): 布朗运动是一个鞅,即 E[B_t | F_s] = B_s for s < t。这意味着对未来的最优预测就是当前的值。
  • 256 |
257 |

A.3 随机积分与伊藤公式

258 |

由于布朗运动的奇异性质,传统的黎曼积分不适用。我们需要一种新的积分理论——随机积分。

259 |

A.3.1 伊藤积分 (Itô Integral)

260 |

伊藤积分 ∫f_s dB_s 的定义在黎曼和中,总是取被积函数在区间的左端点的值。这个选择保证了被积函数 f_s 不会“预见”到噪声 dB_s 的未来,从而使得积分结果仍然是一个鞅。

261 |

理论要点:伊藤积分和另一种常见的斯特拉托诺维奇(Stratonovich)积分(取中点)会导致不同的结果。物理学中常用后者,因为它遵循普通的链式法则。金融和概率论中常用前者,因为它具有鞅性质。扩散模型理论建立在伊藤积分之上。

262 |

A.3.2 伊藤公式 (Itô's Formula)

263 |

伊藤公式是随机微积分的链式法则,是处理SDE最重要的工具。

264 |
265 |

定理 A.3 (伊藤公式) 266 | 设 X_t 满足SDE dX_t = μ_t dt + σ_t dB_tf(x, t) 是一个足够光滑的函数,则: 267 |

268 |
269 |

$$df(X_t, t) = \left(\frac{\partial f}{\partial t} + \mu_t \frac{\partial f}{\partial x} + \frac{1}{2}\sigma_t^2 \frac{\partial^2 f}{\partial x^2}\right)dt + \sigma_t \frac{\partial f}{\partial x} dB_t$$

270 |
271 |

核心区别在于比普通链式法则多出的一项:1/2 * σ_t^2 * ∂^2f/∂x^2,这被称为伊藤修正项,它正是来源于 (dB_t)^2 = dt

272 |
273 |
274 | **练习 A.2:伊藤公式的应用** 275 |
    276 |
  1. 推导:设 B_t 是标准布朗运动,使用伊藤公式计算 d(B_t^3)
  2. 277 |
  3. 证明:证明 M_t = exp(B_t - t/2) 是一个鞅。
  4. 278 |
  5. 研究思路
      279 |
    • 问题1:对 f(x) = x^3 应用伊藤公式,其中 μ_t=0, σ_t=1df = (1/2 * 1^2 * 6B_t)dt + (3B_t^2 * 1)dB_t = 3B_t dt + 3B_t^2 dB_t
    • 280 |
    • 问题2:对 f(x,t) = exp(x - t/2) 应用伊藤公式。df = (-1/2 * f)dt + (0)dt + (1/2 * 1^2 * f)dt + (f * 1)dB_t = f dB_t。由于结果的 dt 项(漂移项)为0,所以它是一个鞅。
    • 281 |
    282 |
  6. 283 |
284 |
285 |

A.4 随机微分方程 (SDEs)

286 |

SDE描述了受随机扰动影响的动态系统,是扩散模型的数学语言。

287 |
288 |

定义 A.4 (SDE) 289 | 一个典型的SDE具有形式:

290 |

$$dX_t = b(X_t, t)dt + \sigma(X_t, t)dB_t$$

291 |
    292 |
  • 漂移项 b(X_t, t): 描述系统的确定性平均行为。
  • 293 |
  • 扩散项 σ(X_t, t): 描述随机波动的强度。
  • 294 |
295 |
296 |

存在唯一性:如果漂移和扩散系数满足Lipschitz连续性和线性增长条件,那么SDE存在唯一的强解。这保证了我们讨论的扩散过程是良定义的。

297 |

A.5 数值方法简介

298 |

大多数SDE没有解析解,需要数值方法来模拟。

299 |
    300 |
  • 301 |

    Euler-Maruyama方法: 最简单的数值格式,直接将SDE离散化: 302 | X_{n+1} = X_n + b(X_n)Δt + σ(X_n) * sqrt(Δt) * Z_n,其中 Z_n ~ N(0, 1)

    303 |
  • 304 |
  • 305 |

    Milstein方法: 更高阶的方法,通过加入一个修正项来获得更高的收敛精度,特别是当扩散系数 σ 不为常数时。

    306 |
  • 307 |
308 |

💡 实践洞察:数值模拟显示,对于扩散系数依赖于状态 X_t 的SDE(例如金融中的一些模型),Milstein方法比Euler-Maruyama方法能更精确地收敛到真实解。对于扩散模型中常见的 σ 只依赖于时间 t 的情况,两种方法的差别不大。

309 |

A.6 与扩散模型的深层联系

310 |

现在,我们可以将这些数学工具与扩散模型联系起来。

311 |

A.6.1 前向与反向SDE

312 |
    313 |
  • 314 |

    前向SDE: 精心设计的、将数据 x_0 转化为噪声 x_T 的过程。例如VP-SDE: 315 | dx = -1/2 * β(t) * x dt + sqrt(β(t)) * dB_t

    316 |
  • 317 |
  • 318 |

    反向SDE: Anderson定理告诉我们,存在一个对应的反向过程,其漂移项必须由分数函数 ∇log p_t(x) 来修正: 319 | dx = [f(x, t) - g(t)^2 * ∇log p_t(x)] dt + g(t) d(bar(W)_t) 320 | 这揭示了学习生成模型等价于学习分数函数

    321 |
  • 322 |
323 |

A.6.2 概率流ODE

324 |
    325 |
  • 326 |

    每个SDE都对应一个确定性的ODE,称为概率流ODE,它描述了概率密度的平均流动方向: 327 | dx = [f(x, t) - 1/2 * g(t)^2 * ∇log p_t(x)] dt

    328 |
  • 329 |
  • 330 |

    由于没有随机项,可以使用高效的ODE数值求解器进行快速、确定性的采样。这是DDIM等快速采样算法的理论基础。

    331 |
  • 332 |
333 |

A.6.3 Fokker-Planck方程

334 |
    335 |
  • 这是一个偏微分方程(PDE),它从宏观上描述了概率密度 p(x, t) 随时间的演化。
  • 336 |
  • 它将微观的粒子运动(SDE)与宏观的密度变化(PDE)联系起来,是进行理论分析的强大工具。
  • 337 |
338 |
339 | **综合练习:统一视角** 340 |

考虑一个简单的一维Ornstein-Uhlenbeck过程:dX_t = -θX_t dt + σdB_t

341 |
    342 |
  1. 稳态分布:使用Fokker-Planck方程,证明其稳态分布为 N(0, σ^2/(2θ))
  2. 343 |
  3. 分数函数:写出其稳态分布的分数函数。
  4. 344 |
  5. 反向SDE:写出在稳态下的反向SDE。
  6. 345 |
  7. 概率流ODE:写出在稳态下的概率流ODE。
  8. 346 |
347 |

解答思路

348 |
    349 |
  1. 在Fokker-Planck方程中令 ∂p/∂t = 0,得到一个关于 p(x) 的常微分方程,求解可得高斯分布。
  2. 350 |
  3. 对于高斯分布 N(μ, Σ^2),分数函数为 -(x-μ)/Σ^2
  4. 351 |
  5. 将分数函数代入Anderson定理的公式。
  6. 352 |
  7. 将分数函数代入概率流ODE的公式。你会发现,在稳态下,ODE的漂移项恰好是前向SDE漂移项的两倍。
  8. 353 |
354 |
355 |

A.7 进一步学习资源

356 |
    357 |
  • Øksendal, B. "Stochastic Differential Equations": SDE的经典入门教材,理论与应用并重。
  • 358 |
  • Evans, L.C. "An Introduction to Stochastic Differential Equations": 更侧重于PDE方法的SDE介绍,适合数学背景较强的读者。
  • 359 |
  • Särkkä, S., & Solin, A. "Applied Stochastic Differential Equations": 侧重于数值方法和实际应用的优秀书籍。
  • 360 |
361 |
362 | 363 | 364 |
365 |
366 | 367 | -------------------------------------------------------------------------------- /chapter2.md: -------------------------------------------------------------------------------- 1 | [← 上一章](chapter1.md) | 第2章 / 共14章 | [下一章 →](chapter3.md) 2 | 3 | # 第2章:神经网络架构:U-Net与ViT 4 | 5 | 扩散模型的成功离不开强大的神经网络架构。有趣的是,扩散模型并没有发明全新的网络结构,而是巧妙地借用了计算机视觉领域的两个里程碑式架构:U-Net和Vision Transformer (ViT)。本章将追溯这两种架构的历史发展,理解它们的设计初衷,并剖析它们为何能与扩散模型的去噪任务完美契合。这种“历史的巧合”不仅展示了深度学习领域知识迁移的魅力,也为我们设计未来更高效的生成模型提供了深刻的启示。 6 | 7 | ## 2.1 从图像分割到去噪:U-Net的历史演变 8 | 9 | ### 2.1.1 生物医学图像的挑战与U-Net的诞生 10 | 11 | 2015年,深度学习正在快速改变计算机视觉的格局。然而,在医学图像分析领域,研究者们面临着独特的挑战:标注数据极其稀缺(医学专家的时间宝贵),图像分辨率高,细节至关重要,且分割边界往往模糊不清。当时流行的全卷积网络(FCN)虽然在自然图像分割上取得了成功,但在医学图像上的表现并不理想。 12 | 13 | 正是在这样的背景下,来自弗莱堡大学的Olaf Ronneberger、Philipp Fischer和Thomas Brox提出了U-Net。他们的灵感来自一个朴素但深刻的观察:医学图像分割需要两种看似矛盾的能力——既要理解全局的语义信息(这是什么器官?),又要精确定位每个像素(边界在哪里?)。传统的编码器-解码器架构在解码过程中丢失了太多空间信息,而U-Net通过引入跳跃连接,优雅地解决了这个问题。 14 | 15 | > **定义:历史脉络的详细时间线** 16 | > - **2012-2014年**:全卷积网络(FCN)的兴起,Long等人证明了CNN可以进行像素级预测,但在细节保留上存在不足。 17 | > - **2015年5月**:U-Net在ISBI细胞追踪挑战赛中首次亮相,以大幅领先的成绩震撼了医学图像界。原始论文展示了仅用30张训练图像就能达到出色性能的能力。 18 | > - **2016-2017年**:U-Net的变体开始涌现——3D U-Net用于体积数据、V-Net引入残差连接、Attention U-Net加入注意力机制。每个变体都针对特定应用场景进行了优化。 19 | > - **2017-2019年**:U-Net架构被广泛应用于各种像素级预测任务,从卫星图像分析到自动驾驶的道路分割,成为该领域的事实标准。其PyTorch和TensorFlow实现成为GitHub上最受欢迎的开源项目之一。 20 | > - **2020年6月**:Ho等人发表DDPM论文,首次将U-Net用作扩散模型的去噪网络。他们的关键洞察是:去噪本质上也是一个像素到像素的映射问题。 21 | > - **2021年**:Dhariwal和Nichol在论文《Diffusion Models Beat GANs on Image Synthesis》中提出了改进的U-Net架构(ADM),加入了自注意力层和自适应归一化,将扩散模型的生成质量推向新高度。 22 | > - **2022年**:Stable Diffusion的发布让U-Net架构走向大众。其高效的潜在空间U-Net设计使得高质量图像生成首次可以在消费级GPU上运行。 23 | > - **2023年至今**:U-Net继续演进,如加入更多的条件机制(ControlNet)、与Transformer混合(U-ViT)、针对视频生成的时空U-Net等。 24 | 25 | ### 2.1.2 从分割到去噪:任务的本质相似性 26 | 27 | 为什么一个为医学图像分割设计的架构能够如此完美地适用于扩散模型?答案隐藏在这两个看似不同的任务的数学本质中。 28 | 29 | **图像分割的数学表述**:给定输入图像 $\mathbf{x} \in \mathbb{R}^{H \times W \times 3}$,预测每个像素的类别标签 $\mathbf{y} \in \{0,1,...,C-1\}^{H \times W}$。这是一个确定性的映射:$f_{\text{seg}}: \mathbb{R}^{H \times W \times 3} \rightarrow \{0,1,...,C-1\}^{H \times W}$。 30 | 31 | **扩散模型去噪的数学表述**:给定带噪声的图像 $\mathbf{x}_t = \sqrt{\bar{\alpha}_t}\mathbf{x}_0 + \sqrt{1-\bar{\alpha}_t}\boldsymbol{\epsilon}$,预测噪声 $\boldsymbol{\epsilon} \in \mathbb{R}^{H \times W \times 3}$。这同样是一个确定性的映射:$f_{\text{denoise}}: \mathbb{R}^{H \times W \times 3} \times \mathbb{R} \rightarrow \mathbb{R}^{H \times W \times 3}$(额外的输入是时间步$t$)。 32 | 33 | 两者的共同点在于: 34 | 1. **像素级预测**:两个任务都需要为输入的每个空间位置产生一个输出。 35 | 2. **多尺度信息融合**:分割需要结合局部纹理(判断边界)和全局语义(识别对象);去噪需要结合局部细节(保留纹理)和全局结构(理解内容)。 36 | 3. **空间对应关系**:输出的空间结构必须与输入严格对应,这正是跳跃连接所保证的。 37 | 38 | ### 2.1.3 U-Net设计哲学的深层洞察 39 | 40 | U-Net的成功不仅仅是技术上的胜利,更体现了深刻的设计哲学。让我们深入剖析其核心设计原则: 41 | 42 | **1. 对称性的美学与功能** 43 | U-Net的U形结构不仅在视觉上优雅,更重要的是体现了信息处理的对称性。编码器逐步压缩空间维度、提取抽象特征的过程,与解码器逐步恢复空间维度、重建具体细节的过程,形成了完美的镜像。这种对称性在扩散模型中获得了新的诠释:编码器理解"现在有什么噪声",解码器决定"如何去除这些噪声"。 44 | 45 | **2. 跳跃连接:信息高速公路** 46 | 原始的编码器-解码器架构存在一个致命弱点:信息瓶颈。当特征图被压缩到最小尺寸时(如原始尺寸的1/32),大量的空间信息已经无可挽回地丢失了。U-Net的跳跃连接就像在山谷两侧架起的桥梁,让高分辨率的信息可以直接"跳过"瓶颈,到达需要它的地方。 47 | 48 | 在扩散模型的语境下,这一点尤为关键。考虑去噪过程的两个极端情况: 49 | - 当噪声很大时($t$接近$T$),模型主要依赖瓶颈处的全局信息来重建大致结构。 50 | - 当噪声很小时($t$接近0),模型主要依赖跳跃连接传递的局部信息来恢复细节。 51 | 52 | **3. 计算效率的权衡艺术** 53 | U-Net的金字塔结构带来了计算上的巨大优势。大部分的计算(自注意力、复杂的卷积)发生在低分辨率的特征图上,而高分辨率层只进行相对简单的操作。这种设计使得U-Net可以在有限的计算资源下处理高分辨率图像,这也是为什么Stable Diffusion能够在个人电脑上运行的关键因素之一。 54 | 55 | ### 2.1.4 U-Net变体的百花齐放 56 | 57 | U-Net的基本思想激发了无数的变体和改进。每一个成功的变体都代表了对特定问题的深刻理解: 58 | 59 | - **3D U-Net (2016)**:将2D卷积替换为3D卷积,用于处理CT、MRI等体积数据。关键创新是各向异性的卷积核(如3×3×1),以处理医学图像中常见的各向异性分辨率。 60 | 61 | - **Attention U-Net (2018)**:在跳跃连接中加入注意力门控(attention gates),让模型学习"哪些跳跃连接的信息是重要的"。这在医学图像中特别有用,因为病变区域往往只占整个图像的一小部分。 62 | 63 | - **U-Net++ (2018)**:通过密集的跳跃连接创建了一个"嵌套"的U-Net结构,让解码器可以从多个尺度的编码特征中选择信息。这种设计虽然增加了计算量,但在某些任务上显著提升了性能。 64 | 65 | - **TransUNet (2021)**:将CNN编码器的瓶颈部分替换为Transformer,结合了CNN的局部特征提取能力和Transformer的全局建模能力。这为后来的混合架构铺平了道路。 66 | 67 | ### 2.1.5 为什么是U-Net?扩散模型的架构选择 68 | 69 | 当Ho等人在2020年为DDPM选择网络架构时,他们面临着多种选择:ResNet、VGG、甚至当时新兴的Vision Transformer。为什么最终选择了U-Net? 70 | 71 | **1. 归纳偏置的匹配** 72 | 扩散模型的去噪任务具有特殊的性质:输出必须与输入在空间上严格对齐。U-Net的架构天然地保证了这一点,而其他架构(如将图像展平后输入全连接网络)则会破坏这种空间结构。 73 | 74 | **2. 多时间尺度的处理能力** 75 | 在扩散过程的不同阶段,去噪的重点是不同的: 76 | - 早期(高噪声):需要重建全局结构和语义内容 77 | - 中期:需要恢复中等尺度的形状和纹理 78 | - 后期(低噪声):需要精修局部细节和清晰度 79 | 80 | U-Net的多尺度特性完美匹配了这种需求,不同的层级自然地专注于不同尺度的特征。 81 | 82 | **3. 实践中的鲁棒性** 83 | 医学图像分割领域的严苛要求(小数据集、高精度需求)锻造了U-Net的鲁棒性。这种鲁棒性在扩散模型的训练中同样重要,因为去噪网络需要处理从纯噪声到清晰图像的整个谱系。 84 | 85 |
86 | 深入研究:U-Net的理论基础与未来方向 87 | 88 | **1. 信息论视角** 89 | 从信息论的角度,U-Net的跳跃连接可以被理解为创建了多个信息传输通道,每个通道具有不同的"带宽"(分辨率)。这种设计最小化了信息在网络中传输时的损失。研究方向: 90 | - 如何定量分析不同跳跃连接的信息流量? 91 | - 是否存在最优的跳跃连接模式? 92 | - 能否设计自适应的跳跃连接,根据输入内容动态调整? 93 | 94 | **2. 神经架构搜索(NAS)在U-Net的应用** 95 | 虽然U-Net的基本结构已经被证明非常有效,但其具体的配置(深度、宽度、跳跃连接的位置等)仍有优化空间。研究方向: 96 | - 如何为特定的数据集自动搜索最优的U-Net配置? 97 | - 能否设计一个"元U-Net",根据输入动态调整其结构? 98 | - 如何在保持U-Net核心思想的同时,探索更激进的架构创新? 99 | 100 | **3. U-Net与其他范式的融合** 101 | U-Net代表了一种特定的归纳偏置,但它并非唯一的选择。研究方向: 102 | - 如何将U-Net与图神经网络(GNN)结合,处理非规则的空间结构? 103 | - 能否设计一个统一的框架,在U-Net和Transformer之间平滑过渡? 104 | - 如何将物理约束(如守恒定律)直接编码到U-Net的架构中? 105 | 106 |
107 | 108 | ## 2.2 U-Net架构详解 109 | 110 | ### 2.2.1 现代U-Net:为扩散模型重新设计 111 | 112 | 当DDPM的作者们在2020年选择U-Net作为去噪网络时,他们面临着与原始分割任务完全不同的需求。因此,一个为扩散模型“现代化”的U-Net诞生了,它融合了自2015年以来深度学习架构的诸多进展。 113 | 114 | > **定义:扩散U-Net的关键改进** 115 | > | 组件 | 原始U-Net (2015) | 扩散U-Net (2020+) | 116 | > | :--- | :--- | :--- | 117 | > | **卷积类型** | Valid卷积 (无padding) | Same卷积 (保持尺寸) | 118 | > | **归一化** | 无 (或后期加入BatchNorm) | GroupNorm (小批量稳定) | 119 | > | **激活函数** | ReLU | SiLU / Swish (更平滑) | 120 | > | **残差连接** | 无 | 每个块内部都有 (类ResNet) | 121 | > | **注意力机制** | 无 | 多分辨率自注意力 | 122 | > | **条件机制** | 无需条件 | 时间嵌入 (必需) | 123 | 124 | 让我们深入理解几个关键改进: 125 | 126 | #### 1. 残差块 (ResNet Block) 127 | 现代U-Net的基本构建单元不再是简单的卷积层,而是借鉴了ResNet的残差块。一个典型的块流程如下: 128 | 1. 输入 `x` 首先通过 `GroupNorm` 和 `SiLU` 激活函数。 129 | 2. 经过一个3x3的 `Conv2d` 层。 130 | 3. 再次通过 `GroupNorm` 和 `SiLU`。 131 | 4. 经过第二个3x3的 `Conv2d` 层。 132 | 5. 将处理后的结果与原始输入 `x` 相加(残差连接)。 133 | 134 | #### 2. 时间嵌入注入 (Time Embedding) 135 | 时间步 `t` 的信息至关重要。它通常通过一个小型MLP从正弦编码转换为嵌入向量,然后通过自适应归一化层(Adaptive Group Normalization, AdaGN)注入到每个残差块中。其核心思想是调制残差块的统计特性: 136 | `h_out = GroupNorm(h_in) * (1 + scale(t)) + shift(t)` 137 | 其中 `scale(t)` 和 `shift(t)` 是从时间嵌入向量线性变换得到的。 138 | 139 | #### 3. 自注意力 (Self-Attention) 140 | 为了捕获长程依赖关系,自注意力机制被引入到U-Net中。但由于其计算复杂度与像素数的平方成正比,它通常只在特征图分辨率较低的层级(如16x16或8x8)使用,以在计算效率和全局建模能力之间取得平衡。 141 | 142 | ### 2.2.2 采样方式的演进:从池化到可学习的卷积 143 | 144 | "如何正确地降低和恢复分辨率"是U-Net设计的核心问题之一,其演进过程反映了深度学习架构设计的范式转变。这个问题看似简单,实则深刻影响着模型的表现力和生成质量。 145 | 146 | #### 下采样的哲学:信息压缩的艺术 147 | 148 | 下采样不仅仅是减少计算量的技术手段,更是一种信息抽象的过程。每次下采样,我们都在回答一个问题:如何用更少的数字表示更大的区域? 149 | 150 | **1. 最大池化时代(2012-2015)** 151 | 最大池化(`nn.MaxPool2d`)曾是卷积神经网络的标配。其背后的假设是:在一个局部区域内,最强的激活值代表了最重要的特征。这种假设在分类任务中很合理——我们关心的是"是否存在某个特征",而不是"特征在哪里"。 152 | 153 | ``` 154 | 输入: [[1, 2], MaxPool2d 输出: [4] 155 | [3, 4]] (2x2) 156 | ``` 157 | 158 | 然而,对于生成任务,这种"赢者通吃"的策略是灾难性的: 159 | - **位置信息丢失**:我们不知道最大值来自哪个位置 160 | - **梯度稀疏**:只有最大值位置有梯度,其他位置梯度为零 161 | - **不可逆性**:无法从池化后的结果准确重建原始信息 162 | 163 | **2. 步进卷积革命(2015-2018)** 164 | DCGAN论文提出了一个革命性的想法:让网络自己学习如何下采样。步进卷积(`stride=2`的`nn.Conv2d`)将下采样和特征提取合二为一: 165 | 166 | ```python 167 | # 传统方法:先卷积,后池化 168 | conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) 169 | pool = nn.MaxPool2d(2) 170 | output = pool(conv(input)) # 两步操作 171 | 172 | # 现代方法:步进卷积一步到位 173 | strided_conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1) 174 | output = strided_conv(input) # 一步操作,可学习 175 | ``` 176 | 177 | 这种方法的优势在于: 178 | - **完全可学习**:网络可以学习最适合任务的下采样方式 179 | - **保留更多信息**:不是简单地选择最大值,而是学习加权组合 180 | - **梯度流畅**:所有位置都参与计算,梯度流动更健康 181 | 182 | **3. 现代最佳实践:分而治之(2018至今)** 183 | 随着模型规模的增长,训练稳定性成为关键考虑。现代架构倾向于将"改变分辨率"和"提取特征"解耦: 184 | 185 | ```python 186 | # 第一步:在当前分辨率提取特征 187 | conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) 188 | # 第二步:专门的下采样层 189 | downsample = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=2, padding=1) 190 | ``` 191 | 192 | 这种设计的智慧在于: 193 | - **功能解耦**:每层专注于一个任务,更容易优化 194 | - **灵活性**:可以在两步之间插入归一化、激活函数等 195 | - **数值稳定**:避免在一个操作中进行过于剧烈的变换 196 | 197 | #### 上采样的挑战:从低分辨率重建细节 198 | 199 | 如果说下采样是"压缩",那么上采样就是"解压缩"。但与信息压缩不同,神经网络的上采样需要"创造"原本不存在的细节。 200 | 201 | **1. 转置卷积的诱惑与陷阱** 202 | 转置卷积(`nn.ConvTranspose2d`)在数学上是步进卷积的精确逆操作。它通过在输入之间插入零值,然后进行常规卷积来实现上采样: 203 | 204 | ``` 205 | 输入: [a, b] → 插零: [a, 0, b] → 卷积: 生成更大的输出 206 | ``` 207 | 208 | 然而,这种方法存在一个致命问题:**棋盘效应(Checkerboard Artifacts)**。当`kernel_size`不能被`stride`整除时,输出像素接收到的"贡献"不均匀: 209 | 210 | ``` 211 | kernel_size=3, stride=2 的情况: 212 | 某些输出像素被1个输入像素影响 213 | 某些输出像素被2个输入像素影响 214 | → 产生棋盘状的明暗模式 215 | ``` 216 | 217 | 这个问题在2016年被Odena等人系统分析后,引发了社区的广泛讨论。 218 | 219 | **2. 插值+卷积:简单但有效的解决方案** 220 | 为了避免棋盘效应,现代架构采用了一个看似"倒退"但实际上更稳健的方法: 221 | 222 | ```python 223 | # 方法1:最近邻插值 + 卷积 224 | upsample = nn.Upsample(scale_factor=2, mode='nearest') 225 | conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) 226 | output = conv(upsample(input)) 227 | 228 | # 方法2:双线性插值 + 卷积 229 | upsample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False) 230 | conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) 231 | output = conv(upsample(input)) 232 | ``` 233 | 234 | 这种方法的优势: 235 | - **无棋盘效应**:插值保证了空间均匀性 236 | - **计算效率高**:插值操作很快,卷积是标准操作 237 | - **易于理解和调试**:两步操作各司其职 238 | 239 | **3. 亚像素卷积:另一种优雅的方案** 240 | 亚像素卷积(Pixel Shuffle)提供了另一种思路:先在低分辨率空间生成多个通道,然后重新排列成高分辨率输出: 241 | 242 | ```python 243 | # 输入: [B, C, H, W] 244 | # 先扩展通道: [B, C*r², H, W] 245 | conv = nn.Conv2d(in_channels, out_channels * scale_factor**2, kernel_size=3, padding=1) 246 | # 然后重排: [B, C, H*r, W*r] 247 | pixel_shuffle = nn.PixelShuffle(scale_factor) 248 | output = pixel_shuffle(conv(input)) 249 | ``` 250 | 251 | 这种方法在超分辨率任务中特别流行,因为它允许网络在低分辨率空间进行大部分计算。 252 | 253 | #### 采样策略对扩散模型的特殊意义 254 | 255 | 在扩散模型中,采样方式的选择有着特殊的重要性: 256 | 257 | **1. 信息保真度** 258 | 扩散模型需要在多个时间步之间传递信息。任何信息损失都会在迭代过程中被放大。因此,可逆或近似可逆的采样方式(如步进卷积配合适当的上采样)特别重要。 259 | 260 | **2. 多尺度一致性** 261 | 去噪过程需要在不同尺度上保持一致性。粗糙的采样方式可能导致不同分辨率层之间的特征不匹配,影响最终的生成质量。 262 | 263 | **3. 计算效率的关键** 264 | U-Net的大部分计算发生在低分辨率层。高效的采样策略可以显著减少计算量,这是Stable Diffusion能够在消费级硬件上运行的关键因素之一。 265 | 266 | ### 2.2.3 归一化技术:从BatchNorm到AdaGN的演进 267 | 268 | 归一化技术的演进史,是深度学习社区对"如何让深层网络稳定训练"这一核心问题不断探索的历史。在扩散模型中,归一化不仅影响训练稳定性,更成为了注入条件信息的关键机制。 269 | 270 | #### 归一化的本质:对抗内部协变量偏移 271 | 272 | 2015年,Ioffe和Szegedy提出BatchNorm时,他们的核心观察是:深层网络训练困难的一个重要原因是**内部协变量偏移(Internal Covariate Shift)**——即每层的输入分布在训练过程中不断变化,导致后续层需要不断适应新的输入分布。 273 | 274 | 归一化的基本思想很简单: 275 | ``` 276 | 归一化输出 = γ × (输入 - 均值) / 标准差 + β 277 | ``` 278 | 其中γ和β是可学习的缩放和偏移参数。关键在于:如何计算均值和标准差? 279 | 280 | #### BatchNorm的局限:为什么它不适合扩散模型 281 | 282 | BatchNorm在许多任务上取得了巨大成功,但在扩散模型中却遇到了前所未有的挑战: 283 | 284 | **1. 批次依赖性带来的不一致** 285 | BatchNorm在训练时使用当前批次的统计量,在推理时使用移动平均。这导致: 286 | ```python 287 | # 训练时:使用批次统计 288 | mean = x.mean(dim=[0, 2, 3]) # 跨批次维度计算 289 | var = x.var(dim=[0, 2, 3]) 290 | x_norm = (x - mean) / sqrt(var + eps) 291 | 292 | # 推理时:使用移动平均 293 | x_norm = (x - running_mean) / sqrt(running_var + eps) 294 | ``` 295 | 296 | 对于扩散模型,这种不一致是致命的: 297 | - 生成时通常batch_size=1,统计量毫无意义 298 | - 训练和推理的行为差异会累积放大 299 | 300 | **2. 时间步混淆问题** 301 | 扩散模型的一个批次中,不同样本可能处于不同的时间步: 302 | ``` 303 | 批次 = [x_t1, x_t2, x_t3, x_t4] # t1, t2, t3, t4可能完全不同 304 | ``` 305 | 306 | BatchNorm会将这些处于不同噪声水平的样本混合计算统计量,这就像把苹果和橙子混在一起求平均——毫无意义。 307 | 308 | **3. 小批量训练的灾难** 309 | 高分辨率的扩散模型因为内存限制,批次大小通常很小(如2或4)。在如此小的批次上估计统计量,方差极大,训练极不稳定。 310 | 311 | #### GroupNorm:优雅的解决方案 312 | 313 | 2018年,何恺明等人提出的GroupNorm巧妙地解决了这些问题。其核心思想是:**不跨样本计算统计量,而是在每个样本内部,将通道分组后计算**。 314 | 315 | ```python 316 | # GroupNorm的计算方式 317 | # 假设输入 x 的形状为 [B, C, H, W] 318 | # 将 C 个通道分成 G 组 319 | x = x.view(B, G, C//G, H, W) 320 | mean = x.mean(dim=[2, 3, 4]) # 在每组内计算 321 | var = x.var(dim=[2, 3, 4]) 322 | x = (x - mean) / sqrt(var + eps) 323 | x = x.view(B, C, H, W) 324 | ``` 325 | 326 | GroupNorm的优势: 327 | - **批次无关**:每个样本独立计算,batch_size=1也能正常工作 328 | - **时间步隔离**:不同时间步的样本互不影响 329 | - **稳定性好**:不依赖批次大小,小批量训练也稳定 330 | 331 | GroupNorm实际上是一个统一框架: 332 | - 当 G = 1 时,退化为 LayerNorm(跨所有通道归一化) 333 | - 当 G = C 时,退化为 InstanceNorm(每个通道独立归一化) 334 | - 当 G = 32 时(常用设置),在两者之间取得平衡 335 | 336 | #### 自适应归一化:从固定到动态的飞跃 337 | 338 | 传统的归一化使用固定的γ和β参数。但StyleGAN的成功启发了一个革命性的想法:**让这些参数根据外部条件动态变化**。 339 | 340 | **AdaGN(Adaptive Group Normalization)的工作原理:** 341 | 342 | ```python 343 | class AdaGN(nn.Module): 344 | def __init__(self, num_features, num_groups=32, time_emb_dim=128): 345 | super().__init__() 346 | self.norm = nn.GroupNorm(num_groups, num_features) 347 | # 从时间嵌入预测 scale 和 shift 348 | self.time_mlp = nn.Sequential( 349 | nn.SiLU(), 350 | nn.Linear(time_emb_dim, num_features * 2) 351 | ) 352 | 353 | def forward(self, x, time_emb): 354 | # 计算动态的 scale 和 shift 355 | scale_shift = self.time_mlp(time_emb) 356 | scale, shift = scale_shift.chunk(2, dim=1) 357 | 358 | # 应用 GroupNorm 359 | x = self.norm(x) 360 | 361 | # 应用动态调制 362 | x = x * (1 + scale[:, :, None, None]) + shift[:, :, None, None] 363 | return x 364 | ``` 365 | 366 | **为什么AdaGN对扩散模型如此有效?** 367 | 368 | 1. **时间感知的去噪**:不同时间步需要不同的去噪策略。早期(高噪声)可能需要更强的归一化来稳定训练,后期(低噪声)可能需要更弱的归一化来保留细节。 369 | 370 | 2. **高效的条件注入**:相比于将条件信息拼接到特征图(增加计算量),AdaGN通过调制现有特征实现条件控制,几乎不增加计算成本。 371 | 372 | 3. **分层的控制粒度**:每一层可以根据时间步独立调整其行为,这种细粒度的控制对于处理不同尺度的噪声至关重要。 373 | 374 | #### 归一化位置的艺术:前置还是后置? 375 | 376 | 在Transformer的发展过程中,Layer Normalization的位置引发了激烈讨论。这个讨论同样适用于U-Net: 377 | 378 | **Post-Norm(传统方式):** 379 | ``` 380 | x → Conv → ReLU → Norm → + → 输出 381 | ↑ 382 | x (残差连接) 383 | ``` 384 | 385 | **Pre-Norm(现代方式):** 386 | ``` 387 | x → Norm → Conv → ReLU → + → 输出 388 | ↑ 389 | x (残差连接) 390 | ``` 391 | 392 | Pre-Norm的优势: 393 | - **梯度流更稳定**:残差连接直接连接输入输出,梯度可以无障碍地流过 394 | - **训练更容易**:特别是对于非常深的网络 395 | - **与AdaGN配合更好**:在块的开始就进行条件调制,影响整个块的计算 396 | 397 | 这就是为什么现代扩散模型普遍采用Pre-Norm设计。 398 | 399 | #### RMSNorm:更简单的未来? 400 | 401 | 最近,RMSNorm作为LayerNorm的简化版本引起了关注: 402 | 403 | ```python 404 | # LayerNorm: 减均值,除标准差 405 | x_norm = (x - mean) / std 406 | 407 | # RMSNorm: 只除以均方根,不减均值 408 | x_norm = x / sqrt(mean(x²)) 409 | ``` 410 | 411 | RMSNorm的优势: 412 | - **计算更简单**:少了减均值的操作 413 | - **某些情况下效果相当**:特别是当激活函数本身有中心化效果时 414 | 415 | 虽然RMSNorm在扩散模型中的应用还不广泛,但它代表了一个重要趋势:**不断简化和优化基础组件**。 416 | 417 |
418 | 练习 2.1:U-Net架构的权衡分析 419 | 420 | 1. **深度 vs. 宽度**:分析U-Net的深度(下采样次数)和宽度(基础通道数)对模型性能和计算成本的影响。对于一个固定计算预算的模型,是更深好还是更宽好? 421 | 2. **注意力位置**:讨论在U-Net的不同层级(高、中、低分辨率)插入自注意力模块的利弊。为什么大多数模型选择在中低分辨率层插入? 422 | 3. **跳跃连接**:标准的跳跃连接使用拼接(concatenation)。分析如果改为逐元素相加(addition)会对信息流产生什么影响。在什么情况下相加可能是更好的选择? 423 | 4. **开放探索**:设计一种“动态U-Net”,其深度或宽度可以根据输入的时间步`t`自适应调整。例如,在噪声水平高时使用更深的网络来捕捉全局结构,在噪声水平低时使用更浅的网络来关注细节。 424 | 5. **研究思路**: 425 | * 查阅有关神经架构搜索(NAS)在生成模型中应用的研究。 426 | * 从信息论角度分析跳跃连接,将其视为信息瓶颈的旁路。 427 | * 研究不同归一化层(如`RMSNorm`)与自适应调制结合的可能性。 428 | 429 |
430 | 431 | ## 2.3 从NLP到CV:Vision Transformer的跨界之旅 432 | 433 | ### 2.3.1 Transformer的视觉革命 434 | 435 | Transformer架构由Vaswani等人在2017年的论文《Attention Is All You Need》中为自然语言处理提出。2020年,Dosovitskiy等人的ViT论文证明了纯Transformer架构在图像分类上可以达到甚至超越顶尖的CNN,开启了Transformer在计算机视觉领域的革命。 436 | 437 | ViT的核心思想极其简洁: 438 | 1. 将输入图像分割成固定大小的patches(例如16×16像素)。 439 | 2. 将每个patch线性投影(embedding)为一个向量(token)。 440 | 3. 将这些tokens序列以及一个可学习的`[CLS]` token输入到标准的Transformer编码器中。 441 | 4. 使用Transformer输出的`[CLS]` token进行分类。 442 | 443 | 这种设计的优雅之处在于它为视觉问题引入了新的归纳偏置:**世界是由可组合的“部件”构成的**。 444 | 445 | ### 2.3.2 扩散Transformer (DiT) 446 | 447 | 2022年,Peebles和Xie在论文《Scalable Diffusion Models with Transformers》中提出了DiT,成功将ViT架构应用于扩散模型。DiT对ViT进行了关键改造以适应去噪任务: 448 | 449 | 1. **输入处理**:输入不再是清晰图像,而是带噪声的图像patches。 450 | 2. **无`[CLS]` Token**:生成任务需要对每个patch进行预测,因此去除了分类任务专用的`[CLS]` token。 451 | 3. **条件注入**:时间步`t`和类别标签`c`的嵌入向量被视为额外的条件tokens,通过自适应LayerNorm(AdaLN)或交叉注意力(cross-attention)注入到模型中。 452 | 4. **输出处理**:Transformer的输出tokens被重新排列,并通过一个线性解码器预测每个patch对应的噪声。 453 | 454 | DiT的成功,特别是其卓越的可扩展性(scaling law),使其迅速成为SOTA文生图模型(如Sora, Stable Diffusion 3)的首选架构。 455 | 456 |
457 | 练习 2.2:比较U-Net和DiT的归纳偏置与复杂度 458 | 459 | 1. **归纳偏置**:对比CNN(U-Net的基础)和Transformer(DiT的基础)的核心归纳偏置。CNN的“局部性”和“平移等变性”与Transformer的“全局关系”和“排列不变性”分别如何影响它们作为去噪网络的性能? 460 | 2. **计算复杂度**:对于一个分辨率为`H x W`的输入,推导U-Net和DiT的主要计算瓶颈。U-Net的复杂度与什么成正比?DiT的复杂度与什么成正比?(提示:考虑卷积操作和自注意力操作的复杂度) 461 | 3. **开放探索**:U-Net和DiT代表了两种不同的架构范式。近年来,出现了许多试图结合两者优点的混合架构(如U-ViT)。分析这种混合设计的动机,并提出一种你自己的混合块(hybrid block)设计。 462 | 4. **研究思路**: 463 | * 阅读ViT和DiT的原文,关注作者关于模型扩展性(scaling)的实验部分。 464 | * 探索卷积操作和自注意力在数学上的联系(例如,卷积可以被看作是一种特殊的、带强位置偏置的局部注意力)。 465 | * 研究最新的SOTA生成模型(如Sora的技术报告),分析其架构选择。 466 | 467 |
468 | 469 | ## 2.4 性能优化与实用技巧 470 | 471 | 理论架构和实际部署之间往往存在巨大鸿沟。本节分享一些在实践中积累的优化技巧。 472 | 473 | ### 2.4.1 内存优化:在GPU上塞下更大的模型 474 | 475 | 训练扩散模型时,内存的最大消耗通常来自**激活值**,特别是U-Net中为跳跃连接而保存的各层特征图。 476 | 477 | - **梯度检查点 (Gradient Checkpointing)**:核心思想是“用计算换内存”。通过`torch.utils.checkpoint.checkpoint`包裹模型的一部分(如一个ResBlock),在前向传播时不保存其内部的激活值,而在反向传播时重新计算它们。这可以显著降低内存占用(约30-50%),但会增加训练时间(约20-30%)。 478 | 479 | - **混合精度训练 (Mixed Precision)**:使用`torch.cuda.amp`(自动混合精度)可以利用现代GPU的Tensor Cores,将大部分计算从FP32转为FP16或BF16,内存减半,速度翻倍。关键是使用`GradScaler`来防止FP16梯度下溢。 480 | 481 | - **注意力优化**:标准自注意力的内存和计算复杂度与序列长度的平方成正比。对于高分辨率图像,这很快会成为瓶颈。FlashAttention等库通过融合内核操作,避免将巨大的注意力矩阵写入和读出GPU内存,从而实现显著的加速和内存节省。 482 | 483 | ### 2.4.2 训练稳定性:让大模型稳定收敛 484 | 485 | - **初始化策略**:一个关键技巧是**将输出层的权重和偏置初始化为零**。这确保模型在训练开始时输出为零,即预测的噪声为零。这是一种“无为而治”的初始化,使得模型在学习初期不会对输入造成巨大扰动,有助于稳定训练。 486 | 487 | - **数值稳定性**: 488 | - **梯度裁剪**:通过`torch.nn.utils.clip_grad_norm_`来防止梯度爆炸,是训练大模型的标配。 489 | - **学习率调度**:使用预热(warmup)和余弦退火(cosine decay)的学习率调度器通常比固定学习率效果更好。 490 | - **AdamW优化器**:AdamW通过解耦权重衰减和梯度更新,通常比标准Adam更稳定。 491 | 492 |
493 | 综合练习:为特定任务设计去噪网络 494 | 495 | 假设你要为以下两种不同的任务设计去噪网络架构,你会如何选择和修改U-Net或DiT?请详细说明理由。 496 | 497 | **任务A:移动端实时人像风格化** 498 | - **约束**:模型大小 < 50MB,在手机GPU上推理延迟 < 100ms。 499 | - **数据**:512x512的人像图片。 500 | 501 | **任务B:生成具有复杂物理规律的科学模拟数据(如流体动力学)** 502 | - **约束**:追求最高的物理保真度,计算资源几乎无限。 503 | - **数据**:256x256x256的3D体数据,需要尊重物理守恒定律。 504 | 505 | **设计分析与研究方向:** 506 | 1. **架构选择**:为每个任务选择基础架构(U-Net, DiT, 或混合架构),并论证你的选择。 507 | 2. **关键修改**:针对每个任务的约束和数据特性,你会对所选架构进行哪些关键修改?(例如,对于任务A,如何修改通道数、深度、注意力机制?对于任务B,如何处理3D数据、如何引入物理约束?) 508 | 3. **理论空白**:在任务B中,如何设计一个能内建物理不变量(如散度为零)的神经网络架构?这被称为物理信息神经网络(PINN)与生成模型的交叉领域,是一个活跃的研究方向。 509 | 4. **研究思路**: 510 | * 查阅有关模型量化、剪枝和知识蒸馏的文献,以满足任务A的部署要求。 511 | * 研究傅里叶神经算子(Fourier Neural Operator)等将物理方程求解器与神经网络结合的工作,以获取任务B的灵感。 512 | * 探索等变神经网络(Equivariant Neural Networks),它们被设计用来尊重数据的内在对称性(如旋转不变性)。 513 | 514 |
515 | 516 | ## 本章小结 517 | 518 | 本章我们追溯了扩散模型中两种主流架构的历史渊源,并深入分析了它们的设计细节和演进过程。 519 | 520 | - **U-Net**:从2015年的医学图像分割任务,到2020年成为DDPM的核心架构,其多尺度特征融合能力是成功的关键。 521 | - **Vision Transformer (DiT)**:从2017年的NLP革命,经2020年的CV突破,到2022年成为可扩展扩散模型的主流选择,其全局关系建模能力和卓越的扩展性是其优势所在。 522 | 523 | 这两种架构能够成功应用于扩散模型并非偶然,而是经过了精心的改造和适配: 524 | - **共同的改造**:都引入了时间嵌入作为关键的条件信息,并发展出如AdaGN/AdaLN等高效的注入机制。 525 | - **不同的演进**:U-Net在卷积、采样和归一化等模块上不断优化;DiT则专注于如何将Transformer范式更好地应用于像素级的生成任务。 526 | 527 | 扩散模型的架构演进史启示我们:创新并不总是需要“从零开始”。善于发现和利用已有技术的潜力,通过巧妙的改造和组合,往往能产生意想不到的突破。 528 | 529 | 下一章,我们将深入DDPM的数学原理,看看这些强大的架构是如何在一个清晰的概率框架下进行训练和优化的。 530 | --------------------------------------------------------------------------------