当前位置: 首页 > news >正文

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录

    • 1、Diffusion的整体过程
    • 2、加噪过程
      • 2.1 加噪的具体细节
      • 2.2 加噪过程的公式推导
    • 3、去噪过程
      • 3.1 图像概率分布
    • 4、损失函数
    • 5、 伪代码过程

此文涉及公式推导,需要参考这篇文章: Stable Diffusion扩散模型推导公式的基础知识

1、Diffusion的整体过程

扩散过程是模拟图像加噪的逆向过程,也就是实现去噪的过程,
加噪是如下图从右到左的过程,称为反向扩散过程,
去噪是从左往右的过程,称为前向扩散过程,

在这里插入图片描述

2、加噪过程

加噪过程如下图,下一时刻的图像是在上一时刻图像的基础上加入噪音生成的,
图中公式的含义: x t x_t xt表示 t 时刻的图像, ϵ t \epsilon_t ϵt 表示 t 时刻生成的随机分布的噪声图像, β t \beta_t βt表示 t 时刻指定的常数,不同时刻的 β t \beta_t βt不同,随着时间 t 的递增而增加,但需要注意 β t \beta_t βt的值始终是比较小的,因为要让图像的数值占较大的比例,

在这里插入图片描述

2.1 加噪的具体细节

A、将图像 x x x像素值映射到[-1,1]之间

图像加噪不是在原有图像上进行加噪的,而是通过把图片的每个像素的值转换为-1到1之间,比如像素的值是 x x x,则需要经过下面公式的处理 x 255 × 2 − 1 \frac{x}{255}\times2-1 255x×21,转换到范围是-1到1之间,

代码:

def get_transform():class RescaleChannels(object):def __call__(self, sample):return 2 * sample - 1return torchvision.transforms.Compose([torchvision.transforms.ToTensor(), RescaleChannels()])

B、生成一张尺寸相同的噪声图片,像素值服从标准正态分布
ϵ ∼ N ( 0 , 1 ) \epsilon \sim N(0,1) ϵN(0,1)

x = {Tensor:(2, 3, 32, 32)}
noise = torch.randn_like(x)

C、 α \alpha α β \beta β
每个时刻的 β t \beta_t βt都各不相同,0 < β t \beta_t βt< 1,因为 β t \beta_t βt是作为权重存在的,且 β 1 < β 2 < β 3 < β T − 1 < β T \beta_1< \beta_2< \beta_3< \beta_{T-1}< \beta_T β1<β2<β3<βT1<βT

代码:

betas = generate_linear_schedule(args.num_timesteps,args.schedule_low * 1000 / args.num_timesteps,args.schedule_high * 1000 / args.num_timesteps)

β \beta β的取值代码,比如 β 1 \beta_1 β1取值low, β T \beta_T βT取值high,

# T:1000 Low/β1: 0.0001 high/βT: 0.02
def generate_linear_schedule(T, low, high):return np.linspace(low, high, T)

α t = 1 − β t \alpha_t=1-\beta_t αt=1βt,alphas = 1.0 - betas

alphas = 1.0 - betas
alphas_cumprod = np.cumprod(alphas)
to_torch = partial(torch.tensor, dtype=torch.float32)
self.registerbuffer("betas", totorch(betas))
self.registerbuffer("alphas", totorch(alphas))
self.register_buffer("alphas_cumprod", to_torch(alphas_cumprod))
self.register_buffer("sqrt_alphas_cumpnod", to_torch(np.sqrt(alphas_cumprod)))
self.register_buffer("sart_one_minus_alphas_cumprod", to_torch(np.sqrt(1 - alphas_cumprod)))
self.registerbuffer("reciprocal sart_alphas", totorch(np.sart(1 / alphas)))
self.register_buffer("remove_noise_coeff", to_torch(betas / np.sqrt(1 - alphas_cumprod)))
self.registerbuffer("siqma",to_torch(np.sqrt(betas)))

D、任一时刻的图像 x t x_t xt都可以由原图像 x 0 x_0 x0直接生成(可以由含 x 0 x_0 x0的公式直接表示)

x t x_t xt x 0 x_0 x0的关系: x t = 1 − α t ‾ ϵ + α t ‾ x 0 x_t=\sqrt{1-\overline{\alpha_t}}\epsilon+\sqrt{\overline{\alpha_t}}x_0 xt=1αt ϵ+αt x0 α t = 1 − β t \alpha_t=1-\beta_t αt=1βt α t ‾ = α t α t − 1 . . . α 2 α 1 \overline{\alpha_t}=\alpha_t\alpha_{t-1}...\alpha_2\alpha_1 αt=αtαt1...α2α1

