# Diffusion Model原理剖析-李宏毅課程筆記(1/4)
>講者:李宏毅
主題:Diffusion Model 原理剖析 (1/4)(optional)
影片連結:[【生成式AI】Diffusion Model 原理剖析 (1/4) (optional)](https://youtu.be/ifCDXFdeaaM?si=1qExlH2mYighQnTc)
## 前情提要:Diffusion Model 的基本概念

Diffusion 的直觀概念,可以用兩個過程來描述:
1. Forward process(前向擴散)
從一張乾淨的 image 開始,逐步加入 noise。
噪聲越加越多,最後變成一張完全看不出原圖的「純雜訊」影像。
2. Reverse process(反向生成)
一開始給模型一張「全部都是 noise」的影像。
每一步執行 denoise,把一點點噪聲移除、讓結構慢慢浮現。
多次重複後,最後得到一張完整、清晰的生成影像。
>**Diffusion Model 的核心概念:**
>把「加噪」當作 forward process,把「去噪生成」當作 reverse process。
## Diffusion Model 與 VAE 的對應關係
老師先將 Diffusion Model 和 VAE 進行比較,因為兩者其實非常像。

### VAE 的結構回顧
- **Encoder**:把 image 映射到 latent representation
$$x \xrightarrow{\text{encoder}} z$$
- **Decoder**:再從 latent 還原回 image
$$z \xrightarrow{\text{decoder}} \hat{x}$$
### 把 Diffusion 看成一種「奇怪的 VAE」
在 Diffusion Model 裡:
- **加噪的過程** 可以視為一種 encoder:
- 把乾淨圖片 $(x_0)$ 加上N次 Gaussian noise,直到最後變成純雜訊 $(x_T)$。
- 這個「加噪 encoder」**不是 neural network**,而是**人為設計的固定 process**。
- 最後的「只有雜訊的 image $(x_T)$」就扮演類似 VAE 裡 latent representation 的角色。
- **Denoise 的過程** 則扮演 decoder 的角色:
- 從雜訊圖開始,逐步去噪,最後還原出原始影像。
> 對應關係:
> VAE:
> - encoder:\(x \rightarrow z\)(學出來的 NN)
> - decoder:\(z \rightarrow x\)(學出來的 NN)
>
>Diffusion:
> - encoder:\(x_0 \rightarrow x_T\)(加噪,**人設計、不學習**)
> - decoder:\(x_T \rightarrow x_0\)(去噪,**用 NN 學**)
## DDPM 演算法在做什麼
DDPM(Denoising Diffusion Probabilistic Model)的訓練演算法,也就是原始 DDPM 論文中的 training procedure。

### Training
演算法的第一行是 `repeat`:
- 意思是重複執行後面第 2~5 行,直到收斂`converged`。
### 第一步:從資料庫抽乾淨圖 $x_0$
從資料庫中 **sample 一張乾淨的圖片**:
$$
x_0 \sim q(x_0)
$$
在 Diffusion 相關文獻中的慣例:
$x_0$代表**乾淨的圖(真實的 data)**。
### 第二步:從 $\{1, \dots, T\}$ 抽一個時間步 $t$
從 $1$ 到 $T$ 之間均勻隨機抽一個整數:
$$
t \sim \text{Uniform}(\{1, \dots, T\})
$$
- $T$ 通常設為一個較大的數,例如 $T = 1000$。
- 例如這次可能抽到 $t = 968$。
### 第三步:Sample 一個 Gaussian noise $\epsilon$
從標準常態分布 sample 一個 noise:
$$
\epsilon \sim \mathcal{N}(0, I)
$$
- $\epsilon$ 的維度大小跟 image $x_0$ 一樣。
- 內容全部是雜訊,看不出任何有意義的結構。
### 第四步:直接從 $x_0$ 生成 noisy image $x_t$

接下來是訓練演算法中最重要的一步:
**利用 closed-form 公式直接生成某個時間步 $t$ 的 noisy image。**
#### 4.1 事先定義好的 noise schedule:$\bar{\alpha}_1, \dots, \bar{\alpha}_T$
在訓練前先定義一個序列:
$$
\bar{\alpha}_1, \bar{\alpha}_2, \dots, \bar{\alpha}_T
$$
- 這些 $\bar{\alpha}_t$:
- 全部是**人為設計的常數**。
- 通常設計為:$t$ 越大,$\bar{\alpha}_t$ 越小(由大到小)
直覺:
- $t$ 越大 $\Rightarrow$ $\bar{\alpha}_t$ 越小
$\Rightarrow$ 類似「原始訊號比例減少、雜訊比例增加」。
#### 4.2 用單一步驟混出 noisy image
在 DDPM 訓練中,對於任意時間步 $t$,直接用下式生成 $x_t$:
$$
x_t = \sqrt{\bar{\alpha}_t}\, x_0 + \sqrt{1 - \bar{\alpha}_t}\, \epsilon
$$
- $\sqrt{\bar{\alpha}_t}$:乾淨圖 $x_0$ 的權重。
- $\sqrt{1 - \bar{\alpha}_t}$:noise $\epsilon$ 的權重。
- $t$ 越大:
- $\bar{\alpha}_t$ 越小 $\Rightarrow$ 原圖所占比例越少。
- $1 - \bar{\alpha}_t$ 越大 $\Rightarrow$ 雜訊所占比例越多。
> **重要差異:**
> - 「直覺上的 diffusion」:每一步加一點點 noise,連續加很多步。
> - **DDPM 的實際訓練作法**:
> 對每個 $t$,直接用上式 **一次** 生出對應噪音程度的 $x_t$,
> 並沒有真的模擬「加噪 $t$ 次」。


#### 5. Noise Predictor 網路 $\varepsilon_\theta$ 的訓練目標
#### 5.1 定義 Noise Predictor
定義一個網路:
$$
\varepsilon_\theta(x_t, t)
$$
- **輸入:**
- noisy image $x_t$
- 時間步 $t$(通常會做 time embedding)
- **輸出:**
- 模型對「當初混入的 noise」的預測,記作:
$$
\hat{\epsilon} = \varepsilon_\theta(x_t, t)
$$
#### 5.2 Ground truth 是什麼?
因為在第三步,我們已經從 $\mathcal{N}(0, I)$ 取樣過真正的 noise $\epsilon$,
所以訓練時的正確答案(ground truth)就是:
$$
\epsilon_{\text{GT}} = \epsilon
$$
也就是說,noise predictor 的任務是:
> 給定 $(x_t, t)$,去預測當初「混入」$x_t$ 的那個 $\epsilon$。
#### 5.3 Loss function(概念形式)
雖然老師這段還沒有寫完整的 loss 推導,但概念上是:
$$
\mathcal{L}(\theta) =
\mathbb{E}_{x_0, t, \epsilon}\Big[
\big\|\epsilon - \varepsilon_\theta(x_t, t)\big\|^2
\Big]
$$
也就是:
1. 從資料庫 sample 一張 $x_0$。
2. 從 $\{1, \dots, T\}$ sample 一個 $t$。
3. 從 $\mathcal{N}(0, I)$ sample 一個 $\epsilon$。
4. 用
$$
x_t = \sqrt{\bar{\alpha}_t} x_0 + \sqrt{1-\bar{\alpha}_t}\epsilon
$$
算出 noisy image。
5. 把 $(x_t, t)$ 丟進網路,得到 $\varepsilon_\theta(x_t, t)$。
6. 用 **MSE** 讓預測的 noise 接近真實的 $\epsilon$。
#### 6. 「概念上的 Diffusion」vs「DDPM 真的在做的事」
這裡是李宏毅老師特別強調的重點:
**演算法實際在做的事情,跟我們直覺想像的流程不太一樣。**
#### 6.1 我們「想像中」的運作方式
直覺上會這樣想:
- Forward(加噪):
$$
x_0 \rightarrow x_1 \rightarrow x_2 \rightarrow \dots \rightarrow x_T
$$
每一步加一點點 noise,圖片越來越糊。
- 訓練 noise predictor 時:
- 每一步學的是:
$$
x_t \xrightarrow{\text{denoise}} x_{t-1}
$$
- 也就是「把這一步額外加進來的那一點點噪訊去掉」。
#### 6.2 DDPM 訓練「實際上」在做的事
- 訓練時 **並沒有真的一步一步加噪**:
- 不會平常先算出 $x_1, x_2, \dots, x_{t-1}$ 再來算 $x_t$。
- 而是直接用 closed-form:
$$
x_t = \sqrt{\bar{\alpha}_t} x_0 + \sqrt{1-\bar{\alpha}_t} \epsilon
$$
一次得到對應時間步 $t$ 的 noisy image。
- Noise predictor 的目標是:
- **直接預測整個 $x_t$ 裡混入的 noise $\epsilon$**,
而不是僅僅預測「$x_{t-1} \rightarrow x_t$ 這一小步」。
> 老師的總結:
> 想像中:noise 是一點一點加、denoise 也是一點一點抹。
> 實際訓練:針對每個 $t$,一次把「對應程度的 noise」加進去,
> 再一次預測整個 $\epsilon$。
---
### 生成(Sampling)過程:Reverse Process 的演算法

接下來老師說明 DDPM 「生圖」時的 reverse process 演算法,
這裡會再出現一個讓人困惑的地方:**為什麼 denoise 的同時還要再加 noise?**
#### 第一步:從純雜訊開始
首先 sample 一張「全部都是 noise」的影像:
$$
x_T \sim \mathcal{N}(0, I)
$$
在文獻中,一般把 $x_T$ 當成:
- 一張完全由雜訊構成的起始圖。
#### 第二步:Reverse Process 的迭代公式
從 $t = T$ 一直到 $t = 1$,重複以下步驟:
1. 每一個 $t$,先再 sample 一個 noise:
$$z \sim \mathcal{N}(0, I)$$
2. 將 $x_t$ 轉成 $x_{t-1}$ 的公式大致如下(概念結構):
$$x_{t-1}=\frac{1}{\sqrt{\alpha_t}}\left(x_t- \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}\varepsilon_\theta(x_t, t)\right)+ \sigma_t z$$
- $\varepsilon_\theta(x_t, t)$:noise predictor 預測的 noise。
- $\alpha_t$、$\bar{\alpha}_t$、$\sigma_t$:事先設計好的參數或由 schedule 推導而得。
- 注意:最後還加上一個 $\sigma_t z$ 的隨機噪聲項。
#### 用圖像化的角度來理解

