手撕Diffusion系列 - 第四期 - Diffusion前向扩散

devtools/2025/1/23 11:52:25/

手撕Diffusion系列 - 第四期 - Diffusion前向扩散

目录

  • 手撕Diffusion系列 - 第四期 - Diffusion前向扩散
  • DDPM 原理图
  • DDPM 前向扩散介绍
  • Diffusion(前向扩散) 代码
    • Part1 引入相关库函数
    • Part2 去噪的一些参数初始化
    • Part3 定义前向传播函数
    • Part4 测试
  • 参考

DDPM 原理图

​ DDPM包括两个过程:前向过程(forward process)反向过程(reverse process),其中前向过程又称为扩散过程(diffusion process),如下图所示。无论是前向过程还是反向过程都是一个参数化的马尔可夫链(Markov chain),其中反向过程可以用来生成图片。

在这里插入图片描述

DDPM 整体大概流程

​ 图中,由高斯随机噪声 x T x_T xT 生成原始图片 x 0 x_0 x0 为反向过程,反之为前向过程(噪音扩散)。

DDPM 前向扩散介绍

一句话概括,前向过程就是对原始图片 x 0 x_0 x0 不断加高斯噪声最后生成随机噪声 x T x_T xT 的过程,如下图所示

在这里插入图片描述

Diffusion前向传播过程(加噪)

前向传播的过程中,上个时刻图像( x t − 1 x_{t−1} xt1)到下个时刻图像( x t x_{t} xt)的加噪传播函数如下所示:
x t = α t x t − 1 + 1 − α t ϵ t − 1 x_t=\sqrt{\alpha_t}x_{t-1} + \sqrt{1-\alpha_t}\epsilon_{t-1} xt=αt xt1+1αt ϵt1
其中 α t \alpha_t αt 是一个很小值的超参数, ϵ t − 1 ∼ N ( 0 , 1 ) \epsilon_{t-1}∼N(0,1) ϵt1N(0,1) 是高斯噪声。由公式推导,最终可以得到 x 0 x0 x0 x t xt xt 的公式,表示如下:
x t = α t ˉ x 0 + 1 − α t ˉ ϵ x_t=\sqrt{\bar{\alpha_t}}x_{0} + \sqrt{1-\bar{\alpha_t}}\epsilon xt=αtˉ x0+1αtˉ ϵ
其中 α t ˉ = ∏ i = 1 t α i , ϵ ∼ N ( 0 , 1 ) \bar{\alpha_{t}} = \prod_{i=1}^t\alpha_i,\epsilon∼N(0,1) αtˉ=i=1tαiϵN(0,1) 也是一个高斯噪声,利用这个公式,我们可以随机生成t,然后利用 x 0 x_0 x0生成 x t x_t xt

Diffusion(前向扩散) 代码

Part1 引入相关库函数

