搜尋課程與筆記

搜尋筆記

輸入主題、關鍵字或單元編號,例如 Flow Matching、U4。

    按 Esc 關閉 · ⌘ / Ctrl K 開啟搜尋

    U1.2 42 分鐘閱讀 2026年10月

    U1.2 Denoising:倒著走一步,要怎麼學?

    本篇重用7 篇

    倒著走一步,如何從 q(xt−1∣xt)q(x_{t-1}\mid x_t) 抽樣?

    上一篇我們已經把前進的路 forward process 給設計好了:知道怎麼從 xt−1x_{t-1} 到 xtx_t,而且任意時刻的 xtx_t 都能用一行公式從 x0x_0 獲得。現在我們想做的是反過來——手上已有一個 xtx_t,要怎麼退到 xt−1x_{t-1},也就是說,要怎麼從 q(xt−1∣xt)q(x_{t-1}\mid x_t) 抽樣。

    複習為什麼是「從 q(xt−1∣xt)q(x_{t-1}\mid x_t) 抽樣」,而不是算出一個答案?

    先複習 q(xt−1∣xt)q(x_{t-1}\mid x_t) 在描述什麼:給定現在的 xtx_t,退到前一步、落在差不多 xt−1x_{t-1} 這個位置的機率密度。

    用上一篇那條從台大到屏東的路線來說:給定現在人在屏東,前一站是高雄(走西部)還是台東(繞東部)?機率會告訴我們每一種可能性有多大,我們就照著它抽一個——抽到高雄或台東都是合理的答案。

    已知現在人在屏東,前一站仍可能是高雄或台東;對應到 diffusion,固定 x_t 後,可能的 x_{t-1} 形成一個 conditional distribution。

    左圖固定現在的位置,仍留下不同的可能來路;右圖的紅點是已知的 xtx_t,藍色點雲則表示 q(xt−1∣xt)q(x_{t-1}\mid x_t) 描述的可能前一步。一次 reverse step 是依這個 conditional distribution 抽出一個 xt−1x_{t-1}。

    Week 3 投影片 27 · 點圖查看原圖

    為什麼要寫成「分布」而不是「一個答案」?因為加噪那一步真的把資訊丟掉了:很多不同的 xt−1x_{t-1} 都可能變成手上這個 xtx_t,而只有分布記得住是哪些、各自多可能。至於拿到這個分布之後要怎麼用——每一步真的抽一個,還是每一步都走一個確定的方向——那是另一個問題,U1.4 會看到兩種做法都成立。

    首先我們知道,xtx_t 是由 xt−1x_{t-1} 加了一撮隨機的 Gaussian noise 得到的。所以 xtx_t 一旦固定,往回看 xt−1x_{t-1},會因為那撮 noise 的隨機性而有一整個範圍的可能。我們要的就是那個範圍上的機率密度。

    課堂提問Q1

    最直覺的想法是把加噪那一步直接反解。既然

    xt=αt xt−1+βt ϵt,x_t=\sqrt{\alpha_t}\,x_{t-1}+\sqrt{\beta_t}\,\epsilon_t ,

    那我就抽一個 ϵt∼N(0,I)\epsilon_t\sim\mathcal N(0,I),代進去解出

    xt−1=(xt−βt ϵt)/αtx_{t-1}=\big(x_t-\sqrt{\beta_t}\,\epsilon_t\big)\big/\sqrt{\alpha_t}

    不就好了嗎?反正 noise 本來就是隨機抽的。

    這樣為什麼不行?

    先想一想,再展開看整理後的答案

    問題出在「ϵt\epsilon_t 本來就是隨機抽的」這句話——它在加噪的時候成立,在取樣的時候不成立。

    加噪時,我們先有 xt−1x_{t-1},再抽一個「與它無關」的 ϵt\epsilon_t——這兩個變數確實互相獨立。但在 reverse process 要做 denoise 時,我們手上先有 xtx_t,想要利用 ϵt\epsilon_t 決定 xt−1x_{t-1};而 xtx_t 是用當初那個特定的 ϵt\epsilon_t 算出來的(現在看不到),因此 ϵt\epsilon_t 和 xtx_t 不是獨立的:看到 xtx_t,等於看到「它因為 ϵt\epsilon_t 而落在哪裡」——這件事本身就帶著關於 ϵt\epsilon_t 的資訊。

    我們可以透過計算兩者之間的共變數(covariance)來證明不獨立這件事。因為 ϵt\epsilon_t 與 xt−1x_{t-1} 是獨立的,

    Cov⁡(ϵt, xt)=Cov⁡(ϵt, αt xt−1+βt ϵt)=βt I  ≠  0.\operatorname{Cov}(\epsilon_t,\,x_t) =\operatorname{Cov}\big(\epsilon_t,\ \sqrt{\alpha_t}\,x_{t-1}+\sqrt{\beta_t}\,\epsilon_t\big) =\sqrt{\beta_t}\,I\;\ne\;0 .

    covariance 不是零,就代表有相關;有相關,就不能另外抽一個與 xtx_t 獨立的 noise 去替代 ϵt\epsilon_t。

    那「不獨立」到底改變了什麼?ϵt\epsilon_t 的 marginal distribution 仍然是 N(0,I)\mathcal N(0,I),但給定 xtx_t 之後,ϵt\epsilon_t 的分布就變了。所以從 N(0,I)\mathcal N(0,I) 抽一個與 xtx_t 獨立的 ϵt\epsilon_t 代進去,就變成錯的。

    回到上一篇的洗牌。你把一副排好的牌洗了一次,然後只看到洗完的樣子——沒看到洗之前。洗牌當然是隨機的,但你看到的那個結果,本身就透露了那一次是怎麼洗的:如果洗完之後有幾張還連在一起,那一次顯然沒把那一段拆開。

    所以你不能說「反正洗牌是隨機的」,就自己隨便洗一次、再宣稱這樣就把它倒回去了——那樣只會回到一個錯的順序。ϵt\epsilon_t 就是那一次洗牌:一旦看到 xtx_t,它就不再是一個可以隨便重抽的東西。

    所以反解這條路是行不通的。那如果我們老老實實去算 q(xt−1∣xt)q(x_{t-1}\mid x_t) 呢?

    因為我們是知道 q(xt∣xt−1)q(x_t\mid x_{t-1}) 的,這時候就會想要用 Bayes 定理來算 q(xt−1∣xt)q(x_{t-1}\mid x_t)(M1.3):

    知道前進規則,能反推上一站嗎?

    q(xt−1∣xt)=q(xt∣xt−1) pt−1(xt−1)pt(xt). \begin{gathered} \reveal{1}{q(x_{t-1}\mid x_t)=}\\[.2em] \reveal{4}{\frac{ \reveal{2}{q(x_t\mid x_{t-1})}\reveal{3}{\,p_{t-1}(x_{t-1})} }{p_t(x_t)}.} \end{gathered}
    1. 已經看到現在的 xtx_t,我們想知道前一步 xt−1x_{t-1} 有哪些可能。
    2. 對每個候選的 xt−1x_{t-1},先看它產生這個 xtx_t 的 density。
    3. 再乘上 pt−1(xt−1)p_{t-1}(x_{t-1}),把前一步各個位置原本的可能性考慮進來。
    4. 最後除以 pt(xt)p_t(x_t),才得到給定現在之後的反向 density。

    分子的 q(xt∣xt−1)q(x_t\mid x_{t-1}) 我們確實會算——那是上一篇自己設計的那一步(U1.1)。但右邊還有 pt−1(xt−1)p_{t-1}(x_{t-1}) 和 pt(xt)p_t(x_t):它們是資料經過加噪之後的 marginal distribution,也就是「所有真實圖片加噪 tt 步之後,長成 xtx_t 的可能性有多大」,我們記成 ptp_t。要知道它,就得把每一張真實圖片的貢獻都加總起來——也就是得先知道整個 pdatap_{\text{data}}(但很明顯我們不知道)。這種「式子寫得出來、但實際上算不出來」的東西,以下都叫 不可算(intractable)。

    Bayes 將 reverse conditional 拆成 forward conditional 與兩個 noisy marginals;forward Gaussian 會算,但兩個 marginals 都包含未知 p_data 的積分。

    藍色框是我們設計的 q(xt∣xt−1)q(x_t\mid x_{t-1}),黃色兩項才是卡住的地方。以 pt(xt)=∫q(xt∣x0)pdata(x0) dx0p_t(x_t)=\int q(x_t\mid x_0)p_{\text{data}}(x_0)\,\mathrm dx_0 為例,必須把所有可能原圖的貢獻加起來;知道每一個 conditional Gaussian,仍不等於已經知道它們混合後的 marginal density。

    Week 3 投影片 32 · 點圖查看原圖

    如果算不出來,那可不可以用「學」的?那要怎麼學?

    我們先換一個角度想。其實我們本來就沒有打算把所有東西都直接算出來——如果每一個 quantity 都可以直接算,那我們根本就不需要 learning。

    所以現在既然真正的 q(xt−1∣xt)q(x_{t-1}\mid x_t) 不好算,我們可不可以乾脆學一個東西來逼近它?例如,用一個 neural network 來參數化一個 conditional distribution pθ(xt−1∣xt)p_\theta(x_{t-1}\mid x_t),接下來的目標就很自然了:想辦法調整 θ\theta,讓 pθ(xt−1∣xt)p_\theta(x_{t-1}\mid x_t) 盡可能接近真正的 q(xt−1∣xt)q(x_{t-1}\mid x_t)。

    如果這件事做得到,那我們是不是就不需要真的把 q(xt−1∣xt)q(x_{t-1}\mid x_t) 算出來了?

    問題就從:

    「這個 distribution 要怎麼算?」

    變成:

    「我要怎麼設計一個 learning problem,讓 neural network 把它學出來?」

    那就來設計這個 learning problem。第一件事是把「接近」說清楚——也就是寫下一個 loss function。兩個分布之間最常用的那個 loss function 是 Kullback–Leibler divergence(M5.1),以下都簡稱 KL;而 xtx_t 本身也是隨機的,所以要對所有可能的 xtx_t 取平均:

    J(θ)=Ept(xt)[DKL(q(xt−1∣xt) ∥ pθ(xt−1∣xt))].\mathcal J(\theta)=\mathbb E_{p_t(x_t)}\Big[D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big)\Big].

    這一行就是最直覺、我們真正想要最小化的東西。好消息是 learning objective 有了,壞消息是裡面那個 q(xt−1∣xt)q(x_{t-1}\mid x_t) 還是不可算,所以這個 loss 我們似乎還是算不出來,也不知道怎麼求 gradient。

    課堂提問Q2

    我們常常在想一個方法的時候、遇到問題就會忘記靜下心來看看我們有什麼?能做什麼?這時不如回頭看一下我們一開始到底有什麼資訊是可以用的——forward process 給了我們什麼?

    我們在 forward process 建立的是一筆要拿來訓練的資料,我們做的是:抽一張資料集裡的真實圖片 x0x_0、抽一個時間 tt、抽一個 ϵ\epsilon,然後一行算出 xtx_t。所以我們其實不是只有 xtx_t,還有創造它的 (x0,ϵ,t)(x_0,\epsilon,t)。

    那這其中有誰可以幫助我們算出 q(xt−1∣xt)q(x_{t-1}\mid x_t)?或是可以有一樣效果的 loss function 呢?

    先想一想,再展開看整理後的答案

    x0x_0。

    寫 q(xt−1∣xt)q(x_{t-1}\mid x_t) 的時候,我們假裝手上只有 xtx_t,但我們其實還知道它是來自哪一張圖 x0x_0。而那正是卡住的原因:pt−1(xt−1)p_{t-1}(x_{t-1}) 和 pt(xt)p_t(x_t) 之所以難算,就是因為它們把所有可能的 x0x_0 都考慮進去了。

    既然算不動的原因是「要考慮所有的 x0x_0」,那就先別考慮全部:把 x0x_0 也放進條件裡看看。

    訓練的時候,我們其實多知道一件事

    先不要急著看公式。想一下 xtx_t 是哪裡來的。

    訓練的時候,我們先從 dataset 拿一張真正的資料 x0x_0,再自己一步一步加 noise 產生 xtx_t。所以每一個訓練時看到的 xtx_t,我們都知道它原本是哪一張 x0x_0 變出來的。這件事在我們真的要生成新資料的時候沒有——那時候只有當下的 xtx_t;但在 training 的時候,x0x_0 一直都藏在我們手上。

    那問題來了:如果 q(xt−1∣xt)q(x_{t-1}\mid x_t) 不可算,多告訴我們原本的 x0x_0,事情會不會變簡單?也就是不要先問

    q(xt−1∣xt),而是問q(xt−1∣xt,x0).q(x_{t-1}\mid x_t),\qquad\text{而是問}\qquad q(x_{t-1}\mid x_t,x_0).

    答案是:會,而且它可以直接算出來。那我們可不可以拿這個「算得出來的東西」來教模型?於是把 training objective 改寫成

    J~(θ)=Epdata(x0) Eq(xt∣x0)[DKL(q(xt−1∣xt,x0) ∥ pθ(xt−1∣xt))].\widetilde{\mathcal J}(\theta)=\mathbb E_{p_{\text{data}}(x_0)}\ \mathbb E_{q(x_t\mid x_0)} \Big[D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t,x_0)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big)\Big].

    這裡有一個看起來很奇怪的地方:左邊那個拿來當 target 的 q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0) 看得到 x0x_0,但右邊我們真正要學的 pθ(xt−1∣xt)p_\theta(x_{t-1}\mid x_t) 看不到。

    為什麼?因為 generation 的時候我們根本沒有 x0x_0,模型最後一定只能靠 xtx_t 往回走。所以 training 時我們可以用 x0x_0 造一個「比較容易算的 target」,但模型最後仍然只能看到 xtx_t。

    訓練資料的建造程序:抽 x_0、t、epsilon,算出 x_t;target 可以使用已知的 x_0,但模型的輸入只有 x_t 和 t。

    Training 時,我們掌握 (x0,t,ϵ,xt)(x_0,t,\epsilon,x_t),所以能用 x0x_0 算出 target q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0)。但模型的輸入始終只有 (xt,t)(x_t,t),學的是 pθ(xt−1∣xt)p_\theta(x_{t-1}\mid x_t)。多知道的 x0x_0 用來造 target,沒有成為生成時拿不到的 input。

    Week 3 投影片 37 · 點圖查看原圖

    這看起來有點像作弊,甚至更嚴重:兩邊條件的東西根本不一樣。我們真的還是在學原本那個 q(xt−1∣xt)q(x_{t-1}\mid x_t) 嗎?

    是。而且這裡不是 approximation。

    在看證明之前,先想一下為什麼它會成立。固定一個 xtx_t,在整個訓練過程中,它有可能會被很多張不同的 x0x_0 給造出來。而每一筆訓練資料都拿出一個不一樣的 x0x_0 要模型去對齊,但模型只看得到 xtx_t,分不出手上這一筆是哪一張 x0x_0 來的,所以它只能給一個答案去應付全部——就是把所有 x0x_0 各自給出的那個分布,按它們出現的「頻率」平均起來,而那個平均就會是 q(xt−1∣xt)q(x_{t-1}\mid x_t)。

    也就是這個意思:

    Ep(x0∣xt)[q(xt−1∣xt,x0)]=q(xt−1∣xt).\mathbb E_{p(x_0\mid x_t)}\big[q(x_{t-1}\mid x_t,x_0)\big]=q(x_{t-1}\mid x_t).

    所以兩個 objective 分別是:直接對齊那個算不出來的 q(xt−1∣xt)q(x_{t-1}\mid x_t),和透過對齊一堆算得出來的 q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0)、再讓模型自己去取平均 Ep(x0∣xt)[ ⋅ ]\mathbb E_{p(x_0\mid x_t)}[\,\cdot\,],也是去對齊 q(xt−1∣xt)q(x_{t-1}\mid x_t)。

    這裡用的雖然是 KL,但和 L2 那種把差距平方起來的距離有類似的性質;以 L2 舉一個 toy example,寫 aˉ=a1+a2+a33\bar a=\frac{a_1+a_2+a_3}{3},minimizing 13[(x−a1)2+(x−a2)2+(x−a3)2]\frac13\big[(x-a_1)^2+(x-a_2)^2+(x-a_3)^2\big] 和 minimizing (x−aˉ)2(x-\bar a)^2 會得到一樣的最佳解 xx,因為兩者之差是一個常數——配方出來就看得到:

    13[(x−a1)2+(x−a2)2+(x−a3)2]=(x−aˉ)2+(a1−aˉ)2+(a2−aˉ)2+(a3−aˉ)23⏟不含 x.\frac13\big[(x-a_1)^2+(x-a_2)^2+(x-a_3)^2\big] =(x-\bar a)^2 +\underbrace{\frac{(a_1-\bar a)^2+(a_2-\bar a)^2+(a_3-\bar a)^2}{3}}_{\text{不含 }x} .

    根據這樣的性質,我們預測會有:

    J~(θ)=J(θ)+C⟹arg⁡min⁡θ J~(θ)=arg⁡min⁡θ J(θ),\widetilde{\mathcal J}(\theta)=\mathcal J(\theta)+C \quad\Longrightarrow\quad \arg\min_\theta\ \widetilde{\mathcal J}(\theta)=\arg\min_\theta\ \mathcal J(\theta),

    其中 CC 完全不依賴 θ\theta;而最佳的那個 pθp_\theta——寫成 p⋆(xt−1∣xt)p^\star(x_{t-1}\mid x_t)——正是上面那個平均 Ep(x0∣xt)[q(xt−1∣xt,x0)]\mathbb E_{p(x_0\mid x_t)}\big[q(x_{t-1}\mid x_t,x_0)\big],也就是 q(xt−1∣xt)q(x_{t-1}\mid x_t)。

    所以我們只是把一個算不出來的 learning objective,換成一個算得出來、但最佳解完全相同的 objective。模型從來沒有直接拿那個算不出來的 q(xt−1∣xt)q(x_{t-1}\mid x_t) 作為目標,卻可以透過很多個「知道 x0x_0 的 training examples」把它學起來。

    動手自己實際推一次:為什麼 J~(θ)=J(θ)+C\widetilde{\mathcal J}(\theta)=\mathcal J(\theta)+C 是對的?

    我們想證明的是:雖然 training 時改用 q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0) 當 target,但最後學到的東西,和原本拿 q(xt−1∣xt)q(x_{t-1}\mid x_t) 當 target 是一樣的。

    先固定一個 xtx_t,看這個 KL:

    DKL(q(xt−1∣xt,x0) ∥ pθ(xt−1∣xt)).D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t,x_0)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big).

    把 KL 的定義展開:

    DKL(q(xt−1∣xt,x0) ∥ pθ(xt−1∣xt))=∫q(xt−1∣xt,x0)log⁡q(xt−1∣xt,x0) dxt−1−∫q(xt−1∣xt,x0)log⁡pθ(xt−1∣xt) dxt−1.\begin{aligned} &D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t,x_0)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big)\\[4pt] &=\int q(x_{t-1}\mid x_t,x_0)\log q(x_{t-1}\mid x_t,x_0)\,\mathrm dx_{t-1}\\[2pt] &\quad-\int q(x_{t-1}\mid x_t,x_0)\log p_\theta(x_{t-1}\mid x_t)\,\mathrm dx_{t-1}. \end{aligned}

    先看第一項:

    ∫q(xt−1∣xt,x0)log⁡q(xt−1∣xt,x0) dxt−1.\int q(x_{t-1}\mid x_t,x_0)\log q(x_{t-1}\mid x_t,x_0)\,\mathrm dx_{t-1}.

    這裡完全沒有 θ\theta。所以不管之後再對 x0x_0、xtx_t 取多少次期望,對我們「調整 θ\theta」這件事來說,它都只是一個常數。

    因此真正會影響 learning 的,是第二項:

    −∫q(xt−1∣xt,x0)log⁡pθ(xt−1∣xt) dxt−1.-\int q(x_{t-1}\mid x_t,x_0)\log p_\theta(x_{t-1}\mid x_t)\,\mathrm dx_{t-1}.

    現在對「有可能造出這個 xtx_t」的 x0x_0 取平均:

    − Ep(x0∣xt)[∫q(xt−1∣xt,x0)log⁡pθ(xt−1∣xt) dxt−1].-\,\mathbb E_{p(x_0\mid x_t)}\Big[\int q(x_{t-1}\mid x_t,x_0)\log p_\theta(x_{t-1}\mid x_t)\,\mathrm dx_{t-1}\Big].

    注意 log⁡pθ(xt−1∣xt)\log p_\theta(x_{t-1}\mid x_t) 只看 xtx_t 和 xt−1x_{t-1},不依賴 x0x_0。所以我們可以先把所有可能的 x0x_0 平均掉:

    −∫[∫q(xt−1∣xt,x0) p(x0∣xt) dx0]log⁡pθ(xt−1∣xt) dxt−1.-\int\Big[\int q(x_{t-1}\mid x_t,x_0)\,p(x_0\mid x_t)\,\mathrm dx_0\Big]\log p_\theta(x_{t-1}\mid x_t)\,\mathrm dx_{t-1}.

    那中括號裡是什麼?

    ∫q(xt−1∣xt,x0) p(x0∣xt) dx0.\int q(x_{t-1}\mid x_t,x_0)\,p(x_0\mid x_t)\,\mathrm dx_0 .

    它的意思就是:已知現在的 xtx_t,把所有可能的原圖 x0x_0 都按照 p(x0∣xt)p(x_0\mid x_t) 的機率加權平均。根據 marginalization,這正好就是

    q(xt−1∣xt).q(x_{t-1}\mid x_t).

    因此第二項變成

    −∫q(xt−1∣xt)log⁡pθ(xt−1∣xt) dxt−1,-\int q(x_{t-1}\mid x_t)\log p_\theta(x_{t-1}\mid x_t)\,\mathrm dx_{t-1},

    也就是 q(xt−1∣xt)q(x_{t-1}\mid x_t) 和 pθp_\theta 的 cross entropy。

    而原本的 DKL(q(xt−1∣xt) ∥ pθ(xt−1∣xt))D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big) 展開之後,也只有這個 cross entropy 和 θ\theta 有關;剩下那個 q(xt−1∣xt)q(x_{t-1}\mid x_t) 的 entropy 一樣不含 θ\theta。

    因此兩個 objective 最後只差一個與 θ\theta 無關的常數,也就有完全相同的最佳解:

    J~(θ)=J(θ)+C⟹arg⁡min⁡θ J~(θ)=arg⁡min⁡θ J(θ).\widetilde{\mathcal J}(\theta)=\mathcal J(\theta)+C \quad\Longrightarrow\quad \arg\min_\theta\ \widetilde{\mathcal J}(\theta)=\arg\min_\theta\ \mathcal J(\theta).

    而當模型夠有表達能力的時候,最佳的情況就是

    pθ(xt−1∣xt)=q(xt−1∣xt).p_\theta(x_{t-1}\mid x_t)=q(x_{t-1}\mid x_t).

    所以 training 時雖然用了額外知道的 x0x_0,模型最後學到的仍然是我們真正想要的那個 reverse distribution。

    這個「取平均」的、將不可算變成可以算的技巧,這門課中會反覆看到,以下都叫它 conditional trick。Lai、Song、Kim、Mitsufuji 與 Ermon [2] 系統性地整理了它在 diffusion models 裡的不同版本。它每一次出現的形狀都一樣:不可算的目標是一個邊際量,而把某個東西放進條件裡之後就算得出來,剩下的平均交給 loss 自己做。 這一篇用的是 KL 版本;U1.3 會用到 MSE 版本,而 U2 的 conditional flow matching 是速度版本。

    把 q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0) 算出來

    知道了 learning objective 是可行的之後,我們回過頭來算 q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0)。一樣先用 Bayes:

    q(xt−1∣xt,x0)=q(xt∣xt−1,x0) q(xt−1∣x0)q(xt∣x0)=q(xt∣xt−1) q(xt−1∣x0)q(xt∣x0).q(x_{t-1}\mid x_t,x_0) =\frac{q(x_t\mid x_{t-1},x_0)\,q(x_{t-1}\mid x_0)}{q(x_t\mid x_0)} =\frac{q(x_t\mid x_{t-1})\,q(x_{t-1}\mid x_0)}{q(x_t\mid x_0)} .

    第二個等號用的是 Markov property:q(xt∣xt−1,x0)=q(xt∣xt−1)q(x_t\mid x_{t-1},x_0)=q(x_t\mid x_{t-1})——往前走一步只讀現在這個狀態,x0x_0 知不知道都一樣。至於 q(xt−1∣x0)q(x_{t-1}\mid x_0) 與 q(xt∣x0)q(x_t\mid x_0) 這兩項,可以注意到它們都多了一個 x0x_0 的條件,而這三項全部都是 forward process 裡設計出來的 Gaussian。

    q(xt∣xt−1)q(x_t\mid x_{t-1}) 是 forward process 每往前一步的設計,q(xt−1∣x0)q(x_{t-1}\mid x_0) 與 q(xt∣x0)q(x_t\mid x_0) 則是我們在 U1.1 最後得到的 closed form(把 tt 換成 t−1t-1 就有中間那一條):

    q(xt∣xt−1)=N(αt xt−1, βtI),每一步的設計q(xt−1∣x0)=N(αˉt−1 x0, (1−αˉt−1)I),closed formq(xt∣x0)=N(αˉt x0, (1−αˉt)I).closed form\begin{aligned} q(x_t\mid x_{t-1})&=\mathcal N\big(\sqrt{\alpha_t}\,x_{t-1},\ \beta_t I\big), &&\text{每一步的設計}\\[2pt] q(x_{t-1}\mid x_0)&=\mathcal N\big(\sqrt{\bar\alpha_{t-1}}\,x_0,\ (1-\bar\alpha_{t-1})I\big), &&\text{closed form}\\[2pt] q(x_t\mid x_0)&=\mathcal N\big(\sqrt{\bar\alpha_t}\,x_0,\ (1-\bar\alpha_t)I\big). &&\text{closed form} \end{aligned}

    Bayes 右邊在乘除的是三個機率密度,不是三個隨機變數。而 Gaussian 的密度是「exp⁡\exp(一個 xx 的二次式)」,把它們乘起來、再除掉一個,只是在指數上把幾個二次式加加減減——加減完還是二次式,所以配方之後出來的仍然是一個 Gaussian。

    動手算一下:配出來的這個 Gaussian q(xt−1∣xt,x0)=N(μ~t, β~tI)q(x_{t-1}\mid x_t,x_0)=\mathcal N(\tilde\mu_t,\ \tilde\beta_t I),它的變異數會跟 x0x_0 有關嗎?

    動手自己配一次方:μ~t\tilde\mu_t 和 β~t\tilde\beta_t 是怎麼跑出來的?

    首先 q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0) 之中,只有 xt−1x_{t-1} 是變數,其他兩個是給定的(視為常數),因此我們只要管 q(xt−1∣x0)q(x_{t-1}\mid x_0) 和 q(xt∣xt−1)q(x_t\mid x_{t-1}) 的乘積,不用理 q(xt∣x0)q(x_t\mid x_0):

    q(xt−1∣xt,x0) ∝ q(xt−1∣x0) q(xt∣xt−1) ∝ exp⁡[−∥xt−αt xt−1∥22βt−∥xt−1−αˉt−1 x0∥22(1−αˉt−1)].q(x_{t-1}\mid x_t,x_0)\ \propto\ q(x_{t-1}\mid x_0)\,q(x_t\mid x_{t-1}) \ \propto\ \exp\Big[-\frac{\|x_t-\sqrt{\alpha_t}\,x_{t-1}\|^2}{2\beta_t} -\frac{\|x_{t-1}-\sqrt{\bar\alpha_{t-1}}\,x_0\|^2}{2(1-\bar\alpha_{t-1})}\Big].

    方括號裡是 xt−1x_{t-1} 的一個二次式。把它按次數收好:平方項的係數是

    A=αtβt+11−αˉt−1,A=\frac{\alpha_t}{\beta_t}+\frac{1}{1-\bar\alpha_{t-1}},

    一次項寫成 −2 b⊤xt−1-2\,b^\top x_{t-1} 的話,

    b=αtβt xt+αˉt−11−αˉt−1 x0.b=\frac{\sqrt{\alpha_t}}{\beta_t}\,x_t+\frac{\sqrt{\bar\alpha_{t-1}}}{1-\bar\alpha_{t-1}}\,x_0 .

    於是整個指數是 −A2∥xt−1−b/A∥2-\tfrac{A}{2}\big\|x_{t-1}-b/A\big\|^2 再加一個不含 xt−1x_{t-1} 的常數,常數可再次無視。對照 Gaussian 的密度公式,直接可以得到 β~t=1/A\tilde\beta_t=1/A、μ~t=b/A\tilde\mu_t=b/A。

    剩下的只是化簡。AA 通分之後分子是 αt(1−αˉt−1)+βt\alpha_t(1-\bar\alpha_{t-1})+\beta_t,而這裡只需要 U1.1 定義 αt\alpha_t、αˉt\bar\alpha_t 時就留下的兩個恆等式——αt+βt=1\alpha_t+\beta_t=1 與 αtαˉt−1=αˉt\alpha_t\bar\alpha_{t-1}=\bar\alpha_t:

    αt−αtαˉt−1+βt=(αt+βt)−αˉt=1−αˉt,\alpha_t-\alpha_t\bar\alpha_{t-1}+\beta_t=(\alpha_t+\beta_t)-\bar\alpha_t=1-\bar\alpha_t ,

    所以 β~t=(1−αˉt−1) βt1−αˉt\tilde\beta_t=\dfrac{(1-\bar\alpha_{t-1})\,\beta_t}{1-\bar\alpha_t}。把它乘進 bb,兩個分母各自消掉,就是下面那兩個係數。

    代進去,我們可以推出

    q(xt−1∣xt,x0)=N(μ~t(xt,x0), β~tI),q(x_{t-1}\mid x_t,x_0)=\mathcal N\big(\tilde\mu_t(x_t,x_0),\ \tilde\beta_t I\big),

    且

    μ~t=αˉt−1 βt1−αˉt x0+αt (1−αˉt−1)1−αˉt xt,β~t=1−αˉt−11−αˉt βt.\tilde\mu_t=\frac{\sqrt{\bar\alpha_{t-1}}\,\beta_t}{1-\bar\alpha_t}\,x_0 +\frac{\sqrt{\alpha_t}\,(1-\bar\alpha_{t-1})}{1-\bar\alpha_t}\,x_t, \qquad \tilde\beta_t=\frac{1-\bar\alpha_{t-1}}{1-\bar\alpha_t}\,\beta_t .

    這個分布的平均 μ~t\tilde\mu_t 是 x0x_0 與 xtx_t 的一個加權平均——一邊拉向起點、一邊留在原地,權重只由 forward process 設計的 schedule 決定。變異數 β~t\tilde\beta_t 則完全不含 x0x_0 和 xtx_t,只是 schedule 的一個數字。

    DDPM 的訓練

    現在 learning objective 中的 target q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0) 算得出來了,下一步就是具體的訓練方法了。首先我們注意到

    q(xt−1∣xt,x0)=N(μ~t(xt,x0), β~tI)q(x_{t-1}\mid x_t,x_0)=\mathcal N\big(\tilde\mu_t(x_t,x_0),\ \tilde\beta_t I\big)

    之中只有 μ~t(xt,x0)\tilde\mu_t(x_t,x_0) 跟 xtx_t、x0x_0 有關,β~t\tilde\beta_t 是常數。而 μ~t(xt,x0)\tilde\mu_t(x_t,x_0) 裡面,模型唯一沒有的就是 x0x_0。因此最直觀的選擇就是:變異數照抄,平均也照抄同一個形狀,只把缺的那一塊換成網路的輸出 x^θ(xt,t)\hat x_\theta(x_t,t):

    pθ(xt−1∣xt)=N(μ~t(xt, x^θ(xt,t)), β~tI).p_\theta(x_{t-1}\mid x_t)=\mathcal N\Big(\tilde\mu_t\big(x_t,\ \hat x_\theta(x_t,t)\big),\ \tilde\beta_t I\Big).

    可以特別留意到這個神經網路的 input 是合理的:當下的狀態 xtx_t,跟在第幾步 tt。(在 U1.4 我們會討論這樣的假設帶來什麼代價,我們可不可以接受?)

    這個選擇讓 learning objective 中的 KL 變成只剩兩個平均之間的距離:

    DKL(q(xt−1∣xt,x0) ∥ pθ(xt−1∣xt))=12β~t∥μ~t(xt,x0)−μ~t(xt,x^θ(xt,t))∥2.\begin{aligned} D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t,x_0)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big) &=\frac{1}{2\tilde\beta_t}\Big\|\tilde\mu_t(x_t,x_0)-\tilde\mu_t\big(x_t,\hat x_\theta(x_t,t)\big)\Big\|^2 . \end{aligned}

    最後得到 L2L_2。兩個 Gaussian 的變異數相同,normalizing constant 就一樣、取對數相減會消掉;展開之後 xt−1x_{t-1} 的二次項也消掉,剩下的正是兩個平均之間的距離。

    而 μ~t\tilde\mu_t 對 x0x_0 是 affine 的,x0x_0 的係數就是上面那個 αˉt−1 βt1−αˉt\frac{\sqrt{\bar\alpha_{t-1}}\,\beta_t}{1-\bar\alpha_t},所以這個距離立刻化成兩張圖之間的距離:

    ∥μ~t(xt,x0)−μ~t(xt,x^θ)∥2=(αˉt−1 βt1−αˉt)2∥x0−x^θ∥2.\Big\|\tilde\mu_t(x_t,x_0)-\tilde\mu_t\big(x_t,\hat x_\theta\big)\Big\|^2=\Big(\frac{\sqrt{\bar\alpha_{t-1}}\,\beta_t}{1-\bar\alpha_t}\Big)^{2}\big\|x_0-\hat x_\theta\big\|^2 .

    把它代回去,整個訓練目標就是一個加權的平方誤差:

    一筆加噪資料,要怎麼變成 regression loss?

    J~(θ)=Et, x0, ϵ[w(t) ∥x^θ(xt,t)−x0∥2],w(t)=αˉt−1 βt2(1−αˉt)(1−αˉt−1), \begin{gathered} \reveal{1}{\widetilde{\mathcal J}(\theta)=}\\[.2em] \reveal{6}{\mathop{\mathbb E}\limits_{t,\,x_0,\,\epsilon}\Big[ \reveal{5}{w(t)\,} \reveal{4}{\big\|\reveal{2}{\hat x_\theta}\reveal{1}{(x_t,t)}\reveal{3}{-x_0}\big\|^2} \Big],}\\[.2em] \reveal{5}{w(t)=\frac{\bar\alpha_{t-1}\,\beta_t}{2(1-\bar\alpha_t)(1-\bar\alpha_{t-1})},} \end{gathered}
    1. 抽出 x0,t,ϵx_0,t,\epsilon,一行產生 xtx_t;模型只拿到 (xt,t)(x_t,t)。
    2. 讓 x^θ\hat x_\theta 根據這個輸入,預測原本的圖片。
    3. Training 時知道真正的 x0x_0,所以可以拿它來和模型預測相減。
    4. 把圖片差的長度取平方,得到這一筆 training pair 的誤差。
    5. 前面的 KL 推導還給了 w(t)w(t),決定這個時間的誤差要乘上多少。
    6. 再對 t,x0,ϵt,x_0,\epsilon 的抽樣取平均,讓不同原圖與加噪方式產生的 labels 都成為學習目標。

    其中 xt=αˉt x0+σtϵx_t=\sqrt{\bar\alpha_t}\,x_0+\sigma_t\epsilon 是一行算出來的。沒有對抗、沒有 normalizing constant,就是一個平方誤差——U1.0 說「路徑自己定,每一步就變成回歸」,指的就是這一行。

    兩個 covariance 相同的 Gaussian,其 KL 中相同的 normalization 與二次項抵消,最後留下兩個 mean 的平方距離;代入 posterior mean 後得到 weighted x_0 regression。

    這裡的 μ1=μ~t(xt,x0)\mu_1=\tilde\mu_t(x_t,x_0)、μ2=μ~t(xt,x^θ(xt,t))\mu_2=\tilde\mu_t(x_t,\hat x_\theta(x_t,t))。固定同一個正的 covariance β~tI\tilde\beta_t I 後,KL 化成 ∥μ1−μ2∥2/(2β~t)\|\mu_1-\mu_2\|^2/(2\tilde\beta_t);再用 μ~t\tilde\mu_t 對 x0x_0 的 affine 形式,就得到上面的 w(t)∥x^θ−x0∥2w(t)\|\hat x_\theta-x_0\|^2。圖中的 x^0\hat x_0 指的就是這個網路預測 x^θ(xt,t)\hat x_\theta(x_t,t)。

    Week 3 投影片 41 · 點圖查看原圖

    在討論 w(t)w(t) 之前,應該要有人舉手問:

    L2L_2 不是才剛被我們否決過嗎?
    為什麼這一次它就可以了?

    課堂提問Q3

    在 U1.0 我們算過:拿 L2L_2 去比對資料 x0x_0 與生成結果 Gθ(z)G_\theta(z),最佳解是一張所有訓練圖片的平均,模型會直接往它學習。現在這個 loss 也是 L2L_2、也是拿模型輸出 x^θ(xt,t)\hat x_\theta(x_t,t) 去比對真實的 x0x_0。

    為什麼這一次不會出問題?

    先想一想,再展開看整理後的答案

    差別只有一個字:配對。

    上一次 zz 與 x0x_0 是各自獨立抽的,模型拿到 zz,但對於它可能跟哪一個 x0x_0 有關完全沒有線索,所以最佳解是取平均 Epdata[x0]\mathbb E_{p_{\text{data}}}[x_0],一個與模型輸入無關的常數。但這一次的 xtx_t 是從某一張特定的 x0x_0 加噪來的,兩者被 forward process 綁在一起。L2L_2 的最佳解因此變成一個條件期望(M1.2):

    x^⋆(xt,t)=E[x0∣xt].\hat x^{\star}(x_t,t)=\mathbb E\big[x_0\mid x_t\big].

    它是一個隨 xtx_t 改變的函數,不是常數。tt 很小的時候,xtx_t 幾乎就是 x0x_0,這個條件期望幾乎等於原圖;tt 很大的時候,同一個 xtx_t 可能來自很多張不同的圖,條件期望就是那些圖的加權平均——這時候預測本來就該是模糊的。(這件事看下面那張圖會更清楚。)

    雖然同樣是做 L2L_2 norm minimization,上一次的最佳解是一個常數,而這一次是一個取決於當下 state xtx_t 的函數。

    其中的差別就來自於模型的輸入和目標 x0x_0 有沒有被以某種方式配對在一起。可以想像成看視力檢查表上的那個 E,猜它的開口朝上下左右哪一邊:畫面很清楚時,你就直接讀出來;畫面糊到只剩輪廓時,你能給的答案就是以 1/41/4 的機率盲猜,猜了幾次後就跟給出「所有可能的平均」沒什麼兩樣。

    (注意 w(t)w(t) 只是每個 tt 的權重、不隨 x^θ\hat x_\theta 改變,所以它不影響每一個 tt 上的最佳解是什麼。)

    把這個最佳解代回 pθp_\theta,整條鏈就閉合了:模型族裡最好的那個平均——寫成 μ⋆\mu^\star——是

    μ⋆(xt,t)=μ~t(xt, E[x0∣xt]),\mu^\star(x_t,t)=\tilde\mu_t\big(x_t,\ \mathbb E[x_0\mid x_t]\big),

    也就是真正那個邊際 q(xt−1∣xt)q(x_{t-1}\mid x_t) 的平均。所以「倒著走一步需要知道什麼」有了完整的答案:散布是 schedule 給的,中心由 E[x0∣xt]\mathbb E[x_0\mid x_t] 決定,而那一個量就是我們要學的東西。

    (要說清楚的是:「L2L_2 的最佳解是條件期望」這件事,我們在這裡只是提到,並沒有證明——上面是靠和前一個情境對照得到的。這個結論的證明與它真正的份量,U1.3 會好好討論。)

    同一個 x_t 對應多張可能原圖:小 t 時 posterior 較集中,大 t 時權重較分散,conditional mean 因而可能模糊。

    把可能原圖離散成 x0(i)x_0^{(i)} 後,E[x0∣xt]=∑ip(x0(i)∣xt)x0(i)\mathbb E[x_0\mid x_t]=\sum_i p(x_0^{(i)}\mid x_t)x_0^{(i)}。上排用 (0.96,0.03,0.01)(0.96,0.03,0.01) 示意集中的 posterior;下排用 (0.28,0.24,0.20,0.18,0.10)(0.28,0.24,0.20,0.18,0.10) 示意較分散的 posterior。這些權重是教學例子;它們各自加總為 11,平均後的模糊正是這個例子的 conditional mean。

    Week 3 投影片 43 · 點圖查看原圖

    看一個點怎麼被去噪

    互動 demo:去噪一個點。 在平面上點一個位置當成 xtx_t,再拖 tt。每個資料點的大小是它的後驗權重 p(x0∣xt)∝exp⁡(−∥xt−αˉtx0∥2/2σt2)p(x_0\mid x_t)\propto\exp\big(-\|x_t-\sqrt{\bar\alpha_t}x_0\|^2/2\sigma_t^2\big),箭頭指向 E[x0∣xt]\mathbb E[x_0\mid x_t]。tt 小的時候只有一兩個點亮著,箭頭幾乎指在原地;tt 大的時候整批點都亮,箭頭就指向一個平均的位置。

    學完之後,怎麼真的走回去?

    前面我們已經把模型訓練好了。現在假設手上有一個 xtx_t,下一步就是要產生 xt−1x_{t-1}。

    我們前面把 reverse distribution 寫成

    pθ(xt−1∣xt),p_\theta(x_{t-1}\mid x_t),

    而且選擇用 Gaussian 來 parametrize 它。網路負責預測 x^θ(xt,t)\hat x_\theta(x_t,t),再把它代回前面推導出的 posterior mean:

    預測出原圖之後,怎麼真的退回一步?

    xt−1=μ~t(xt, x^θ(xt,t))+β~t z,z∼N(0,I). \begin{aligned} \reveal{1}{x_{t-1}=} &\reveal{3}{\tilde\mu_t\big(\reveal{1}{x_t},\ \reveal{2}{\hat x_\theta(x_t,t)}\big)}\\ &\reveal{4}{+\sqrt{\tilde\beta_t}\,z,}\\ &\reveal{4}{z\sim\mathcal N(0,I).} \end{aligned}
    1. 生成時先有當下的 xtx_t,要從它產生前一步 xt−1x_{t-1}。
    2. 真正的 x0x_0 不在手上,先讓網路預測 x^θ(xt,t)\hat x_\theta(x_t,t)。
    3. 把現在的狀態和預測原圖代回 μ~t\tilde\mu_t,算出這一步的平均位置。
    4. 再加上一個新抽的 β~tz\sqrt{\tilde\beta_t}z,完成從 reverse Gaussian 抽樣。

    這樣就完成一次 xt→xt−1x_t\to x_{t-1}。

    接下來沒有新的東西:從

    xT∼N(0,I)x_T\sim\mathcal N(0,I)

    開始,重複同樣的步驟,

    xT→xT−1→⋯→x1→x0,x_T\to x_{T-1}\to\cdots\to x_1\to x_0,

    最後就得到一個 sample。

    到這裡,我們已經知道 DDPM 怎麼訓練,也知道訓練完之後怎麼拿來生成。

    這樣的 regression,憑什麼保證生成出來的東西是好的?

    前面一路做下來,我們最後得到的只是一個 regression loss。但我們真正關心的是:把這個 loss 壓低,真的會讓模型生成的 data distribution 更接近資料實際的分布嗎?

    根據其實是有的,我們可以沿著三個步驟去解釋、證明。

    第一步:從 likelihood 出發。 我們希望模型對真實資料給高 likelihood,也就是讓 −log⁡pθ(x0)-\log p_\theta(x_0) 越小越好。但 pθ(x0)p_\theta(x_0) 需要把整條 latent path 積掉,不好直接算。利用 forward process q(x1:T∣x0)q(x_{1:T}\mid x_0) 和 Jensen inequality,可以得到

    −log⁡pθ(x0) ≤ Eq(x1:T∣x0) ⁣[−log⁡pθ(x0:T)q(x1:T∣x0)].-\log p_\theta(x_0)\ \le\ \mathbb E_{q(x_{1:T}\mid x_0)}\!\left[-\log\frac{p_\theta(x_{0:T})}{q(x_{1:T}\mid x_0)}\right].

    也就是說,我們可以改去最小化 negative log-likelihood 的一個上界,也就是 ELBO(evidence lower bound,見 當那個要加總的量算不出來,可以退到哪裡?)對應的 loss。

    第二步:把整條 path 看成兩個 distribution。 再對 x0∼pdatax_0\sim p_{\text{data}} 取平均,上面的 quantity 可以寫成

    DKL(q(x0:T) ∥ pθ(x0:T))+constant.D_{\mathrm{KL}}\big(q(x_{0:T})\,\big\|\,p_\theta(x_{0:T})\big)+\text{constant}.

    所以問題變成:讓模型的整條 reverse path,接近資料經過 forward process 產生的那條 path。

    第三步:Markov structure 讓這個 path-level KL 可以逐步拆開。 最後跟 θ\theta 有關的部分,就是每個 timestep 的 reverse transition mismatch:

    ∑tEpt(xt)[DKL(q(xt−1∣xt) ∥ pθ(xt−1∣xt))].\sum_t\mathbb E_{p_t(x_t)}\Big[D_{\mathrm{KL}}\big(q(x_{t-1}\mid x_t)\,\big\|\,p_\theta(x_{t-1}\mid x_t)\big)\Big].

    而這正是我們前面一路改寫、最後變成 regression loss 的東西。

    所以整條關係是

     regression loss ⟶ reverse-step KL ⟶ path KL ⟶ −log⁡pθ(x0) 的上界 \boxed{\ \text{regression loss}\ \longrightarrow\ \text{reverse-step KL}\ \longrightarrow\ \text{path KL}\ \longrightarrow\ -\log p_\theta(x_0)\ \text{的上界}\ }

    也就是說,前面的 regression 並不是憑空設計的:它一路可以接回我們真正關心的 generative likelihood。

    不過這並不代表每一步都能完全學準。我們把 pθ(xt−1∣xt)p_\theta(x_{t-1}\mid x_t) 限制在特定的 Gaussian family 裡,因此一般不保證它能精確等於真正的 reverse conditional。

    這也留下幾個後面的問題:這個 approximation 到底有多好?noise 一定要加嗎?如果 timestep 切得越來越細,又會發生什麼?

    這些等到 U1.4 再討論!

    同一個 reverse step,不一定要學 x0x_0

    由 xt=αˉtx0+σtϵx_t=\sqrt{\bar\alpha_t}x_0+\sigma_t\epsilon 可以看到:在 xtx_t 已知的情況下,只要知道 x0x_0 或 ϵ\epsilon 其中一個,另一個就可以直接算出來:

    x0=xt−σtϵαˉt⟺ϵ=xt−αˉtx0σt.x_0=\frac{x_t-\sigma_t\epsilon}{\sqrt{\bar\alpha_t}} \qquad\Longleftrightarrow\qquad \epsilon=\frac{x_t-\sqrt{\bar\alpha_t}x_0}{\sigma_t}.

    所以,網路不一定非得直接預測 x0x_0。我們也可以讓它預測 ϵ\epsilon,再用上面的式子換回 x0x_0。同一個 denoising 問題,可以選擇讓網路預測不同、但彼此可以換算的 quantity。這個「網路輸出要用哪一種表示方式」的選擇,就叫做 parametrization。

    在我們目前這個 formulation 裡,實務上常見的選擇有三種:x0x_0-prediction、ϵ\epsilon-prediction,以及 vv-prediction。

    x0x_0-prediction:直接輸出 x^0\hat x_0,也就是〈DDPM 的訓練〉推出來的那個 loss。

    ϵ\epsilon-prediction(Ho、Jain 與 Abbeel 的 DDPM 原文 [1]):讓網路去猜那個總噪聲。

    Lϵ=E[∥ϵθ(xt,t)−ϵ∥2],x^0=xt−σtϵθαˉt.\mathcal L_\epsilon=\mathbb E\big[\|\epsilon_\theta(x_t,t)-\epsilon\|^2\big], \qquad \hat x_0=\frac{x_t-\sigma_t\epsilon_\theta}{\sqrt{\bar\alpha_t}} .

    vv-prediction(Salimans 與 Ho [3]):把 (αˉt,σt)(\sqrt{\bar\alpha_t},\sigma_t) 看成 (cos⁡ϕt,sin⁡ϕt)(\cos\phi_t,\sin\phi_t),定義

    v=αˉt ϵ−σt x0.v=\sqrt{\bar\alpha_t}\,\epsilon-\sigma_t\,x_0 .

    vv 是 (x0,ϵ)(x_0,\epsilon) 平面上與 xtx_t 垂直的那個方向。它在 t→0t\to0 時像 ϵ\epsilon、在 t→Tt\to T 時像 −x0-x_0,兩端都不會退化。這個「兩端都不退化」現在看起來只是好看,要到 U5.1 把步數減到很少的時候才真正派上用場——vv-prediction 最早就是在那裡被提出來的。

    符號為什麼 v 可以看成「垂直方向」?

    因為 αˉt+σt2=1\bar\alpha_t+\sigma_t^2=1,我們可以寫 αˉt=cos⁡ϕt\sqrt{\bar\alpha_t}=\cos\phi_t、σt=sin⁡ϕt\sigma_t=\sin\phi_t。於是

    xt=cos⁡ϕt x0+sin⁡ϕt ϵ,v=cos⁡ϕt ϵ−sin⁡ϕt x0.x_t=\cos\phi_t\,x_0+\sin\phi_t\,\epsilon,\qquad v=\cos\phi_t\,\epsilon-\sin\phi_t\,x_0 .

    在以 x0x_0、ϵ\epsilon 為兩軸的平面上,xtx_t 與 vv 剛好是互相垂直的一組座標——vv 就是「沿著 ϕt\phi_t 增加的方向」,也就是 xtx_t 對 ϕt\phi_t 的導數。這也是它兩端都不退化的原因:不管 ϕt\phi_t 靠近 0 還是 π/2\pi/2,垂直方向永遠存在。

    三者之間可以透過 affine transformation 互相轉換,而且轉換係數只和 tt 有關。所以,在表示上,只要知道其中一個,就可以直接算出另外兩個——給定其中一個訓好的網路,另外兩個不用重訓,代數換算就有了。實作那篇會要你親手驗證一次。

    但用這三種 parametrization 去訓練,最後會得到完全一樣的結果嗎?

    表示上等價,但訓練上不相同

    假設我們都使用看起來一樣的 MSE loss——就是前面一路在用的那個平方誤差:

    E[∥prediction−target∥2],\mathbb E\big[\|\text{prediction}-\text{target}\|^2\big],

    把 target 從 x0x_0 換成 ϵ\epsilon 或 vv 之後,對應回同一個 quantity 時,不同 noise level 的誤差會被乘上不同的權重。

    把 x^0\hat x_0 與 ϵθ\epsilon_\theta 的關係代進去就看得到:

    ∥x^0−x0∥2=σt2αˉt ∥ϵθ−ϵ∥2=1SNR(t) ∥ϵθ−ϵ∥2,SNR(t)=αˉt1−αˉt.\|\hat x_0-x_0\|^2=\frac{\sigma_t^2}{\bar\alpha_t}\,\|\epsilon_\theta-\epsilon\|^2 =\frac{1}{\mathrm{SNR}(t)}\,\|\epsilon_\theta-\epsilon\|^2, \qquad \mathrm{SNR}(t)=\frac{\bar\alpha_t}{1-\bar\alpha_t}.

    所以前面推出來的那個加權平方誤差,換到 ϵ\epsilon 座標之後也只是換一組權重:

    J~(θ)=Et[w(t)SNR(t)⋅(該 t 的 ϵ-loss)],w(t)SNR(t)=βt2 αt (1−αˉt−1).\widetilde{\mathcal J}(\theta)=\mathbb E_t\Big[\tfrac{w(t)}{\mathrm{SNR}(t)}\cdot\big(\text{該 } t \text{ 的 }\epsilon\text{-loss}\big)\Big], \qquad \frac{w(t)}{\mathrm{SNR}(t)}=\frac{\beta_t}{2\,\alpha_t\,(1-\bar\alpha_{t-1})}.

    所以三種 parametrization 雖然可以互相換算,但它們定義的 training objective 並不完全相同。

    要小心「不完全相同」指的是什麼:不同寫法的最小值點是同一個(都被同一個條件期望達成);不一樣的是在有限容量、有限訓練時間下,它們對不同 tt 的重視程度。也就是說:

    representation equivalent  ≠  optimization equivalent\boxed{\text{representation equivalent} \;\neq\; \text{optimization equivalent}}

    差別主要就在於:不同的 parametrization,會讓模型更重視不同 noise level 的誤差。

    同一個 noisy input 可選擇預測 x_0、epsilon 或 v;三種表示可互相換算,但相同形式的 MSE 會產生不同的 timestep weighting。

    三欄代表三種可選的 target;fθ(xt,t)f_\theta(x_t,t) 表示網路骨幹,輸出可選 x^0\hat x_0、ϵθ\epsilon_\theta 或 vθv_\theta。下方一邊列出代數換算,一邊寫出 ∥x^0−x0∥2=∥ϵθ−ϵ∥2/SNR(t)\|\hat x_0-x_0\|^2=\|\epsilon_\theta-\epsilon\|^2/\mathrm{SNR}(t)。右下的垂直關係是 (x0,ϵ)(x_0,\epsilon) 的係數座標旋轉,不是說任意兩張圖片向量 xtx_t 與 vv 的內積都等於零。

    Week 3 投影片 45 · 點圖查看原圖

    這裡我們順便講一下 DDPM 原文實際採用的做法。

    在實作上,它直接把這個 weighting w(t)w(t) 拿掉,改成均勻(uniform)加權的 ϵ\epsilon-MSE:

    Lsimple(θ)=Et, x0, ϵ[∥ϵθ(xt,t)−ϵ∥2].\mathcal L_{\text{simple}}(\theta)=\mathbb E_{t,\,x_0,\,\epsilon}\big[\|\epsilon_\theta(x_t,t)-\epsilon\|^2\big].

    關於這樣的操作,我們可以理解成:

    forward process 決定我們怎麼製造不同 noise level 的資料;
    weighting 決定 training 時多重視哪些 noise level。

    兩件事其實可以分開設計。因此,即使 forward process 不變,我們仍然可以改變不同 tt 在 loss 裡的 weighting。代價是前面那個 ELBO 的不等式跟著失效:加權一換,被界住的就不再是原來那個 −log⁡pθ(x0)-\log p_\theta(x_0)。Kingma 與 Gao [4] 系統性地整理了這些 diffusion objectives 與 ELBO 的關係。理想情況下,改變 weighting 不會動到每個 tt 對應的最佳 predictor,但會改變實際訓練時模型把 capacity 和 optimization effort 放在哪些地方。U2 比較 diffusion 與 flow matching 時,這個 distinction 還會再出現。

    DDPM 的訓練核心其實就這五行

    repeat
      x0 ← 一個 batch 的資料
      t  ← Uniform{1,…,T}
      ε  ← N(0, I)
      xt ← √ᾱ_t · x0 + √(1-ᾱ_t) · ε
      loss ← ‖ε_θ(xt, t) − ε‖²
      梯度下降

    這裡我們先寫成 pseudo code。真的要實作,還需要決定 batch size、TT、noise schedule、ϵθ\epsilon_\theta 的網路架構和 optimizer,但核心 training loop 就是上面這幾步。

    到 U1.5,我們會把它真的寫成可以跑的程式。到時候你也會看到一個有趣的現象:loss 不會一路掉到 0,而會停在一個非零值附近。這不是程式寫錯;在 U1.3,我們會先了解為什麼這件事本來就應該發生。

    消化一下

    想一想

    把目標從「q(xt−1∣xt)q(x_{t-1}\mid x_t) 與 pθp_\theta 的 KL」換成「q(xt−1∣xt,x0)q(x_{t-1}\mid x_t,x_0) 與 pθp_\theta 的 KL、再對 x0x_0 取平均」,這個換法是什麼?

    想一想

    這一篇從頭到尾,哪一步才是真正的取捨(也就是可能讓我們拿不到真正最佳解的那一步)?

    想一想

    訓好一個 ϵ\epsilon-prediction 網路之後,想拿到 x^0\hat x_0,需要做什麼?

    想一想

    DDPM 原文用的 Lsimple\mathcal L_{\text{simple}} 和這一篇推導出來的目標,關係是什麼?

    想一想

    把 tt 固定在很大的值(噪聲很重)訓練,然後看模型對單一個 xtx_t 的輸出 x^0\hat x_0,會看到什麼?

    參考文獻

    1. Ho, J., Jain, A., Abbeel, P. Denoising Diffusion Probabilistic Models. NeurIPS 2020. (變分推導、ϵ\epsilon-prediction 與「丟掉加權」的簡化 loss。)
    2. Lai, C.-H., Song, Y., Kim, D., Mitsufuji, Y., Ermon, S. The Principles of Diffusion Models. 2025, Section 2.2. (本篇的骨架:先用等價定理證明條件化合法,再挑模型族。)
    3. Salimans, T., Ho, J. Progressive Distillation for Fast Sampling of Diffusion Models. ICLR 2022. (vv-prediction 的出處。)
    4. Kingma, D. P., Gao, R. Understanding Diffusion Objectives as the ELBO with Simple Data Augmentation. NeurIPS 2023. (把「加權」與 ELBO 的關係講清楚。)