一、核心思想

  扩散模型(Diffusion Model)是一种生成模型,受热力学中扩散过程的启发,通过模拟数据从噪声中逐步去噪的过程来生成样本。其核心思想是渐进式地添加噪声(正向过程)和逐步去噪(反向过程)。

在正向过程中,逐步向数据中添加高斯噪声,最终将数据转化为纯噪声;在反向过程中,学习如何从噪声中逐步去噪,恢复出原始数据分布。

二、前向扩散过程(Forward Diffusion)

  目标:将真实数据逐步“破坏”为随机噪声。

  过程:对原始数据(如图像)进行 T 步微小的高斯噪声添加,每一步都让数据更接近纯噪声。

  数学上,第t 步的状态\(x_t\)由第 t-1 步的状态\(x_{t-1}\)和噪声\(\epsilon\)(服从标准正态分布)生成:

\[x_t=\sqrt{\alpha_t}\cdot x_{t-1}+\sqrt{1-\alpha_t}\cdot \epsilon
\]

    其中,\(\alpha_t\)是控制噪声强度的参数(\(0<\alpha_t<1),随着 t 增大,x_t\)逐渐接近随机噪声。

  结果:经过 T 步后,原始数据完全转化为与训练数据无关的高斯噪声\(x_T\)。

三、逆向扩散过程(Reverse Diffusion)

  目标:从纯噪声中逐步“恢复”出有意义的数据(即生成新样本)。

  过程:训练一个神经网络(通常是 U-Net 结构)学习“去噪”能力 —— 给定第 t 步的带噪声数据\(x_t\),预测它在第 t-1 步的状态\(x_{t-1}\)(或直接预测添加的噪声\(\epsilon\))。

  实际生成时,从随机噪声\(x_T\)出发,利用训练好的网络反向迭代 T 步,每一步都去除部分噪声,最终得到接近真实数据分布的生成结果\(x_0\)。

  核心:神经网络通过学习噪声的分布规律,实现从噪声到数据的“逆推”。

四、Python示例

  构建一个基础的扩散模型,用于生成一维数据。

