大白话扩散模型(无公式版)

news/2024/4/29 17:41:03

背景

传统的图像生成模型有GAN,VAE等,但是存在模式坍缩,即生成图片缺乏多样性,这是因为模型本身结构导致的。而扩散模型拥有训练稳定,保持图像多样性等特点,逐渐成为现在AIGC领域的主流。

扩散模型

正如其名,该方法是从自然界的扩散现象(热力学第二定律、熵增)得到启发,认为任意我们想要的图片可以由随机噪声经过一系列采样步骤后得到,把对这个过程进行定义和建模就称为扩散模型。虽然原始论文涉及到的知识包括随机分布,马尔科夫链等,而且推导过程极其复杂,但本文不会深入去推导相关的公式,而是把重心放在思考这个过程以及对其中发现的一些问题进行探讨。

前向过程

前向过程其实就是一些假设。给定一张原始的图片,不断地往这张图片加正态分布的噪声,最终这张图片会变成正态分布噪声。

  • 为什么老有这个正态分布出现?其他分布不行吗?

统计学上有个中心极限定理,在特定条件下,大量统计独立的随机变量的和的分布趋于正态分布。依据这一定理的结论,其它概率分布能够用正态分布作为近似。这就降低了很多随机过程的计算难度

  • 那这个前向过程的作用是啥呢?

如果在假设的条件下,能够得到最终的噪声图片,那么反过来从噪声中也能得到想要的“原始图片”,即我就能从随机噪声生成任意图片,这里就与GAN是一样的。这就是下面的反向过程推导了。

  • 噪声是怎么加的?

前向过程加噪声是先小后大,因为一开始图片质量很高,加很小的噪声就发生很大的变化,而越后面的图片含有噪声越多,失真越严重,必须加更大的噪声才能引起较大变化。如果玩过文生图的话就能发现,选择了一定的采样步数后,前几步图片变化非常大,从模糊的噪声逐渐出现轮廓,后面几步基本不变,只是一些细节发生了变化。

  • 前向过程的最终结论

前向推导出加噪声过程可由 x 0 x_0 x0直接得到,那在训练过程就不必保存中间的过程变量,不需要一步步迭代,节省中间变量占用的内存。相当于前向过程是一个公式,时间复杂度是 O ( 1 ) O(1) O(1),整个模型的时间复杂度只取决于反向过程。

反向过程

反向过程其实就是在前面定义的基础上,本来想直接求解 q ( x t − 1 ∣ x t ) q(x_{t-1}|x_t) q(xt1xt)的。但是发现走不通,这样是完全求不出来的。而 q ( x t − 1 ∣ x t , x 0 ) q(x_{t-1}|x_t,x_0) q(xt1xt,x0)这个是有办法求解的(经过贝叶斯公式一系列变换),但是这样需要假设我们知道 x 0 x_0 x0的情况才行。因此需要加上 x 0 x_0 x0,然后我们用来进行训练一个模型,拟合训练数据的分布之后,就可以预测出 q ( x t − 1 ∣ x t ) q(x_{t-1}|x_t) q(xt1xt),即对任意噪声图片的任意时刻,我都能预测出前一时刻该图片的样子,不管准不准。问题建模成 p θ ( x t − 1 ∣ x t ) p_\theta(x_{t-1}|x_t) pθ(xt1xt)来求解, θ \theta θ就是求解的参数,实际上就是代表模型对 x 0 x_0 x0的预测能力

训练与采样

在这里插入图片描述

算法2的采样中, ϵ θ ( x t , t ) \epsilon_\theta(x_t,t) ϵθ(xt,t)表示的即是模型预测出来 t t t时候加上的噪声,结合如下代码更容易理解。

