Denoising Diffusion Probabilistic Models

![Hotpot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/11d73810-4453-750e-5059-3cb4c064eb93.png)
*A classy diffusion model dancing in a ballroom*

---

こんにちは！AMBL株式会社　R＆D部のエイドリアンです。
こちらの記事はADVENT CALENDARの記事です。

今回は最近話題になっているDiffusion Modelについての論文を紹介したいと思います。

https://qiita.com/advent-calendar/2022/ambl-rd

# 論文情報

| タイトル | Denoising Diffusion Probabilistic Models  |
| :------- | ----------------------------------------- |
| 発表年   | 2020/12/16                                |
| URL      | https://arxiv.org/abs/2006.11239          |
| github   | https://github.com/hojonathanho/diffusion |

# TL;DR

**Diffusion Modelとは**

画像を純粋なノイズから生成するモデルです。
簡単にまとめると、下記の特徴が挙げられます。

* 従来の画像生成系モデル（VAE, GAN等）よりも高度な画像生成ができる。
* 画像にノイズを加えること（Forward process）と<br>ノイズから画像を生成する（Backward process）の2つ処理で学習を行う。
* マルコフ過程を用いることで計算を効率化させる。


下のネコちゃんを覚えていただければと思います。

**Diffusion Model = 画像を壊して作り直す**

![Cat](https://cvpr2022-tutorial-diffusion-models.github.io/img/thumbnail.png)


# モチベーション

では、なぜこういう手法が出てきたのか？実は画像生成系モデルが非常に研究されています。その他にも、

* VAE: Variational Autoencoders (2013)
* GAN: Generative Adversarial Networks (2014)
* DDPM: Denoising Probailistic Models (2020) ← 本論文
* +α: Diffusion Models Beat GAN on Image Synthesis (2021)

などがあります。それぞれの特徴を上げますと、下記の図になります。

![Generative Model](https://developer-blogs.nvidia.com/wp-content/uploads/2022/04/GANs_Diffusion_Autoencoders.png)
*Nvidia Developer Blog*


## 学習準備
では、Diffusion Modelはどうやって学習していくのか？

DDPMの学習には以下の3つのものが必須となります。

1. Noise Scheduler（画像を壊す器）
1. Neural Network (学習担当)
1. Timestamp Encoding（破壊発火器）

それぞれのパラメータを用意し、Forward（画像を壊す）
処理とBackward（画像を作り直す）処理を行って学習を進めていきます。

## Forward Process

$x_0=画像$ 

$q(x_{i:T}|x_o)=\prod_{t}^{T}q(x_t|x_{t-1})$

そして、 

$q(x_{t}|x_{t-1})=N(x_t; \sqrt{1-\beta_t}{x_{t-1},\beta_t{I}})$

$\beta_t$: $t$時点の分散量

つまり、$\beta$が1に近づけば近づくほど画像が純粋なノイズとなっていきます。
また、マルコフ過程により$t$が大きくなればなるほど、画像が純粋なノイズになっていきます。

-- *（変形後）* --

$q(x_{t}|x_{0})=N(x_t; \sqrt{\bar{\alpha}}{x_{0},(1-\bar\alpha_t)I})$


## Backward Process

$p_{\theta}(x_{0:T}):=p_{\theta}(x_{T})\prod_{t}^{T}p_\theta(x_{t-1}|x_{t})$

そして、 

$p_{\theta}(x_{t-1}|x_{t})=N(x_{t-1}; \mu_{\theta}(x_t,t), \sigma^2_tI)$ for $1 < t \leq T$

$\mu_{\theta}$: 平均値

つまり、ノイズ画像から'正常'画像へ戻す（作り直す）時は、<br>ノイズの分布（平均、分散）さえ分かればいい、ということになります。

--

$x_{t-1}\approx x_t-e$

 
## 手法

上記の話しをまとめると、下記のとうな手順になります。

![width:1100px](https://hojonathanho.github.io/diffusion/assets/img/algorithms.png)

## Neural Network

モデルの脳みその部分です。
今回のタスクはノイズ↔画像なので、入力（画像）と出力（画像）の形が一致<br>
しなければなりません。ですので、U-NETがピッタリと言えるでしょう。

![width:900px](https://nchlis.github.io/2019_10_30/architecture_unetV2.png)

*入力と出力の形は同じである*

## 目的関数

ここがマホウです。様々なマホウをかけたら、目的関数は下記の通り簡単になりました！。

![](https://www.assemblyai.com/blog/content/images/size/w1000/2022/05/image-18.png)

--

$\epsilon$: 真のノイズ

$\epsilon_\theta$: 予測ノイズ

つまり変なことをせずとも、ノイズを正しく予測させればよい、ということです。


## 実験結果

実験はよろしいみたいですね。

![image](https://user-images.githubusercontent.com/100895560/207873383-3a951a6a-a751-4ced-beba-1deef0f7f47c.png)

## DEMO

![sa](https://www.assemblyai.com/blog/content/images/2022/05/movie.gif)


# 参考

マホウ：https://lilianweng.github.io/posts/2021-07-11-diffusion-models/
簡易実装: https://colab.research.google.com/drive/1sjy9odlSSy0RBVgMTgP7s99NXsqglsUL?usp=sharing