import matplotlib
matplotlib.use('TkAgg') import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset plt.rcParams['font.sans-serif']=['SimHei'] # 中文支持
plt.rcParams['axes.unicode_minus']=False # 负号显示 # 设置随机种子,确保结果可复现
np.random.seed(42)
torch.manual_seed(42) # 生成一维数据(示例数据:混合高斯分布)
def generate_data(n_samples=1000):
# 生成两个高斯分布的数据
cluster1 = np.random.normal(loc=-2.0, scale=0.5, size=(n_samples // 2, 1))
cluster2 = np.random.normal(loc=2.0, scale=0.5, size=(n_samples // 2, 1))
data = np.vstack([cluster1, cluster2])
np.random.shuffle(data)
return data # 前向过程:逐步添加噪声
def forward_process(x_0, timesteps, betas):
"""
执行扩散过程的前向步骤,逐步向数据添加噪声
"""
# 计算alpha和alpha_bar
alphas = 1. - betas
alphas_cumprod = torch.cumprod(alphas, dim=0) # 随机选择一个时间步
t = torch.randint(0, timesteps, (x_0.shape[0],), device=x_0.device) # 从标准正态分布采样噪声
noise = torch.randn_like(x_0) # 计算x_t
sqrt_alphas_cumprod_t = torch.sqrt(alphas_cumprod[t]).reshape(-1, 1)
sqrt_one_minus_alphas_cumprod_t = torch.sqrt(1 - alphas_cumprod[t]).reshape(-1, 1)
x_t = sqrt_alphas_cumprod_t * x_0 + sqrt_one_minus_alphas_cumprod_t * noise return x_t, t, noise # 简单的神经网络模型,用于预测噪声
class SimpleDenoiser(nn.Module):
def __init__(self, input_dim=1, hidden_dim=128):
super(SimpleDenoiser, self).__init__()
self.model = nn.Sequential(
nn.Linear(input_dim + 1, hidden_dim), # +1 for time embedding
nn.SiLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.SiLU(),
nn.Linear(hidden_dim, input_dim)
) def forward(self, x, t):
# 将时间步t嵌入为模型输入的一部分
t_emb = t.unsqueeze(-1).float()
x_with_t = torch.cat([x, t_emb], dim=1)
return self.model(x_with_t) # 训练函数
def train_diffusion_model(model, dataloader, num_epochs=1000, lr=1e-3):
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
optimizer = optim.Adam(model.parameters(), lr=lr)
criterion = nn.MSELoss() # 定义扩散过程的参数
timesteps = 100
betas = torch.linspace(0.0001, 0.02, timesteps, device=device) for epoch in range(num_epochs):
epoch_loss = 0.0
for batch in dataloader:
x_0 = batch[0].to(device) # 前向过程:添加噪声
x_t, t, noise = forward_process(x_0, timesteps, betas) # 模型预测噪声
noise_pred = model(x_t, t) # 计算损失
loss = criterion(noise_pred, noise) # 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step() epoch_loss += loss.item() if (epoch + 1) % 100 == 0:
print(f"Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss / len(dataloader):.6f}") return model # 采样函数:从噪声中生成数据
def sample(model, sample_size=1000, timesteps=100):
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
model.eval() # 定义扩散过程的参数
betas = torch.linspace(0.0001, 0.02, timesteps, device=device)
alphas = 1. - betas
alphas_cumprod = torch.cumprod(alphas, dim=0)
alphas_cumprod_prev = torch.cat([torch.tensor([1.], device=device), alphas_cumprod[:-1]])
sqrt_recip_alphas = torch.sqrt(1.0 / alphas)
posterior_variance = betas * (1. - alphas_cumprod_prev) / (1. - alphas_cumprod) # 从标准正态分布开始采样
x = torch.randn(sample_size, 1, device=device) with torch.no_grad():
for i in reversed(range(timesteps)):
t = torch.full((sample_size,), i, device=device, dtype=torch.long)
noise_pred = model(x, t) # 计算均值
sqrt_recip_alphas_t = sqrt_recip_alphas[i]
x = sqrt_recip_alphas_t * (x - betas[i] / torch.sqrt(1 - alphas_cumprod[i]) * noise_pred) # 添加方差(最后一步不添加)
if i > 0:
noise = torch.randn_like(x)
posterior_variance_t = posterior_variance[i]
x = x + torch.sqrt(posterior_variance_t) * noise return x.cpu().numpy() # 主函数
def main():
# 生成数据
data = generate_data(n_samples=1000)
data_tensor = torch.tensor(data, dtype=torch.float32) # 创建数据加载器
dataset = TensorDataset(data_tensor)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True) # 初始化模型
model = SimpleDenoiser(input_dim=1) # 训练模型
trained_model = train_diffusion_model(model, dataloader, num_epochs=1000) # 生成样本
samples = sample(trained_model, sample_size=1000) # 可视化结果
plt.figure(figsize=(12, 5)) plt.subplot(1, 2, 1)
plt.hist(data, bins=50, density=True, alpha=0.7, label='真实数据')
plt.title('真实数据分布')
plt.xlabel('值')
plt.ylabel('密度')
plt.legend() plt.subplot(1, 2, 2)
plt.hist(samples, bins=50, density=True, alpha=0.7, label='生成数据', color='orange')
plt.title('扩散模型生成的数据分布')
plt.xlabel('值')
plt.ylabel('密度')
plt.legend() plt.tight_layout()
plt.show() if __name__ == "__main__":
main()

  示例展示了扩散模型的主要过程:

    数据生成:使用两个高斯分布的混合作为示例数据

    前向过程:逐步向数据添加噪声,最终将数据转换为噪声

    模型架构:使用一个简单的神经网络来学习预测噪声

    训练过程:通过最小化预测噪声与实际噪声之间的差异来训练模型

    采样过程:从噪声开始,逐步恢复数据

五、小结

  扩散模型通过“加噪-去噪”的框架,将生成问题转化为对噪声分布的逐步修正,其核心在于反向过程的参数化学习和噪声调度的设计。这一方法在生成任务中展现了强大的潜力,成为当前生成式AI的重要技术之一。

扩散模型(Diffusion Model)原理概述的更多相关文章

  1. 一文详解扩散模型:DDPM

    作者:京东零售 刘岩 扩散模型讲解 前沿 人工智能生成内容(AI Generated Content,AIGC)近年来成为了非常前沿的一个研究方向,生成模型目前有四个流派,分别是生成对抗网络(Gene ...

  2. A Neural Influence Diffusion Model for Social Recommendation 笔记

    目录 一.摘言 二.杂记 三.问题定义和一些准备工作 四.模型真思想 五.实验部分 六.参考文献 一.摘言 之前协同过滤利用user-item交互历史很好的表示了user和item.但是由于用户行为的 ...

  3. DPM(Deformable Parts Model)--原理(一)(转载)

    DPM(Deformable Parts Model) Reference: Object detection with discriminatively trained partbased mode ...

  4. DPM(Deformable Parts Model)--原理(一)

    http://blog.csdn.net/ttransposition/article/details/12966521 DPM(Deformable Parts Model) Reference: ...

  5. tensorflow学习笔记——模型持久化的原理,将CKPT转为pb文件,使用pb模型预测

    由题目就可以看出,本节内容分为三部分,第一部分就是如何将训练好的模型持久化,并学习模型持久化的原理,第二部分就是如何将CKPT转化为pb文件,第三部分就是如何使用pb模型进行预测. 一,模型持久化 为 ...

  6. nvGRAPH原理概述

    nvGRAPH原理概述 nvGRAPH的API参考分析. 简介 数据分析是高性能计算的不断增长的应用.许多高级数据分析问题可以称为图形问题.反过来,当今许多常见的图形问题也可以称为稀疏线性代数.这是N ...

  7. Hugging Face 每周速递: 扩散模型课程完成中文翻译,有个据说可以教 ChatGPT 看图的模型开源了

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  8. [Tensorflow]模型持久化的原理,将CKPT转为pb文件,使用pb模型预测

    文章目录 [Tensorflow]模型持久化的原理,将CKPT转为pb文件,使用pb模型预测 一.模型持久化 1.持久化代码实现 convert_variables_to_constants固化模型结 ...

  9. thinkphp模型层Model、Logic、Service讲解

    thinkphp模型层Model.Logic.Service讲解 时间:2014-08-24 15:54:56   编辑:一切随缘   文章来源:php教程网 已阅读:771 次       js特效 ...

  10. linux软中断与硬中断实现原理概述

    linux软中断与硬中断实现原理概述. 1.软中断通过open_softirq注册一个软中断处理函数,即在软中断向量表softirq_vec数组中添加新的软中断处理action函数. 2.调用rais ...

随机推荐

  1. C#+Selenium+Nunit实现Web自动化demo

    1.新建Nunit工程 步骤如下: 打开Rider选择图示选项 使用Nuget安装对应库 2.编写代码 代码如下: using NUnit.Framework; using OpenQA.Seleni ...

  2. TCP连接(Netty)

    启动类增加 public static void main(String[] args) { SpringApplication application = new SpringApplication ...

  3. ArcGIS拼接、镶嵌同一空间位置的不同遥感影像

      本文介绍在ArcGIS下属的ArcMap软件中,对处于同一空间位置的多幅栅格图像加以拼接.融合与叠加等操作的方法.   假如现在我们分别有以下三幅栅格图像,三者分别是独立的三个图层.第一个图层如下 ...

  4. 可持久化 01-trie 简记

    本文略过了 trie 和 可持久化的介绍,如果没学过请先自学. 在求给定一个值 \(k\) 与区间中某些值的异或最大值时,可以考虑使用在线的数据结构可持久化 01-trie 来维护. 01-trie ...

  5. 工具 | Hacking

    0x00 简介 Hacking是一款包含多种渗透测试功能的脚本. 下载地址: Hacking下载:Hacking下载 0x01 功能说明 Brute Force DDos Attack NMap Po ...

  6. 算法:请找出数组a所有重复元素和比较数组a和数组b得到不重复的新数组和比较数组a和数组b请找出所有重复元素

    /** * 1.给定数组int[] a,int[] b * (1)请找出数组a所有重复元素,例:int[] a = {1,2,3,4,8,9,3,5,1,3},结果int[] a1 = {1,1,3, ...

  7. vue3 基础-组件间传值及校验

    本篇讲基于对页面组件化拆分后, 组件之间如何进行数据传递, 通常是父组件如何给子组件进行传值, 子组件接收并进行数据校验后再使用. 父子组件传值 <!DOCTYPE html> <h ...

  8. C#中扩展方法无法获得多态性的行为

    在C#中,扩展方法(Extension Methods)是一种用于给现有类型添加新方法的技术.但是,扩展方法无法实现多态性的行为,因为它们是静态方法,它们的行为是在编译时确定的,而不是在运行时. 多态 ...

  9. codebuddy模型基于Python的实时音视频直播系统开发:多线程采集、WebSocket传输与JWT安全认证实践

    我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 我现在需要帮用户解决一个Pyt ...

  10. AD 权限维持-金票银票攻击

    本文通过 Google 翻译 Domain Persistence – Golden Ticket and Silver Ticket Attacks 这篇文章所产生,本人仅是对机器翻译中部分表达别扭 ...