betas = torch.linspace(start=0.0001, end=0.02, steps=1000)
alphas = 1 - betas
alphas_cum = torch.cumprod(alphas, 0)
alphas_cum_s = torch.sqrt(alphas_cum)
alphas_cum_sm = torch.sqrt(1 - alphas_cum)# 扩散损失计算
def diffusion_loss(model, x0, t, noise):# 根据公式计算 xtxt = alphas_cum_s[t] * x0 + alphas_cum_sm[t] * noise# 模型预测噪声predicted_noise = model(xt, t)# 计算Lossreturn mse_loss(predicted_noise, noise)# 训练过程
for i in len(data_loader):# 从数据集读取一个 batch 的真实图片x0 = next(data_loader)# 采样时间步t = torch.randint(0, 1000, (batch_size,))# 生成高斯噪声noise = torch.randn_like(x_0)loss = diffusion_loss(model, x0, t, noise)optimizer.zero_grad()loss.backward()optimizer.step()

http://www.mrgr.cn/p/58342145

相关文章

分布式系统的发展史

目录 🐳今日良言:且视他人之疑目如盏盏鬼火,大胆地去走自己的夜路 🐇一、常见概念 🐇二、发展史 今日良言:且视他人之疑目如盏盏鬼火,大胆地去走自己的夜路 一、常见概念 在正式介绍分布式系…

M1 mac安装 Parallels Desktop 18 激活

M1 mac安装 Parallels Desktop 18 激活 下载安装Parallels Desktop 18.1.1 (53328) 激活1. 拷贝prl_disp_service2. 在终端打开Crack所在位置3. 输入命令,激活成功 下载 安装包和激活文件下载地址 链接: https://pan.baidu.com/s/1EjT7xeEDcntIIoOvvhBDfg?pwd9pue …

全国植被类型分布数据

引言 全国植被类型分布数据利用 Landsat 卫星数据(Landsat TM,ETM和 OLI)完成了长时序的地表覆盖变化检测,并结合变化 检测结果实现了逐区域和逐期的地表覆盖动态更新,30米精细植被类型分布数据,共包含 2…

由浅到深认识Java语言(31):阶段性练习

该文章Github地址:https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.c…

[蓝桥杯 2022 省 A] 求和

[蓝桥杯 2022 省 A] 求和 题目描述 给定 n n n 个整数 a 1 , a 2 , ⋯ , a n a_{1}, a_{2}, \cdots, a_{n} a1​,a2​,⋯,an​, 求它们两两相乘再相加的和,即 S a 1 ⋅ a 2 a 1 ⋅ a 3 ⋯ a 1 ⋅ a n a 2 ⋅ a 3 ⋯ a n − 2 ⋅ a n − 1 a n − 2 ⋅ a…

【Canvas与艺术】简约式胡萝卜配色汽车速度表

【效果图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>胡萝卜色汽车速度仪表盘简化版</title><style type"…

网页无插件视频播放器,支持录像、截图、音视频播放,多路播放等,提供源码下载

前言 本播放器内部采用jessibuca插件接口&#xff0c;支持录像、截图、音视频播放等功能。播放器播放基于ws流&#xff0c;分屏操作支持1分屏、4分屏、6分屏、9分屏方式。 jessibuca工作原理是通过Emscripten将音视频解码库编译成Js&#xff08;WebAssembly&#xff0c;简称was…

python 中判断文件、目录是否存在的方法

判断目录是否存在并创建目录 一、实现上传文件功能二、判断目录是否存在的办法2.1、使用os模块2.1.1、判断目录是否存在2.1.2、os.makedirs()&#xff1a;递归创建目录 2.2、使用pathlib模块2.2.1、path.exist()判断目录是否存在2.2.1、path.mkdir()&#xff1a;创建目录 2.3、…

【Linux】详解进程终止进程等待

一、页表&&写时拷贝的进一步理解 页表中不仅仅只有虚拟地址到物理地址的映射&#xff0c;还包括了很多选项&#xff0c;其中就包括了映射条目的权限。当我们进程的代码和数据加载到内存并和进程地址空间建立映射关系时&#xff0c;如果数据的内容不允许被修改&#xff…

测试一下MySQL四种隔离级别都做了什么

准备工作: 一个表:两条事务 ,每条事务有两条相同sql,update值改成A、B用作区分: 1.读未提交 1.1测试脏读:事务A执行update操作,不提交,事务B执行select查询结果。 期望:按照网上所说,应该会产生脏读问题,查询到未提交的值,即name = "事务A"。 测试结果:…