- 手上有上一輪的結果 $x_t$。
- 準備好兩組數列:
- $\bar{\alpha}_1, \dots, \bar{\alpha}_T$
- $\alpha_1, \dots, \alpha_T$
- 把 $x_t$ 和 $t$ 丟進 noise predictor,得到:
$$
\hat{\epsilon} = \varepsilon_\theta(x_t, t)
$$
- 然後:
- 把 $\hat{\epsilon}$ 乘上一個係數 $\dfrac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}}$。
- 從 $x_t$ 中「減掉」這個噪聲項。
- 再乘上 $\dfrac{1}{\sqrt{\alpha_t}}$,
得到一張「看起來更乾淨」的影像。
- 按理說,這時候就應該得到 $x_{t-1}$,
但演算法還會再加上:$+\ \sigma_t z$
又丟進一點新的 noise。
#### 為什麼還要再加一個 noise?(本節還沒說出原因)
這裡是第二個暗藏玄機的地方:
- 直覺上,我們以為:
去噪就是把噪音預測出來,然後從 $x_t$ 減掉,就結束了。
- 但在 DDPM 裡:
- 即使在 reverse process 中,
每一步仍然會再 sample 一個新的 noise $z$,再加回影像中。
- 這看起來像是「一邊去噪、一邊再加噪」,非常違反直覺。
李宏毅老師也形容這部分是「令人匪夷所思的操作」,
這也是他說 DDPM 演算法「暗藏玄機」的原因之一。
---
下一節:[Diffusion Model原理剖析-李宏毅課程筆記(2/4)](https://hackmd.io/@1I0zSdF_QSi-tPfJXnBEXA/Hy5EXRSlbl)