由上式可知, β t \beta_t βt是常数,则 α t \alpha_t αt 1 − α t ‾ \sqrt{1-\overline{\alpha_t}} 1αt α t ‾ \sqrt{\overline{\alpha_t}} αt 也是常数, ϵ \epsilon ϵ也是已知的,所以可以直接由 x 0 x_0 x0生成 x t x_t xt

def perturb_x(self, x, t, noise):return (extract(self.sqrt_alphas_cumprod, t, x.shape) * x +extract(self.sqrt_one_minus_alphas_cumprod, t, x.shape) * noise)
def extract(a, t, x_shape):b, *_ = t.shapeout = a.gather(-1, t)return out.reshape(b, *((1,) * (len(x_shape) - 1)))

2.2 加噪过程的公式推导

加噪过程:

在这里插入图片描述

加噪过程的公式:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:

在这里插入图片描述

3、去噪过程

去噪是加噪的逆过程,由时间T时刻的图像逐渐去噪到时刻为0的图像,
下面介绍一下由时刻为T的图像 x T x_T xT去噪到时刻为T-1的图像 x T − 1 x_{T-1} xT1,输入为时刻为t的图像 x t x_t xt和时刻t,喂给Unet网络生成 ϵ θ \epsilon_\theta ϵθ,其中 θ \theta θ是Unet网络的所有参数,然后由下图中的 x t − 1 {\bf x}_{t-1} xt1的公式即可生成时刻为t-1的图像 x t − 1 {\bf x}_{t-1} xt1

在这里插入图片描述

3.1 图像概率分布

去噪过程的2个假设:
(1)加噪过程看作马尔可夫链,假设去噪过程也是马尔可夫链,
(2)假设去噪过程是高斯分布,

在这里插入图片描述

假设数据集中有100张图片,每张图片的shape是4x4x3,假设每张图片的每个channel的每个像素点都服从正态分布, x t − 1 x_{t-1} xt1的正态分布的均值 μ \mu μ 和方差 σ 2 \sigma^2 σ2 只和 x t x_t xt有关,已知在t时刻的图像,求t-1时刻的图像,

在这里插入图片描述

1、因为均值和方差 μ ( x t ) \mu(x_t) μ(xt) σ 2 ( x t ) \sigma^2(x_t) σ2(xt) 无法求出,所以我们决定让网络来帮我们预测均值和方差,
2、因为每一个像素都有自己的分布,都要预测出一个均值和方差,所以网络输出的尺寸需要和图像尺寸一致,所以我们选用 Unet 网络,
3、作者在论文中表示,方差并不会影响结果,所以网络只要预测均值就可以了,

4、损失函数

在这里插入图片描述
我们要求极大似然的最大值,需要对 μ \mu μ σ \sigma σ求导,但是对于扩散的过程是不可行的,如下面的公式无法求出,因为 x 1 : x T x_1:x_T x1:xT的不同组合所求出的 x 0 x_0 x0的值也不同,
p ( x 0 ) = ∫ x 1 : x T p ( x 0 ∣ x 1 : x T ) d x 1 : x T p(x_0)=\int_{x_1:x_T}p(x_0|x_1:x_T)d_{x_1:x_T} p(x0)=x1:xTp(x0x1:xT)dx1:xT

为了实现对极大似然函数的求导,把对极大似然求导的问题转换为ELBO :Evidence Lower Bound

在这里插入图片描述

对ELBO的公式继续进行化简,

在这里插入图片描述
在这里插入图片描述
首先来看 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 t x_t xt的情况下推导 x t − 1 x_{t-1} xt1,这个公式是可以求解的,如上图公式推导; p θ ( x t − 1 ∣ x t ) p_{\theta}(x_{t-1}|x_t) pθ(xt1xt)需要使用 Unet 预测出该分布的均值,

q ( x t − 1 ∣ x t , x 0 ) q(x_{t-1}|x_t,x_0) q(xt1xt,x0)公式的推导如下:

在这里插入图片描述
在这里插入图片描述

综上可知,UNet是在预测下面的公式,下面的公式中除了 ϵ \epsilon ϵ之外都是已知量,所以UNet网络实际预测的就是 ϵ \epsilon ϵ
在这里插入图片描述

5、 伪代码过程

