【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)

深入理解扩散模型:Diffusion Models

  • 引言
  • 扩散模型的原理
    • 扩散过程
    • 反向过程
    • 优化目标
  • 模型设计
  • 代码实现
  • Stable Diffusion、DALL-E、Imagen背后共同的套路
    • Stable Diffusion
    • DALL-E series
    • Imagen
    • Text encoder
    • Decoder
    • 什么是FID(Frechet Inception Distance)
    • 什么是CLIP(Contrastive Language-Image Pre-Training)
  • Diffusion Model: Summary
    • Diffusion Model in PyTorch
  • 参考资料

本文综合最近阅读的关于扩散模型的一些基础博客和文章整理而成。主要参考的内容来自 Calvin Luo 的论文,针对的对象主要是对扩散模型已经有一些基础了解的读者。

引言

继OpenAI在2021提出的文本转图像模型DALLE之后,越来越多的大公司卷入这个方向,例如谷歌相继推出了ImagenParti。一些主流的文本转图像模型,例如DALL·E 2stable-diffusionImagen采用了扩散模型(Diffusion Model)作为图像生成模型,这也引发了对扩散模型的研究热潮。

与GAN相比,扩散模型训练更稳定,而且能够生成更多样的样本,OpenAI的论文Diffusion Models Beat GANs on Image Synthesis也证明了<font color=’red>扩散模型能够超越GAN。
Diffusion Models Beat GANs on Image Synthesis
论文地址:https://arxiv.org/abs/2105.05233

简单来说,扩散模型包含两个过程:前向扩散过程和反向生成过程前向扩散过程是对一张图像逐渐添加高斯噪音直至变成随机噪音,而反向生成过程是去噪音过程,我们将从一个随机噪音开始逐渐去噪音直至生成一张图像,这也是我们要求解或者训练的部分。扩散模型与其它主流生成模型的对比如下所示:
扩散模型与其他主流生成模型
目前所采用的扩散模型大都是来自于2020年的工作DDPM: Denoising Diffusion Probabilistic Models,DDPM对之前的扩散模型(具体见Deep Unsupervised Learning using Nonequilibrium Thermodynamics)进行了简化,并通过变分推断variational inference)来进行建模,这主要是因为扩散模型也是一个隐变量模型latent variable model),相比VAE这样的隐变量模型,扩散模型的隐变量是和原始数据是同维度的,而且推理过程(即扩散过程)往往是固定的本文将基于DDPM详细介绍扩散模型的原理,并给出具体的代码实现和分析。
Denoising Diffusion Probabilistic Models
论文地址:https://arxiv.org/abs/2006.11239

扩散模型的原理

扩散模型包括两个过程:前向过程forward process)和反向过程reverse process),其中前向过程又称为为扩散过程diffusion process),如下图所示。无论是前向过程还是反向过程都是一个参数化的马尔可夫链Markov chain ),其中反向过程可以用来生成数据,这里我们将通过变分推断来进行建模和求解
扩散模型的原理

扩散过程

扩散过程是指的对数据逐渐增加高斯噪声直至数据完全变成随机噪声的过程。对于原始数据【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇),总共包含【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)步的扩散过程的每一步都是对上一步得到的数据【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)按如下方式增加高斯噪声:
【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)
这里【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)为每一步所采用的方差,它介于【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)之间。对于扩散模型,往往称不同step的方差设定为variance schedule或者noise schedule,通常情况下,越后面的step会采用更大的方差,即满足【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)。在一个设计好的variance schedule下,如果扩散步数【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)足够大,那么最终得到的【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)就完全丢失了原始数据而变成了一个随机噪音。 扩散过程的每一步都生成一个带噪音的数据【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇),整个扩散过程也就是一个马尔卡夫链
【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)
Forward diffusion process

扩散过程的这个特性很重要。首先,可以看到【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)其实可以看成是原始数据【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)和随机噪音【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)的线性组合,其中【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)为组合系数,它们的平均和等于1,可以称两者分别为signal_ratenoise_rate

参考:https://keras.io/examples/generative/ddim/#diffusion-schedule和Variational Diffusion Models

更进一步,可以基于【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)而不是【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)来定义noise schedule(见Improved Denoising Diffusion Probabilistic Models所设计的cosine schedule),因为这样处理更直接,比如我们直接将【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)设定为一个接近0的值,那么就可以保证最终得到的【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)近似为一个随机噪声。其次,后面的建模和分析过程将使用这个特性。
扩散过程

反向过程

