扩散模型浅析

扩散模型浅析

背景-Why

为什么会提出扩散模型

VAE过程

variational auto-encoder(VAE) :先定义隐变量z满足正态分布,后定义条件分布 pθ(x|z),从而定义了 z 和 x 的联合分布。训练模型时,先采样得到隐变量z,后根据z和条件分布得到x。

整个过程理解为:把标准高斯z通过条件分布pθ(x|z)映射到数据分布X上。

  • 出现问题

训练VAE基于最大似然,而 log⁡pθ(x) 的计算是intractable的(因为真实后验无法计算),通常我们都需要借助variational inference的技巧

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbCUmpC9-1667304334719)(images/TIg3zKEgoUjCphT-7pNZmePO7arbSw5sXAMF4r6ZtP0.png)]

训练VAE的本质是训练右边期望最大值。同时训练 pθ(x|z) 和 qϕ(z|x),当他们相等时取到最大值。

VAE的核心是如何选择 qϕ(z|x)能保证得到最大值?选择简单无法接近真实后验,导致模型效果不好;选择复杂,log( qϕ(z|x))难以计算,导致难以优化。

  • 核心难点

变分后验的表达能力和计算代价的权衡一直是VAE领域核心痛点

GAN和Normalizing Flow

都是直接使用高斯噪声生成数据分布,不需要关注后验分布,简单直接;

但GAN需要额外训练辨别器来辨别生成结果是否真实(难以训练);

Normalizing Flow要求映射函数是可逆的,保证生成结果对应,但一般的神经网络模型不满足要求,限制其应用;

是否有一种生成模型,只需要生成器,目标函数简单,不需要额外网络,表达能力强?

diffusion model!

真正把diffusion model首次做work的工作是2020年提出的DDPM

扩散模型的核心思路

VAE中需要考虑变分后验,难以选择合适的变分后验。既能考虑到将高斯噪声映射到数据分布,又要变分后验与生成函数接近,保证最大期望,这个要求太高。但VAE的思路是先定义生成器后选择合适后验分布匹配,是否可以先选择简单“后验分布”,再定义生成器来匹配它?由此提出diffusion model,先计算数据分布映射到高斯噪声的映射关系,再通过生成器学习高斯噪声到数据分布的逆过程即可。

核心思想:学习前向过程中每一步的逆过程

原理-What

确定了核心思想:学习简单前向过程每一步的逆过程,如何达到这个目标呢?

使用马尔科夫链,不论从什么分布出发,只要一直采样都能得到想要的平稳分布(stationary distribution)。而把数据映射到标准高斯分布的过程其实非常简单:构造一个平稳分布是标准高斯分布的马尔科夫链即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NlogG1Lr-1667304334720)(images/lgb86NV2gmZvuQ1FGgRJ9yjh2f29QBpMkedCCJEvArk.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RxTx80ah-1667304334720)(images/RjUuj8h0kz-xNynaRDVXtaHTu_ljYDdcu2rYLbOC0-g.png)]

重点是:前向过程的每一小步的逆过程都可以近似为高斯分布!(原理证明文章

如果选取的bate很小,可以用高斯分布近似其逆过程。

这也是为什么diffusion model里经常会见到用一个参数化的高斯分布 pθ(xt−1|xt) 来近似逆向过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m74Xxsga-1667304334720)(images/NAT5oCjzhXyesMOqYRd8xbO7UmtaQuPStW8u_zI0-cw.png)]

可以用一个直观的图来感受一下。diffusion model定义了一个简单的前向过程(下面那行),不断地加噪来把真实数据映射到标准高斯;然后又定义一个逆向过程来去噪(上面那行),并且逆向过程的每一步只需要是一个很简单的高斯分布即可。

总而言之,从理论角度来看,diffusion model的成功在于我们训练的模型只需要“模仿”一个简单的前向过程对应的逆向过程,而不需要像其它模型那样“黑盒”地搜索模型。并且,这个逆向过程的每一小步都非常简单,只需要用一个简单的高斯分布来拟合。这为diffusion model的优化带来了诸多便利,这也是它empirical performance非常好的原因之一。

Diffusion model的定义:去噪模型与score function的联系

考虑我们上一节介绍的平稳分布为标准高斯分布的马尔科夫链的连续版本:随机微分方程(SDE)。前向过程就是一个不断加噪声的SDE,它唯一对应了一个逆向过程(reverse SDE),其中的未知量只有每一时刻的score function:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6muFwMSk-1667304334721)(images/7UIcMSOCBgxMZ2NcMafKPB8gBb0Y7fsdovFUqey-EuQ.jpeg)]

所谓的“去噪模型”与score function其实是等价的loss,这其实只需要用denoising score matching的一个性质就可以证明。有些文章里会出现“去噪”,而有些文章又会出现“估计噪声”,有些文章又会出现“score function”,但其实它们都是等价的参数化

应用-How

代码中主要三个任务:超分、补全和文本生成图像;
autoencode用于编码特征,进行超分训练;

Image Super-Resolution via Iterative Refinement pdf code 解析 (CVPR2021)
Palette: Image-to-Image Diffusion Models pdf code (sigraph 2022)
guided-diffusion code (openai)
openai/improved-diffusion
diffusion based model for colorization code (slight)

参考

清华博士知乎文章

华科DDPM介绍

diffusion model详细介绍

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocal 是 Java 中的一个类,它提供了一种线程局部变量的机制。线程局部变量是指每个线程都有自己的变量副本,每个线程对该变量的访问都是独立的,互不影响。 ThreadLocal 主要用于解决多线程并发访问共享变量时的线程安全问题。在多线程环境下,如果多个线程共同访问同一个变量,可能会出现竞争条件,导致数据不一致或者出现线程安全问题。通过使用 ThreadLocal,可以为每个线程提供独立的副本,从而避免了线程安全问题。 ThreadLocal 的工作原理是,每个 Thread 对象内部都维护了一个 ThreadLocalMap 对象,ThreadLocalMap 是一个 key-value 结构,其中 key 是 ThreadLocal 对象,value 是该线程对应的变量副本。当访问 ThreadLocal 的 get() 方法时,会根据当前线程获取到对应的 ThreadLocalMap 对象,并从中查找到与 ThreadLocal 对象对应的值。如果当前线程尚未设置该 ThreadLocal 对象的值,则会通过 initialValue() 方法初始化一个值,并将其存入 ThreadLocalMap 中。当访问 ThreadLocal 的 set() 方法时,会将指定的值存入当前线程对应的 ThreadLocalMap 中。 需要注意的是,ThreadLocal 并不能解决共享资源的并发访问问题,它只是提供了一种线程内部的隔离机制。在使用 ThreadLocal 时,需要注意合理地使用,避免出现内存泄漏或者数据不一致的情况。另外,由于 ThreadLocal 使用了线程的 ThreadLocalMap,因此在使用完 ThreadLocal 后,需要手动调用 remove() 方法清理对应的变量副本,以防止内存泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值