下图是训练阶段的伪代码,第1行和第6行表示第2行到第5行的代码一直在循环,
第2行:从数据集中筛选出一张图像,即为 x 0 \bf{x}_0 x0,
第3行:从0到 T T T的均匀分布中筛选出 t t t,源码中 T T T的范围设为1000,
第4行:从均值为0,方差为1的标准正态分布中采样出 ϵ \epsilon ϵ ϵ \epsilon ϵ的size和 x 0 \bf{x}_0 x0的size是相同的,
第5行: x t x_t xt和从0到 T T T的均匀分布中筛选出 t t t喂给Unet,输出 ϵ θ \epsilon_\theta ϵθ,和第4行代码采样出的 ϵ \epsilon ϵ ∣ ∣ ϵ − ϵ θ ( . . . ) ∣ ∣ 2 ||\epsilon-\epsilon_\theta(...)||^2 ∣∣ϵϵθ(...)2的均方差作为损失函数,对这个损失函数求梯度进行参数更新,参数是Unet所有参数的集合 θ \theta θ

在这里插入图片描述

下图是推导/采样/生成图片阶段的伪代码,

第1行:从随机分布中采样一个 x T {\bf x}_T xT
第2行:遍历从 T T T到1,
第3行:从随机分布中采样一个 z \bf{z} z
第4行:已知 z \bf{z} z α t \alpha_t αt σ t \sigma_t σt ϵ θ \epsilon_\theta ϵθ是Unet网络生成的,就可以得到 x t − 1 {\bf x}_{t-1} xt1
循环2-4行代码,

在这里插入图片描述


在这里插入图片描述

参考:
1、CSDN链接:链接
2、哔哩视频:https://www.bilibili.com/video/BV1ju4y1x7L4/?p=5&spm_id_from=pageDriver
3、论文Denoising Diffusion Probabilistic Models:https://arxiv.org/pdf/2006.11239.pdf

相关文章:

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导&#xff0c;需要参考这篇文章&#xff1a; Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…...

关于rabbitmq的prefetch机制

消息预取机制&#xff08;Prefetch Mechanism&#xff09;是RabbitMQ中用于控制消息传递给消费者的一种机制。它定义了在一个信道上&#xff0c;消费者允许的最大未确认的消息数量。一旦未确认的消息数量达到了设置的预取值&#xff0c;RabbitMQ就会停止向该消费者发送更多消息…...

机器学习介绍

机器学习是人工智能&#xff08;AI&#xff09;的一个分支&#xff0c;它使计算机系统能够从数据中学习并改进它们的性能。机器学习的核心在于开发算法&#xff0c;这些算法可以从大量数据中识别模式和特征&#xff0c;并用这些信息来做出预测或决策&#xff0c;而无需进行明确…...

OpenCV4.9开发之Window开发环境搭建

1.打开OpenCV所在github地址 2.点击opencv仓库,进入仓库详情,点击右下方的OpenCV 4.9.0进入下载页面 3.点击opencv-4.9.0-windows.exe下载 开始下载中... 下载完成 下载完成后,双击运行解压,默认解压路径,修改为c:/...

DDD 中的实体和值对象有什么区别?

在DDD中&#xff0c;实体 Entity 和值对象 Value Object 是两个基本的概念&#xff0c;它们之间有一些重要的区别。 唯一性&#xff1a;实体是唯一的&#xff0c;每个实体都有一个唯一的标识符&#xff0c;即使它的属性在一段时间内发生了变化&#xff0c;它仍然是这个实体。与…...

算法-最值问题

#include<iostream> using namespace std; int main() {int a[7];//上午上课时间int b[7];//下午上课时间int c[7];//一天总上课时间for (int i 0; i < 7; i) {cin >> a[i] >> b[i];c[i] a[i] b[i];}int max c[0];//max记录最长时间int index -1;//索…...

Go 性能压测工具之wrk介绍与使用

在项目正式上线之前&#xff0c;我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug&#xff1b;压力测试&#xff08;压测&#xff09;是确保系统在高负载情况下仍能稳定运行的重要步骤。通过模拟高并发场景&#xff0c;可以评估系统的性能瓶颈、可靠…...

数学思想论(有目录)

数学思想是数学发展过程中的重要指导原则,它涉及对数学概念、方法和理论的理解和认识,以及如何利用这些工具来解决实际问题。数学思想的形成和演进是随着数学的发展而逐渐深化的,它体现了人类对数学本质和应用的不断探索和思考。 一些主要的数学思想包括: 函数与方程思想…...

C++的并发世界(五)——线程状态切换

0.线程状态 初始化&#xff1a;该线程正在被创建&#xff1b; 就绪&#xff1a;该线程在列表中就绪&#xff0c;等待CPU调度&#xff1b; 运行&#xff1a;该线程正在运行&#xff1b; 阻塞&#xff1a;该线程被阻塞挂机&#xff0c;Blocked状态包括&#xff1a;pend&#xff…...