CSS问题精粹1

1.关于消除<li>列表前的符号 我相信很多人在初学CSS时会遇到该问题&#xff0c;无论是创作导航&#xff0c;还是列表&#xff0c;前面都会有个黑点点或其它符号。 解决该问题其实很简单 采用list-style-type:none或list-style:none直接解决 如果你想更换前面的黑点点&a…

代码随想录算法训练营第五十九天|● 503.下一个更大元素II ● 42. 接雨水

下一个更大元素II 题目链接:503. 下一个更大元素 II - 力扣(LeetCode) 思路:这里处理循环数组的方式值得学习,用i%nums.size()和for循环的上限来模拟两层for循环。整体思路还是单调栈。 class Solution { public:vector<int> nextGreaterElements(vector<int>…

零基础学python之高级编程(6)---Python中进程的Queue 和进程锁,以及进程池的创建 (包含详细注释代码)

Python中进程的Queue 和进程锁,以及进程池的创建 文章目录 Python中进程的Queue 和进程锁,以及进程池的创建前言一、进程间同步通信(Queue)二、进程锁&#xff08;Lock&#xff09;三、创建进程池Poorpool 类方法: End! 前言 大家好,上一篇文章,我们初步接触了进程的概念及其应…

C语言从入门到实战----数据在内存中的存储

1. 整数在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下⾯的内容&#xff1a; 整数的2进制表⽰⽅法有三种&#xff0c;即 原码、反码和补码 有符号的整数&#xff0c;三种表⽰⽅法均有符号位和数值位两部分&#xff0c;符号位都是⽤0表⽰“正”&#xff0c;⽤…

NO9 蓝桥杯单片机实践之串口通信的使用

1 回顾 串口通信的代码编写结构还是与中断一样&#xff0c;不同的是&#xff1a; 初始中断函数条件涉及到串口通信相关的寄存器和定时器1相关的寄存器&#xff08;定时器1用于产生波特率&#xff09;&#xff0c;但初始条件中的中断寄存器只考虑串口通信而不考虑定时器1。 vo…

Matlab|计及电池储能寿命损耗的微电网经济调度

目录 1 主要内容 储能寿命模型 负荷需求响应 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考文献《考虑寿命损耗的微网电池储能容量优化配置》模型&#xff0c;以购售电成本、燃料成本和储能寿命损耗成本三者之和为目标函数&#xff0c;创新考虑储能寿命损耗约…

程序员如何兼职赚小钱?

程序员由于有技术和手艺其实兼职赚钱的路子还是挺多的&#xff0c;只要你有足够的时间。 1. 做外包 这是比较传统的方式&#xff0c;甲方在一些众包平台上发布开发任务&#xff0c;你可以抢这个任务&#xff0c;但是价格都比较便宜。 任务比较多的平台: 猪八戒、一品威客、开…

C语言指针详解(上)

一.什么是指针 指针是一种类型&#xff0c;用来存储变量的地址的类型 有哪些类型呢 字符指针&#xff1a;char* 整型指针&#xff1a;int* 浮点型指针&#xff1a;float* 双精度浮点型指针&#xff1a;double* 空指针&#xff1a;void* &#xff08;每一个类型的指针&a…

ubuntu没有有线网络的一种解决办法

直接使用下面的代码: sudo nmcli networking off sudo nmcli networking on转自 Ubuntu 20.04 LTS 有线网络设置消失了怎么办 - 知乎 (zhihu.com) 评论区第一条 理客Lick - 知乎 (zhihu.com)Keep it simple and stupid

Huawei设备基础配置

<Huawei>system-view # 进入系统视图 [Huawei]telnet server enable # 开启设备telnet功能 [Huawei]user-interface vty 0 4 # 开启登录端口0-4并进入用户接口视图 [Huawei-ui-vty0-4]protocol inbound telnet # 通过telnet协议登录 [Huawei-ui-vty0-4]authentic…