扩散过程是将数据噪声化,那么反向过程就是一个去噪的过程。如果我们知道反向过程的每一步的真实分布【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇),那么从一个随机噪音【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)开始,逐渐去噪,就能生成一个真实的样本,所以反向过程也就是生成数据的过程。
反向过程

虽然分布【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)是不可直接处理的,但是加上条件【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)的后验分布【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)却是可处理的,这里有:【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)
下面来具体推导这个分布。首先根据贝叶斯公式,有:【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)
由于扩散过程的马尔可夫链特性,知道分布【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)(这里条件【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)是多余的),而由前面得到的扩散过程特性可知:【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)
所以,有:
反向过程

优化目标

上面介绍了扩散模型的扩散过程和反向过程,现在我们来从另外一个角度来看扩散模型:如果把中间产生的变量看成隐变量的话,那么扩散模型其实是包含T个隐变量的隐变量模型latent variable model),它可以看成是一个特殊的Hierarchical VAEs(见Understanding Diffusion Models: A Unified Perspective)
Understanding Diffusion Models: A Unified Perspective

不过实际的代码实现和上述过程略有区别(见https://github.com/hojonathanho/diffusion/issues/5:先基于预测的噪音生成【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇),并进行了clip处理(范围[-1, 1],原始数据归一化到这个范围),然后再计算均值。这应该算是一种约束,既然模型预测的是噪音,那么我们也希望用预测噪音重构处理的原始数据也应该满足范围要求

模型设计

前面我们介绍了扩散模型的原理以及优化目标,那么扩散模型的核心就在于训练噪音预测模型,由于噪音和原始数据是同维度的,所以我们可以选择采用AutoEncoder架构来作为噪音预测模型。DDPM所采用的模型是一个基于residual blockattention blockU-Net模型。如下所示:
U-Net模型

另外,扩散模型其实需要的是个噪音预测模型,实际处理时,我们可以增加一个time embedding(类似transformer中的position embedding)来将timestep编码到网络中,从而只需要训练一个共享的U-Net模型。具体地,DDPM在各个residual block都引入了time embedding,如上图所示。

代码实现

最后,我们基于PyTorch框架给出DDPM的具体实现,这里主要参考了三套代码实现:

  • GitHub – hojonathanho/diffusion: Denoising Diffusion Probabilistic Models(官方TensorFlow实现)
  • GitHub – openai/improved-diffusion: Release for Improved Denoising Diffusion Probabilistic Models (OpenAI基于PyTorch实现的DDPM+)
  • GitHub – lucidrains/denoising-diffusion-pytorch: Implementation of Denoising Diffusion Probabilistic Model in Pytorch

Stable Diffusion、DALL-E、Imagen背后共同的套路

Framework
Framework

  1. Text Encoder: 使用Text Encoder将文本生成一个embedding,
  2. Generation Model:然后和噪声一起生成一个Generation Model,得到一个中间产物
  3. Decoder: 使用Decoder都得到带有噪声图片

Stable Diffusion

Stable Diffusion

DALL-E series

DALL-E Series

Imagen

Imagen

Text encoder

text encoder

Decoder

Decoder can be trained without labelled data.
Decoder

什么是FID(Frechet Inception Distance)

FID

什么是CLIP(Contrastive Language-Image Pre-Training)

CLIP

Diffusion Model: Summary

Diffusion Model1

Diffusion Model in PyTorch

The easier way to use a Diffusion Model in PyTorch is to use the denoising-diffusion-pytorch package.

pip install denoising_diffusion_pytorch

一个示例代码:

import torch
from denoising_diffusion_pytorch import Unet, GaussianDiffusion
model = Unet(
    dim = 64,
    dim_mults = (1, 2, 4, 8)
)
model = Unet(
    dim = 64,
    dim_mults = (1, 2, 4, 8)
)
diffusion = GaussianDiffusion(
    model,
    image_size = 128,
    timesteps = 1000,   # number of steps
    loss_type = 'l1'    # L1 or L2
)
training_images = torch.randn(8, 3, 128, 128)
loss = diffusion(training_images)
loss.backward()
sampled_images = diffusion.sample(batch_size = 4)

结果

参考资料

  1. 从大一统视角理解扩散模型(Diffusion Models)
  2. What are Diffusion Models?
  3. Understanding Diffusion Models: A Unified Perspective
  4. Generative Modeling by Estimating Gradients of the Data Distribution
  5. Stable Diffusion、DALL-E、Imagen 背後共同的套路
  6. 带你深入理解扩散模型DDPM
  7. https://colab.research.google.com/github/huggingface/notebooks/blob/main/diffusers/stable_diffusion.ipynb#scrollTo=AAVZStIokTVv

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年6月21日
下一篇 2023年6月24日

相关推荐