C语言——指针

地址是由物理的电线上产生的&#xff0c;能够标识唯一一个内存单元。在C语言中&#xff0c;地址也叫做指针。 在32位机器中&#xff0c;有32根地址线。地址是由32个0/1组成的二进制序列&#xff0c;也就是用4个字节来存储地址。 在64位机器中&#xff0c;有64根地址线。地址是…...

手搓二分查找

第一种&#xff1a; 该种方法是若a[mid]目标数&#xff0c;则让r一直等于mid&#xff0c;让l往右移动&#xff0c;一直移动到rl&#xff0c;这时候跳出循环&#xff0c;在循环外判断 但是不能写成让lmid&#xff0c;让r往左移动&#xff0c;比如a[2]key&#xff0c;这时&#x…...

pycharm调试(步过(Step Over)、单步执行(Step Into)、步入(Step Into)、步出(Step Out))

pycharm调试 pycharm调试 pycharm调试为什么要学会调试&#xff1f;1. 步过 (Step Over)2. 单步执行 (Step Into)3. 步入&#xff08;Step Into&#xff09;4. 步出&#xff08;Step Out&#xff09; 为什么要学会调试&#xff1f; 调试可以帮助初学者更深入地理解编程基础&am…...

Linux是什么,该如何学习

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Linux的起源与发展 2、Linux在现代计算机领域…...

C++ | Leetcode C++题解之第7题整数反转

题目&#xff1a; 题解&#xff1a; class Solution { public:int reverse(int x) {int rev 0;while (x ! 0) {if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {return 0;}int digit x % 10;x / 10;rev rev * 10 digit;}return rev;} };...

Linux------一篇博客了解Linux最常用的指令

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;Linux &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#…...

vscode安装通义灵码

作为vscode的插件&#xff0c;直接使用 通义灵码-灵动指间&#xff0c;快码加编&#xff0c;你的智能编码助手 通义灵码&#xff0c;是一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研…...

RIP协议(路由信息协议)

一、RIP协议概述 RIP协议&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;即根据跳数来度量路由开销&#xff0c;进行路由选择。 相比于其它路由协议&#xff08;如OSPF、ISIS等&#xff09;&#…...

SpringBoot根据配置类动态加载不同环境下的自定义配置

dev环境配置 Profile({"dev","test"}) PropertySource("classpath:dev.properties") public class DevConfigLoader { }Profile("prod") PropertySource("classpath:prod.properties") public class ProdConfigLoader { }P…...

什么?穷哥们没钱RLHF?跟我一起DPO吧,丐版一样用

本次DPO训练采用TRL的方式来进行训练 Huggingface TRL是一个基于peft的库&#xff0c;它可以让RL步骤变得更灵活、简单&#xff0c;你可以使用这个算法finetune一个模型去生成积极的评论、减少毒性等等。 本次进行DPO的模型是一个500M的GPT-2&#xff0c;目的是训练快&#x…...

【Leetcode笔记】102.二叉树的层序遍历

目录 知识点Leetcode代码&#xff1a;ACM模式代码&#xff1a; 知识点 vector、queue容器的操作 对vector<int> vec;做插入元素操作&#xff1a;vec.push_back(x)。对queue<TreeNode*> que;做插入元素操作&#xff1a;que.push(root);。队列有四个常用的操作&…...

进程的状态

目录 1.操作系统的进程状态 2.Linux系统的进程状态 特殊的进程状态 进程的查看 1.操作系统的进程状态 a.新建&#xff1a;就是新建一个进程 b.运行&#xff1a;PCB结构体在运行队列中排队 c.阻塞&#xff1a;PCB结构体在等待队列中&#xff0c;等待非CPU资源就续 d:挂起…...

spring-boot集成websocket

