# Diffusion Model原理剖析-李宏毅課程筆記(1/4) >講者:李宏毅 主題:Diffusion Model 原理剖析 (1/4)(optional) 影片連結:[【生成式AI】Diffusion Model 原理剖析 (1/4) (optional)](https://youtu.be/ifCDXFdeaaM?si=1qExlH2mYighQnTc) ## 前情提要:Diffusion Model 的基本概念 ![image](https://hackmd.io/_uploads/HkTTlpreZe.png) Diffusion 的直觀概念,可以用兩個過程來描述: 1. Forward process(前向擴散) 從一張乾淨的 image 開始,逐步加入 noise。 噪聲越加越多,最後變成一張完全看不出原圖的「純雜訊」影像。 2. Reverse process(反向生成) 一開始給模型一張「全部都是 noise」的影像。 每一步執行 denoise,把一點點噪聲移除、讓結構慢慢浮現。 多次重複後,最後得到一張完整、清晰的生成影像。 >**Diffusion Model 的核心概念:** >把「加噪」當作 forward process,把「去噪生成」當作 reverse process。 ## Diffusion Model 與 VAE 的對應關係 老師先將 Diffusion Model 和 VAE 進行比較,因為兩者其實非常像。 ![image](https://hackmd.io/_uploads/rJLXp2Bl-e.png) ### 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。 ![image](https://hackmd.io/_uploads/BkjhCOXlbx.png) ### 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$ ![image](https://hackmd.io/_uploads/SJ0VdaHeZx.png) 接下來是訓練演算法中最重要的一步: **利用 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$ 次」。 ![image](https://hackmd.io/_uploads/r1Cauarx-e.png) ![image](https://hackmd.io/_uploads/BkLx5prlZe.png) #### 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 的演算法 ![image](https://hackmd.io/_uploads/B1olCarlZe.png) 接下來老師說明 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$ 的隨機噪聲項。 #### 用圖像化的角度來理解 ![image](https://hackmd.io/_uploads/rygu36rgbe.png) - 手上有上一輪的結果 $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)