# 该模块实现的过程是利用函数输入批次的图像和批次的t,对图像利用公式进行正向扩散,得到批次的噪声图,
# 注意,这里实现的时候不是类,因为这个严格来说不算网络结构,也就是不在计算图的构建范围内,只是构造训练数据集的其中一个处理过程,所以写成函数即可。'''
# Part1 引入相关的库函数
'''
from config import * # 一些基础参数
from dataset import minist_train, minist_loader,TenosrtoPil_action # 数据的测试
import torch # 用一系列的数据处理
import matplotlib.pyplot as plt # 用于绘图

Part2 去噪的一些参数初始化

'''
# Part2 初始化一些beta和alpha参数用于函数中的加噪过程。
'''# 首先获取Beta_t,主要是T步里面的参数,这个一般是直接定好的,(left,right)中取样T次(单调增加的)
beta_t=torch.linspace(start=0.0001,end=0.02,steps=T) # (T,) # 单维度tensor# 然后是获取alpha_t ,因为和beta_t相加为1,所以直接和1相减 (单调递减)
alpha_t=1-beta_t # (T,)# 然后需要得到alpha_bar,这个是累乘得到的
alpha_bar=torch.cumprod(alpha_t,dim=-1) # alpha_t累乘 (T,)    [a1,a2,a3,....] ->  [a1,a1*a2,a1*a2*a3,.....]

Part3 定义前向传播函数

def forward_diffusion(batch_x0,batch_t): # (batch_size,chanal,imag_sie,imag_size) , (batch_size,)# 第一步首先要获取,整个batch图像的,t-1时刻的噪声。batch_noise_t=torch.randn_like(input=batch_x0) # (batch_size,chanal,imag_sie,imag_size),默认是标准正态分布# 首先需要利用batch_t,从alpha_bar里面取出对应的t,并且为了便于广播机制,需要对batch_t进行形状的转换,至少保持同纬度alpha_bar_t=alpha_bar[batch_t].reshape(batch_t.size()[0],1,1,1)# 计算得到噪声后的图batch_xt=torch.sqrt(alpha_bar_t)*batch_x0+torch.sqrt(1-alpha_bar_t)*batch_noise_treturn batch_xt,batch_noise_t

Part4 测试

if __name__ == '__main__':batch_x = next(iter(minist_loader))[0]  # 2个图片拼batch, (2,1,48,48)# 加噪前的样子plt.figure(figsize=(10, 10))plt.subplot(1, 2, 1)plt.imshow(TenosrtoPil_action(batch_x[0]))plt.subplot(1, 2, 2)plt.imshow(TenosrtoPil_action(batch_x[1]))plt.show()# 如果需要将噪声(通常是从[-1, 1]范围生成的)加到图像上,你需要将图像数据重新缩放到[-1, 1]范围,以便它与噪声匹配,能够平衡噪声对训练的影响。# 虽然正态分布不是严格[-1,1]之间,但是通过三sigema定理,我们这里可以初略定在一个sigema之间。# 总之就是没有偏差batch_x = batch_x * 2 - 1  # [0,1]像素值调整到[-1,1]之间,以便与高斯噪音值范围匹配batch_t = torch.randint(0, T, size=(batch_x.size(0),))  # 每张图片随机生成diffusion步数# batch_t=torch.tensor([5,100],dtype=torch.long)print('batch_t:', batch_t)batch_x_t, batch_noise_t = forward_diffusion(batch_x, batch_t)print('batch_x_t:', batch_x_t.size())print('batch_noise_t:', batch_noise_t.size())# 加噪后的样子plt.figure(figsize=(10, 10))plt.subplot(1, 2, 1)plt.imshow(TenosrtoPil_action((batch_x_t[0] + 1) / 2)) # 返回原来的图像范围plt.subplot(1, 2, 2)plt.imshow(TenosrtoPil_action((batch_x_t[1] + 1) / 2))plt.show()

参考

视频讲解:diffusion前向扩散_哔哩哔哩_bilibili

原理博客:手撕Diffusion系列 - 第一期 - DDPM原理-CSDN博客


http://www.ppmy.cn/devtools/152872.html

相关文章

【组件分享】商品列表组件-最佳实践

商品列表组件 商品列表组件用于展示商品信息列表&#xff0c;支持多种布局方式和自定义配置。 基础用法 <template><ProGoodsList :goods-list"goodsList" :layout"layout" item-click"handleItemClick" /> </template>&l…

Unreal Engine 5 C++ Advanced Action RPG 十一章笔记

第十一章 In Game Widgets 本章节就是做UI2-Template Button Widget 这章节创建不同的UI 结束UI胜利UI暂停菜单主菜单加载UI新建一个按钮小组件作为模版 3-Pause Menu Template Button 继续做更多模版UI 4-Lose Screen(游戏失败UI) 做失败的UI 之前按钮模版的调度程序就在这起…

Python中采用.add_subplot绘制子图的方法简要举例介绍

Python中采用.add_subplot绘制子图的方法简要举例介绍 目录 Python中采用.add_subplot绘制子图的方法简要举例介绍一、Python中绘制子图的方法1.1 add_subplot函数1.2 基本语法&#xff08;1&#xff09;add_subplot的核心语法&#xff08;2&#xff09;add_subplot在中编程中的…

【深度学习】常见模型-卷积神经网络(Convolutional Neural Networks, CNN)

卷积神经网络&#xff08;CNN&#xff09; 概念简介 卷积神经网络&#xff08;Convolutional Neural Networks, CNN&#xff09;是一种专门用于处理数据具有网格状拓扑结构&#xff08;如图像、语音&#xff09;的深度学习模型。它通过卷积操作从输入数据中提取局部特征&…

3D可视化定制:开启个性化购物新时代,所见即所得

在当前的数字化浪潮中&#xff0c;3D可视化产品定制正悄然革新消费者的购物旅程与企业的营销战略。相较于众多仍局限于二维平面的在线定制服务&#xff0c;3D可视化产品定制为消费者解锁了一个直观互动、高度个性化的定制新天地&#xff0c;赋予他们沉浸式的购物享受。 通过3D…

【深度学习】傅里叶变换

[toc]深度学习中的傅里叶变换 傅里叶变换 傅里叶变换在深度学习中有着广泛的应用&#xff0c;尤其是在信号处理、图像处理和自然语言处理等领域。 1. 傅里叶变换基础 傅里叶变换是一种将信号从时域转换到频域的数学工具。对于连续信号&#xff0c;傅里叶变换定义为&#xf…

fyne 选项卡设计

用户界面的设计至关重要&#xff0c;它直接影响着用户体验。选卡设计作为一种常见的界面布局方式&#xff0c;能够有效地组织和展示信息&#xff0c;使用户能够方便快捷地浏览和操作。 Fyne 是一个用 Go 语言编写的跨平台 GUI 框架&#xff0c;它提供了丰富的组件和功能&#…

Oracle审计

审计是监控选定的用户数据库操作的过程 审计的目的&#xff1a; 调查可疑的数据库活动&#xff1a; 审计可以帮助检测和跟踪潜在的 security breaches、未授权的访问尝试或其他异常行为。通过分析审计日志&#xff0c;可以确定可疑活动的来源、时间、频率和影响。 收集特定数…