引入Maven依赖包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>跟随spingboot版本</version> </dependency>后端代码 /*** 开启WebSocket支持*…...

【Python】【Flask】提交表单后报500错误

【背景】 日常用户使用的一个Online的基于Flask做的工具,今天忽然报错,看现象是点击表单提交按钮后发生错误。报500内部错误。 【分析】 用print步步为营接近root cause。 报错对应视图函数的展示部分正常执行。提交表单按钮后的内容全部没有正常执行。 提交表单用的方法是…...

Golang vs Java

目录 前言 一、语言背景与特性 二、性能与效率 三、生态系统与库支持 四、开发体验与工具支持 五、微服务架构设计中的对比 六、总结与建议 前言 在当今的软件开发世界中&#xff0c;选择合适的编程语言对于项目的成功至关重要。GoLang&#xff08;也称为Golang&#x…...

HomePlug AV

目录 HomePlug AV的基本概念基本术语网络概念网络实例 HomePlug AV物理层&#xff08;PHY&#xff09;HomePlug AV OFDM收发器架构PHY的调制模式FC调制和ROBO调制物理层的特点OFDM频域/时域转换开窗/槽式OFDM信号和噪声PHY发送控制——信道自适应PHY帧格式&#xff08;Symbol&a…...

【面试八股总结】超文本传输协议HTTP(二)

参考资料 &#xff1a;小林Coding、阿秀、代码随想录 一、HTTP缓存技术 将资源&#xff08;如网页、图像、脚本等&#xff09;的副本存储在客户端或中间代理服务器上&#xff0c;以便将来的请求可以直接从缓存中获取&#xff0c;而不必重新从服务器下载资源。这有助于减少网…...

SQL Server中视图使用子查询的性能影响与优化方案

在SQL Server中&#xff0c;视图&#xff08;View&#xff09;是一种虚拟的表&#xff0c;其内容由查询定义。在视图中&#xff0c;我们可以使用子查询来组合和呈现数据&#xff0c;这为数据呈现提供了灵活性&#xff0c;但同时也可能带来一些性能上的问题。本文将深入分析视图…...

Adaboost集成学习 | Matlab实现基于SVM-Adaboost支持向量机结合Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料效果一览 基本介绍 Adaboost集成学习 | 基于SVM-Adaboost支持向量机结合Adaboost集成学习时间序列预测(股票价格预测)基于SVM(支持向量机)和AdaBoost集成学习的时间序列预测(如股票价格预测)是一种结合了两种强大机器学习算…...

Apache DolphinScheduler 【安装部署】

前言 今天来学习一下 DolphinScheduler &#xff0c;这是一个任务调度工具&#xff0c;现在用的比较火爆。 1、安装部署 1.0、准备工作 1.0.1、集群规划 dolphinscheduler 比较吃内存&#xff0c;所以尽量给 master 节点多分配一点内存&#xff0c;桌面和虚拟机里能关的应用…...

【随笔】Git -- 高级命令(上篇)(六)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…...

厦门网站建设开发/哪个网站做推广效果好

这几天在做ASP.NET网站&#xff0c;后台数据库就用轻便的Access作数据库。我发现Access虽然相对MSSQL简单小巧&#xff0c;不用那么多的设置&#xff0c;但它也不轻松。如果你对它执行SQL语句的操作&#xff0c;万一表名或者字段名使用了它的关键字&#xff0c;那么就会抛出异常…...

做电影网站犯罪吗/百度官网下载

摘 要&#xff1a;针对《计算机应用基础》传统课堂教学存在的弊端&#xff0c;文章提出《计算机应用基础》课程要转变教学环境&#xff0c;实施机房教学模式&#xff0c;从创设情境、提出问题、主动探究、交流反馈四个步骤开展机房教学改革&#xff0c;目的在于培养学员的自主探…...

做淘宝需要知道什么网站/福州网站排名推广

创建父工程 idea创建父工程 idea创建一个工程。父工程管理公共资源 添加子模块 选择添加到父工程里面spring_cloud_parent 相应的子模块添加到父工程的pom.xml文件里 转载于:https://www.cnblogs.com/mentalidade/p/10326343.html...

做mod的网站/网络游戏推广员的真实经历

ssh docker attach docker attach 必须登陆到已经运行的容器里&#xff0c;如果从这个容器exit或ctrl c退出的话&#xff0c;会导致容器停止,而且可能进入不成功docker attach同时多人进入的话&#xff0c;执行的所有操作&#xff0c;每个进入的人都可以同步看到对应的操作信…...

wordpress+HTML5游戏/重庆 seo

1.先从微软网站下载补丁. 下载地址1为&#xff1a;http://download.microsoft.com/download/8/0/7/8071514d-9370-45c3-8af1-4ff09a70e59d/VS80sp1-KB926604-X86-CHS.exe&#xff08;中文版&#xff09;大约为430M。2.作好打VS2005 SP1补丁之前的设置. 第一步&#xff1a;…...

花卉网站建设策划书/什么是搜索引擎优化的核心

对于 React 组件来说&#xff0c;refs 会指向一个组件类的实例&#xff0c;所以可以调用该类定义的任何方法。 如果需要访问该组件的真实 DOM&#xff0c;可以用 ReactDOM.findDOMNode 来找到 DOM 节点&#xff0c;但我们并 不推荐这样做。因为这在大部分情况下都打破了封装性&…...