CS236 第 8 講 · Coupling 與 Autoregressive Flows
Stanford CS236 · Fall 2023 · Lecture 8

Coupling 與 Autoregressive Flows:怎麼做出可逆的神經網路

上一講知道 flow 需要三件事:容易反轉、容易算 Jacobian 行列式、而且兩個方向至少有一個要快。這講看具體的設計。Coupling layer(NICE、RealNVP)讓一半的變數原樣通過、用它去平移和縮放另一半。Autoregressive flow(MAF、IAF)把 Gaussian autoregressive model 重新詮釋成 flow,在「快速取樣」和「快速算 likelihood」之間二選一,Parallel WaveNet 再用蒸餾兩者兼得。最後是 MintNet 和 Gaussianization flow 兩種不同思路。

讀完這頁你應該能夠

  1. 寫出 NICE 加法 coupling 的正向、反向與 Jacobian,說明為什麼它保持體積(det = 1)。
  2. 寫出 RealNVP 仿射 coupling 的三個公式,說明為什麼 \(\mu_\theta,\alpha_\theta\) 可以是任意神經網路。
  3. 把 Gaussian autoregressive model 寫成 flow,說明 MAF 的取樣慢、算 likelihood 快。
  4. 說明 IAF 是 MAF 的反向,取樣快、算外部資料的 likelihood 慢,但能快速算自己樣本的 likelihood。
  5. 解釋 Parallel WaveNet 的 probability density distillation 為什麼用 \(D_{\mathrm{KL}}(s\Vert t)\),以及它需要的三個量都能有效計算。
  6. 說明 MintNet 的遮罩卷積與 Gaussianization flow 的「把資料變成高斯」觀點。

前置知識檢查

  • 第 7 講:變數變換公式、多層 flow 的 log 行列式相加、三角 Jacobian(第 7 講 B6)
  • 第 3 講:MADE 的遮罩、PixelCNN 的遮罩卷積、autoregressive model 取樣是逐步的
  • 第 4 講:KL 的兩個方向;第 6 講:reparameterization trick
  • CDF 與反 CDF 取樣(第 2 講補充、本講第 8 節)

本頁對照過投影片圖片;標「出處」的補充來自 Lilian Weng〈Flow-based Deep Generative Models〉、Kingma & Welling (2019) 第 3 章、Lai et al. (2026)(arXiv 2510.21890v3)§5.1。

01回顧:flow 的三個需求(投影片 2–8)

這部分是第 7 講沒講到的投影片 13–19,詳細內容見第 7 講 B6。這裡只整理課堂上新增的說明和問答。

$$p_X(\mathbf x;\theta) = p_Z\big(f_\theta^{-1}(\mathbf x)\big)\left|\det\frac{\partial f_\theta^{-1}(\mathbf x)}{\partial\mathbf x}\right|,\qquad f_\theta = f_\theta^M\circ\cdots\circ f_\theta^1$$
  • 精確、沒有任何近似:不需要 encoder、不需要對 \(\mathbf z\) 積分,和 autoregressive model 一樣舒服。代價是 \(\mathbf z\) 和 \(\mathbf x\) 必須同維度。03:39
  • 每層都可逆,合起來就可逆;整體的 log 行列式是各層相加。每層的參數不共享,\(\theta\) 代表所有層參數的聯集。07:52
  • 為什麼要疊很多簡單的層,而不是一個複雜的網路?這是深度學習的老套路:每層都很簡單(接近線性),疊起來就能非常有彈性。12:39
  • 可逆性怎麼保證?要把架構設計成不管參數怎麼學,都一定可逆,而且反函數要好算、Jacobian 行列式也要好算(一般是 \(O(n^3)\))。這正是這講的主題。13:39
課堂問答 · 21:29要參數化 \(f_\theta\)(取樣用的方向)還是 \(f_\theta^{-1}\)(訓練用的方向)?兩者都可以,只要參數化一個,另一個由可逆性得到。但「可逆」不代表「反得便宜」:如果反函數要解一個線性方程組,訓練時每步都要做就太貴。所以要依用途決定哪個方向要快,這就是後面 MAF 和 IAF 的取捨。21:29

投影片 8 列出今天的計畫:對角 Jacobian 的可逆變換(NICE、RealNVP)、autoregressive model 當 flow、可逆 CNN(MintNet)、Gaussianization flow、Parallel WaveNet 的 probability density distillation。投影片 9 還列了 i-ResNet、Glow 等其他設計。

02NICE:加法 coupling(投影片 10–13)

把 \(\mathbf z\) 分成兩組:\(\mathbf z_{1:d}\) 和 \(\mathbf z_{d+1:n}\),\(1\le d<n\) 任選。29:19

正向 z → x $$\mathbf x_{1:d} = \mathbf z_{1:d}$$ $$\mathbf x_{d+1:n} = \mathbf z_{d+1:n} + m_\theta(\mathbf z_{1:d})$$ \(m_\theta\) 是任意神經網路,\(d\) 個輸入、\(n-d\) 個輸出。
反向 x → z $$\mathbf z_{1:d} = \mathbf x_{1:d}$$ $$\mathbf z_{d+1:n} = \mathbf x_{d+1:n} - m_\theta(\mathbf x_{1:d})$$ 反向時 \(m_\theta\) 的輸入 \(\mathbf x_{1:d}\) 等於正向時的 \(\mathbf z_{1:d}\),所以平移量算得出來。

為什麼這麼簡單就可逆?前 \(d\) 個沒變,所以反向時能重新算出正向用過的平移量 \(m_\theta\),再減掉就好。\(m_\theta\) 本身不需要可逆,可以是任意複雜的網路。30:51

$$J = \frac{\partial\mathbf x}{\partial\mathbf z} = \begin{pmatrix} I_d & 0 \\ \dfrac{\partial\mathbf x_{d+1:n}}{\partial\mathbf z_{1:d}} & I_{n-d}\end{pmatrix},\qquad \det J = 1$$

下三角,對角線全是 1,所以 \(\det J = 1\):volume preserving(保持體積)。行列式項在 likelihood 中直接消失。左下角那塊 \(\partial\mathbf x_{d+1:n}/\partial\mathbf z_{1:d}\) 再複雜也不影響行列式。32:27

Rescaling 層

多個加法 coupling 層疊起來,每層可以換不同的分組方式。最後一層做縮放:\(x_i = s_iz_i\)(\(s_i>0\)),反向 \(z_i = x_i/s_i\),Jacobian 是 \(\mathrm{diag}(\mathbf s)\),\(\det J = \prod_i s_i\)。有了這層,模型才能整體改變體積。35:06

投影片 12–13 的圖:NICE 在四個資料集上的取樣:MNIST(可以認出的手寫數字,但有些筆畫斷裂)、TFD 人臉(灰階、模糊但有臉的輪廓)、SVHN 門牌號碼(彩色、隱約可見數字)、CIFAR-10(彩色斑塊,看不出物體)。36:43

老師怎麼說 · 36:43這麼簡單的層就能做到這樣,已經令人意外:疊夠多層,就能把像素上的複雜分佈映射成高斯。36:43
為什麼每層要換分組?

只用一種分組時,前 \(d\) 個變數永遠原樣通過,從頭到尾都沒被改動,模型對它們的分佈什麼也學不到(只能靠最後的縮放)。所以相鄰的層要交換角色,讓上一層沒被改動的變數在下一層被改動。RealNVP 在影像上用了兩種分組:棋盤格遮罩(空間上黑白格交錯)和通道遮罩(一半通道不動),並搭配 squeeze 操作做多尺度架構。Glow 則把固定的「交換順序」換成可學的 1×1 可逆卷積:每個像素位置上對 \(c\) 個通道乘同一個 \(c\times c\) 矩陣 \(W\),log 行列式是 \(h\cdot w\cdot\log|\det W|\),因為 \(c\) 很小所以算得起。排列只是 \(W\) 的特例。

出處:Lilian Weng,〈Flow-based Deep Generative Models〉RealNVP、Glow 兩節。

03RealNVP:仿射 coupling(投影片 14–16)

NICE 的自然延伸:除了平移,也縮放。39:18

正向 z → x $$\mathbf x_{1:d} = \mathbf z_{1:d}$$ $$\mathbf x_{d+1:n} = \mathbf z_{d+1:n}\odot\exp\big(\alpha_\theta(\mathbf z_{1:d})\big) + \mu_\theta(\mathbf z_{1:d})$$
反向 x → z $$\mathbf z_{1:d} = \mathbf x_{1:d}$$ $$\mathbf z_{d+1:n} = \big(\mathbf x_{d+1:n} - \mu_\theta(\mathbf x_{1:d})\big)\odot\exp\big(-\alpha_\theta(\mathbf x_{1:d})\big)$$
$$J = \begin{pmatrix} I_d & 0 \\ \dfrac{\partial\mathbf x_{d+1:n}}{\partial\mathbf z_{1:d}} & \mathrm{diag}\big(\exp(\alpha_\theta(\mathbf z_{1:d}))\big)\end{pmatrix},\qquad \det J = \prod_{i=d+1}^{n}\exp\big(\alpha_\theta(\mathbf z_{1:d})_i\big) = \exp\Big(\sum_{i=d+1}^{n}\alpha_\theta(\mathbf z_{1:d})_i\Big)$$
  • 取 exp 是為了保證縮放因子不為 0,這樣才可逆。40:21
  • 行列式可以大於或小於 1:non-volume preserving(這就是 NVP 的意思),能在某些方向壓縮、某些方向放大,所以比 NICE 有彈性。\(\alpha_\theta\equiv0\) 時就退回 NICE。43:34
  • log 行列式就是 \(\sum_i\alpha_\theta(\cdot)_i\),一次 forward 就算出來,完全不用算矩陣行列式。
為什麼 μ 和 α 可以是任意複雜的網路?

兩個原因:(1) 求反函數時不需要反轉 \(\mu_\theta\) 或 \(\alpha_\theta\),只要用已知的 \(\mathbf x_{1:d}\) 重新算一次;(2) 算 Jacobian 行列式時不需要 \(\mu_\theta,\alpha_\theta\) 的 Jacobian,因為它們只出現在左下角,不影響三角矩陣的行列式。所以 coupling layer 把「可逆」和「表達力」分開處理:可逆性由結構保證,表達力交給任意的神經網路。

出處:Lilian Weng,〈Flow-based Deep Generative Models〉RealNVP 一節。

課堂問答 · 45:07給定 \(\mathbf z\),生成過程是確定的嗎?是。映射本身是確定的,所有隨機性都在 \(\mathbf z\)。這是限制,也正是讓 likelihood 可算的原因。45:07

投影片 15–16 的圖:RealNVP 的取樣,左邊是訓練資料、右邊是生成的影像:CelebA 人臉、LSUN 臥室、ImageNet 等,解析度不高但結構正確,比 NICE 好得多。投影片 16 是潛在空間內插:每個 3×3 圖格的四個角是真實影像,中間是把它們的 \(\mathbf z\) 內插後再解碼的結果,人臉和建築都平滑過渡。45:37

內插公式(投影片 16):用四個驗證樣本的 \(\mathbf z^{(1)},\dots,\mathbf z^{(4)}\),

$$\mathbf z = \cos\phi\big(\mathbf z^{(1)}\cos\phi' + \mathbf z^{(2)}\sin\phi'\big) + \sin\phi\big(\mathbf z^{(3)}\cos\phi' + \mathbf z^{(4)}\sin\phi'\big)$$

用 cos 和 sin 而不是線性內插,是因為高維高斯的樣本幾乎都落在半徑約 \(\sqrt n\) 的球殼上。線性內插的中點會跑進球的內部,那裡在先驗下其實是罕見的區域;用 cos/sin 組合,長度大致保持不變。所以即使 \(\mathbf z\) 沒有壓縮,它仍然有有意義的結構。47:11

Demo A在瀏覽器裡訓練 NICE / RealNVP

二維 two moons 資料。8 層 coupling(交替讓 \(x_1\)、\(x_2\) 當條件),每層的 \(\mu_\theta,\alpha_\theta\) 是一個 24 個隱藏單元的小網路,最後加一層可學的縮放(NICE 的 rescaling)。用精確的 log-likelihood 做 MLE、Adam 訓練。「NICE」模式把 \(\alpha_\theta\) 固定為 0,只剩平移。

訓練資料
學到的密度 p(x)(精確計算)
樣本流經前 k 層
RealNVP 測試 NLLNICE 測試 NLL(若有訓練過)
  • 右圖的滑桿是「flow」的字面意義:k = 0 是標準高斯,每多一層,點雲就被拉扯一次,最後變成兩個月亮。每層只是「固定一個座標,平移和縮放另一個座標」,疊起來卻能做出彎曲的形狀。
  • NICE 每層的行列式都是 1,只有最後的縮放層能改變整體大小,所以它只能「剪切和移動」機率質量,不能局部壓縮或拉伸。比較兩條訓練曲線,RealNVP 的 NLL 通常明顯較低,月亮的邊緣也較銳利。實測各訓練到停止:測試集 NLL RealNVP 1.53、NICE 1.99 nats / 點。

04Autoregressive model 就是 flow:MAF(投影片 17–19)

考慮連續的 Gaussian autoregressive model:48:45

$$p(\mathbf x) = \prod_{i=1}^{n}p(x_i\mid\mathbf x_{<i}),\qquad p(x_i\mid\mathbf x_{<i}) = \mathcal N\Big(\mu_i(x_1,\dots,x_{i-1}),\ \exp\big(\alpha_i(x_1,\dots,x_{i-1})\big)^2\Big)$$

\(\mu_i,\alpha_i\) 對 \(i>1\) 是神經網路,\(i=1\) 時是常數。怎麼從它取樣?用 reparameterization:50:18

  1. 抽 \(z_i\sim\mathcal N(0,1)\),\(i=1,\dots,n\)
  2. \(x_1 = \exp(\alpha_1)z_1 + \mu_1\),然後算 \(\mu_2(x_1),\alpha_2(x_1)\)
  3. \(x_2 = \exp(\alpha_2)z_2 + \mu_2\),然後算 \(\mu_3(x_1,x_2),\alpha_3(x_1,x_2)\)
  4. \(x_3 = \exp(\alpha_3)z_3 + \mu_3\),……
FLOW 的詮釋這就是把一組獨立的標準高斯 \((z_1,\dots,z_n)\),用 \(\mu_i(\cdot),\alpha_i(\cdot)\) 參數化的可逆變換,轉成模型的樣本 \((x_1,\dots,x_n)\)。這和 RealNVP 的「平移加縮放」是同一種運算,只是條件換成了所有前面的 \(x\)。

投影片 18–19 的圖(改編自 Eric Jang 的部落格):下排是基底分佈的 \(z_1,z_2,\dots,z_n\),上排是轉換後的 \(x_1,x_2,\dots,x_n\)。每個 \(x_i\) 由 \(z_i\) 往上一箭頭得到,中間有紅、綠兩個小圓圈代表 \(\mu_i,\alpha_i\),它們的輸入箭頭來自上排已經算好的 \(x_{<i}\)。

MAF 正向 z → x(取樣)
每個 \(x_i\) 都要等前面的 \(x_{<i}\) 算完才能算 \(\mu_i,\alpha_i\):依序、慢、\(O(n)\) 步,就和 autoregressive model 取樣一樣。54:31
MAF 反向 x → z(算 likelihood)給一張完整的 \(\mathbf x\),所有 \(\mu_i,\alpha_i\) 可以一次平行算出(例如用 MADE),再平行算 \(z_i = (x_i-\mu_i)/\exp(\alpha_i)\)。Jacobian 下三角,likelihood 計算快速且可平行。55:01

這就是 Masked Autoregressive Flow(MAF,Papamakarios et al. 2017)。不同變數順序的層可以疊起來,增加彈性。它本質上就是一個 autoregressive model,繼承了全部的性質:訓練快、取樣慢。57:09

MAF 的 log 行列式

反向映射 \(z_i = (x_i-\mu_i(\mathbf x_{<i}))\exp(-\alpha_i(\mathbf x_{<i}))\)。\(z_i\) 只依賴 \(\mathbf x_{\le i}\),所以 Jacobian \(\partial\mathbf z/\partial\mathbf x\) 是下三角,對角線是 \(\partial z_i/\partial x_i = \exp(-\alpha_i)\):

$$\log p(\mathbf x) = \sum_{i=1}^{n}\Big[\log\mathcal N(z_i;0,1) - \alpha_i(\mathbf x_{<i})\Big]$$

代回去會發現,這就是 \(\sum_i\log\mathcal N(x_i;\mu_i,e^{2\alpha_i})\),也就是原本 autoregressive model 的 log-likelihood。flow 的觀點和 autoregressive 的觀點給出同一個數字。

05IAF:把 MAF 反過來用(投影片 20–22)

既然 MAF 只是一個可逆的神經網路,把 \(\mathbf x\) 和 \(\mathbf z\) 的名字對調,它仍然是可逆的神經網路。哪一端叫輸入、哪一端叫輸出,其實無所謂。58:42現在讓 \(\mu_i,\alpha_i\) 依賴 \(\mathbf z_{<i}\),就是 Inverse Autoregressive Flow(IAF,Kingma et al. 2016):

IAF 正向 z → x(平行)抽好所有 \(z_i\sim\mathcal N(0,1)\);\(\mu_i(\mathbf z_{<i}),\alpha_i(\mathbf z_{<i})\) 全部可以平行算;\(x_i = \exp(\alpha_i)z_i + \mu_i\) 也全部平行。一次就生成。
IAF 反向 x → z(依序)
\(z_1 = (x_1-\mu_1)/\exp(\alpha_1)\),算出 \(\mu_2(z_1),\alpha_2(z_1)\);\(z_2 = (x_2-\mu_2)/\exp(\alpha_2)\),算出 \(\mu_3(z_1,z_2)\)……必須一個一個來。60:49
  • 取樣快、算外部資料的 likelihood 慢,所以很難用 MLE 訓練:每個訓練資料點都要依序反推。
  • 但算自己樣本的 likelihood 很快:如果是自己生成的點,把當初用的 \(z_1,\dots,z_n\) 存起來(cache),就不用反推,\(\alpha_i\) 也早就算過了。62:24

投影片 21 的圖:左邊是 MAF 的反向計算、右邊是 IAF 的正向計算,兩張圖的箭頭結構完全一樣,只是上下兩排的標籤 x 和 z 對調了。MAF 的反向就是 IAF 的正向,MAF 的正向就是 IAF 的反向。64:31

MAFIAF
取樣 \(\mathbf z\to\mathbf x\)慢(n 步依序)快(1 步平行)
外部資料的 likelihood快(1 步平行)慢(n 步依序)
自己樣本的 likelihood快快(cache 住 z)
適合MLE 訓練、密度估計即時生成;當 VAE 的 q

能不能兩者兼得?65:01

IAF 原本是為 VAE 的近似後驗設計的

回想第 6 講:VAE 的 \(q(\mathbf z\mid\mathbf x)\) 需要兩件事:從 \(q\) 抽樣(reparameterization),以及算自己抽出的樣本的 \(\log q(\mathbf z)\)。它從來不需要算「外部給定的點」在 \(q\) 下的機率。這正好是 IAF 的強項。

Kingma & Welling 書中的作法:encoder 先給一個對角高斯 \(\mathbf z_0 = \boldsymbol\mu + \boldsymbol\sigma\odot\boldsymbol\epsilon\),再疊 \(T\) 步 IAF;每一步用 autoregressive 網路(例如 MADE)算出 \(\mathbf m,\mathbf s\),令 \(\boldsymbol\sigma_t = \mathrm{sigmoid}(\mathbf s)\)、\(\mathbf z \leftarrow \boldsymbol\sigma_t\odot\mathbf z + (1-\boldsymbol\sigma_t)\odot\mathbf m\),同時 \(\log q \leftarrow \log q - \sum_i\log\sigma_{t,i}\)。這讓 \(q\) 從對角高斯變成能表示相關性和非高斯形狀的分佈,縮小第 6 講說的 approximation gap。

出處:Kingma & Welling (2019), §3.3 "Inverse Autoregressive Transformations"、§3.4 "Inverse Autoregressive Flow (IAF)" 與 Algorithm 3。

Demo BMAF vs. IAF:需要幾個依序步驟?

12 維的例子。每一「輪」可以平行算出所有已經具備輸入的位置;顏色表示該位置在第幾輪完成。綠色是一開始就已知的量。

06Parallel WaveNet:probability density distillation(投影片 23–25)

WaveNet(第 1、3 講)是很好的語音 autoregressive model,但逐個樣本點生成太慢,無法上線。Parallel WaveNet 的作法是用老師和學生兩階段訓練:66:06

  1. 老師是 MAF(就是一個 autoregressive model):可以有效地用 MLE 訓練。
  2. 學生是 IAF:不能有效算外部資料點的密度,但能快速取樣。
  3. 關鍵觀察:IAF 能有效算自己生成的樣本的密度(cache 住雜訊 \(z_1,\dots,z_n\))。
PROBABILITY DENSITY DISTILLATION $$D_{\mathrm{KL}}(s\Vert t) = \mathbb E_{\mathbf x\sim s}\big[\log s(\mathbf x) - \log t(\mathbf x)\big]$$ 用 Monte Carlo 估計並最佳化,需要:
  1. 從學生(IAF)取樣 \(\mathbf x\):快。
  2. 學生給 \(\mathbf x\) 的密度:是自己的樣本,快。
  3. 老師(MAF)給 \(\mathbf x\) 的密度:MAF 算 likelihood 快。

三者都能有效實作。方向很重要:用的是 \(D_{\mathrm{KL}}(s\Vert t)\),期望對學生取。反方向 \(D_{\mathrm{KL}}(t\Vert s)\) 需要從老師取樣(慢)、再算學生在外部點的密度(也慢),兩樣都是弱點。67:43

整體流程:(1) 用 MLE 訓練老師 MAF;(2) 訓練學生 IAF 最小化和老師的 KL;(3) 測試時丟掉老師,只用學生。老師說這樣取樣快得多,能放上手機等產品。論文摘要的說法是:生成高品質語音比即時快 20 倍以上,並已部署在 Google Assistant(英文和日文語音)。69:46

課堂問答 · 70:20怎麼對學生的參數求梯度?學生的取樣就是「從簡單雜訊出發、做確定性變換」,整個就是一個大的 reparameterization trick(第 6 講),可以直接 backprop。老師 \(t\) 固定不動。70:20
課堂問答 · 71:57語言模型能這樣蒸餾嗎?很可惜不行。文字是離散的,不能把取樣看成「把連續分佈做可微、可逆的變換」,變數變換公式只適用於機率密度,不適用於離散的機率質量。71:57
這個 KL 方向的副作用:mode-seeking

\(D_{\mathrm{KL}}(s\Vert t)\) 是第 4 講的 reverse KL,學生會傾向 mode-seeking:集中在老師的高機率區域,可能忽略老師的某些模式。對語音生成來說,「每個樣本都要像真的」比「涵蓋所有可能」重要,所以這個副作用可以接受。第 7 講 Demo C 的 planar flow 用的是同一種目標,也看得到它只抓住一個 mode。(Parallel WaveNet 論文還加了其他輔助損失來改善品質,這裡不展開。)

07MintNet:用遮罩卷積做可逆 CNN(投影片 26–28)

一般的 CNN 表達力強,但不可逆、Jacobian 行列式也貴。作法和 PixelCNN 一樣:73:31

  • 用遮罩卷積強制一個順序,讓每個輸出只看順序上之前的輸入(也包括通道之間的順序,例如先 R 再 G 再 B)。
  • 因為有順序,Jacobian 是三角的,行列式是對角線乘積,很好算。
  • 若 Jacobian 的對角線元素全部(嚴格)為正,這個變換就是可逆的。

投影片 27 的圖:三個 3×3 卷積濾波器,畫成立方體。實心的棋盤格小方塊是未遮罩的權重,透明藍色方塊是被遮掉的權重。每個濾波器下方用花紋標出它在輸入特徵圖上的感受野:只涵蓋當前位置之前的像素,以及順序在前的通道。投影片 28 是 MintNet 在 MNIST、CIFAR-10、ImageNet 32×32 上未經挑選的樣本。75:09

代價:感受野受限,不能看整張圖。好處:Jacobian 好算。76:11

另一條路:residual flow(投影片 9 的 i-ResNet)

另一種設計是 \(f(\mathbf z) = \mathbf z + \mathbf v(\mathbf z)\),只要 \(\mathbf v\) 是收縮的(Lipschitz 常數 < 1),由 Banach 不動點定理保證可逆,反函數可以用迭代 \(\mathbf z\leftarrow\mathbf x - \mathbf v(\mathbf z)\) 求出。log 行列式用 \(\log\det(I+J_{\mathbf v}) = \mathrm{tr}\log(I+J_{\mathbf v})\) 展開成冪級數,再用隨機的 trace 估計量(Hutchinson)近似。

Lai 等人的書把它當成通往 Neural ODE 的橋樑:把每層寫成很小的殘差更新 \(\mathbf x_{k+1} = \mathbf x_k + \Delta t\,\mathbf v(\mathbf x_k,t_k)\),層數趨於無限就變成常微分方程 \(d\mathbf x/dt = \mathbf v(\mathbf x,t)\),也就是連續時間的 flow。這就是後面 diffusion model 的 probability flow ODE、以及 flow matching 的起點。

出處:Lai et al. (2026), §5.1.1「Normalizing Flows」中的「Residual Flows」小段,以及 §5.1.2「Neural ODEs」(檔名 Chapter-4)。

08Gaussianization flow(投影片 29–34)

換個角度看 flow 的訓練

令 \(X = f_\theta(Z)\),\(Z\sim\mathcal N(0,I)\),\(\tilde X\sim p_{\text{data}}\) 是真實資料。MLE 最小化 \(D_{\mathrm{KL}}(p_{\text{data}}\Vert p_\theta) = D_{\mathrm{KL}}(p_{\tilde X}\Vert p_X)\):高斯樣本經過 \(f_\theta\) 要像資料。可以證明77:16

$$D_{\mathrm{KL}}\big(p_{\tilde X}\Vert p_X\big) = D_{\mathrm{KL}}\big(p_{f_\theta^{-1}(\tilde X)}\Vert p_{f_\theta^{-1}(X)}\big) = D_{\mathrm{KL}}\big(p_{f_\theta^{-1}(\tilde X)}\Vert p_Z\big)$$

也就是說,等價地,資料經過 \(f_\theta^{-1}\) 要變成高斯。訓練 flow 就是在 Gaussianize 資料。79:50

為什麼 KL 在可逆變換下不變?

設 \(g\) 可逆,\(P,Q\) 兩個分佈經 \(g\) 變換後是 \(P',Q'\)。由變數變換,\(p'(\mathbf y) = p(g^{-1}(\mathbf y))|\det J_{g^{-1}}(\mathbf y)|\),\(q'\) 也乘上同一個行列式。所以在比值中它約掉了:

$$\frac{p'(\mathbf y)}{q'(\mathbf y)} = \frac{p(g^{-1}(\mathbf y))}{q(g^{-1}(\mathbf y))}$$

再把 \(\mathbb E_{\mathbf y\sim P'}\) 換回 \(\mathbb E_{\mathbf x\sim P}\)(\(\mathbf y = g(\mathbf x)\)),就得到 \(D_{\mathrm{KL}}(P'\Vert Q') = D_{\mathrm{KL}}(P\Vert Q)\)。直覺:可逆變換只是換座標,不增加也不減少兩個分佈之間的差異。

一維:反 CDF 技巧

資料 \(\tilde X\) 的 CDF 是 \(F_{\text{data}}(a) = \int_{-\infty}^a p_{\text{data}}\)。80:21

  • 反 CDF 取樣:若 \(U\sim U[0,1]\),則 \(F_{\text{data}}^{-1}(U)\sim p_{\text{data}}\)。
  • 反過來,\(U = F_{\text{data}}(\tilde X)\) 是均勻分佈。
  • 再用高斯的反 CDF:\(\Phi^{-1}(U) = \Phi^{-1}(F_{\text{data}}(\tilde X))\) 就是標準高斯。
一維 GAUSSIANIZATION可逆變換 \(\Phi^{-1}\circ F_{\text{data}}\) 把任何一維連續資料變成標準高斯。

投影片 30 的圖:三個並排的小圖。左邊是資料分佈(一個不規則的、偏斜的密度),中間是它的 CDF(從 0 漸升到 1 的 S 形曲線,標著「近似 CDF」),右邊是經過高斯反 CDF 後得到的鐘形輸出。

多維:逐維 Gaussianize,再旋轉,重複

  1. 逐維 Gaussianization:對每一維各自做上面的一維轉換。Jacobian 是對角的,好算。注意:每一維的邊際變成高斯,但聯合分佈不一定是高斯。如果到此為止、直接用高斯先驗近似,就是一個淺層的 flow,叫 copula model(Sklar 1959),華爾街常用。81:54
  2. 旋轉:乘一個正交矩陣。Jacobian 是正交矩陣,\(|\det| = 1\)。\(\mathcal N(0,I)\) 是旋轉不變的,所以如果已經是高斯,旋轉不會破壞它;如果還不是,旋轉會把「不高斯」的結構混到各個座標軸上,下一次逐維 Gaussianization 才處理得到。
  3. 重複 1、2:疊起來就是 Gaussianization flow(可學的 Gaussian copula 的堆疊)。

投影片 31–34 的圖:一團彎曲的二維藍色點雲,兩軸各畫著它的邊際分佈。逐維 Gaussianization 後,兩個邊際都變成鐘形,但點雲仍是彎的;旋轉之後形狀轉了一個角度;投影片 33 是 3×5 的小圖序列,重複多次後點雲逐漸變成一團圓形的高斯。投影片 34 比較二維密度估計:第一列是資料(各種條紋、棋盤格等圖案),第二列是 Glow 的樣本,第三列是 Gaussianization flow 的樣本,GF 對棋盤格等不連續的圖案還原得比較好。

Demo CGaussianization:一維與二維

一維:資料 → CDF → 均勻 → Φ⁻¹ → 高斯

資料 x̃(雙峰、偏斜)
u = F_data(x̃):均勻
Φ⁻¹(u):標準高斯

二維:逐維 Gaussianize + 隨機旋轉

非高斯程度(越小越像高斯)

二維部分的「逐維 Gaussianize」用的是經驗 CDF(每一維依排名換成高斯分位數),所以每一步之後兩軸的邊際都是完美的高斯,但點雲的形狀不是。旋轉後再 Gaussianize,彎曲的結構一點一點被拉直,大約 10–20 步後就變成一團圓形。實測三種資料的非高斯程度:起點 0.14–0.22,20 步後約 0.01–0.02(旋轉是隨機的,每次略有不同)。「非高斯程度」是沿許多隨機方向投影後,和標準高斯分位數的平均差距。逐維 Gaussianization 本身只保證兩個軸方向是高斯,斜的方向要靠旋轉才會改善。

09總結與比較(投影片 35)

  • 用變數變換把簡單分佈轉成複雜分佈。
  • 變換的 Jacobian 行列式要好算,學習和密度估計才有效率。
  • 正向與反向的計算成本有取捨。
Flow每層做什麼log |det J|取樣算 likelihood
Planar(第 7 講)\(\mathbf z + \mathbf u\,h(\mathbf w^\top\mathbf z+b)\)\(\log|1+h'\mathbf u^\top\mathbf w|\)快需要數值反解
NICE一半不動、另一半加平移0(加最後的縮放)快快
RealNVP / Glow一半不動、另一半平移加縮放\(\sum\alpha_\theta\)快快
MAFautoregressive 平移縮放(依賴 \(\mathbf x_{<i}\))\(\sum\alpha_i\)慢(n 步)快
IAFautoregressive 平移縮放(依賴 \(\mathbf z_{<i}\))\(\sum\alpha_i\)快慢(自己樣本則快)
MintNet遮罩卷積三角 Jacobian 對角線需要迭代反解快
Gaussianization逐維 CDF 轉換 + 旋轉對角 + 0需要反 CDF快

Coupling 層可以看成 autoregressive flow 的特例:只分兩組,第二組一次全部依賴第一組。因此兩個方向都只要一步,代價是每層只改動一半的變數,需要疊更多層。

常見誤解

誤解:「coupling layer 裡的 μ 和 α 網路必須可逆」。不用。反轉時只要用沒被改動的那一半重新算一次,它們可以是任意網路。
誤解:「NICE 每層 det = 1,所以整個模型不能改變密度」。加法 coupling 會移動、剪切機率質量;而且 NICE 最後有縮放層。只是它不能局部地壓縮或拉伸。
誤解:「IAF 不能算 likelihood」。能算,只是對外部資料點要依序反推、很慢。對自己的樣本(有 cache 的 z)一樣快。
誤解:「MAF 和 IAF 是兩種不同的模型家族」。它們是同一種可逆網路,用在相反的方向。
誤解:「Parallel WaveNet 的方法可以直接用在 LLM 上」。文字是離散的,沒有變數變換公式,不能這樣蒸餾。
誤解:「每一維都是高斯,整體就是高斯」。邊際高斯不代表聯合高斯(copula 正是利用這點)。所以 Gaussianization 需要旋轉後再重複。

自我測驗

1. 寫出 NICE 加法 coupling 的正向、反向與 det J。
正向:\(\mathbf x_{1:d} = \mathbf z_{1:d}\),\(\mathbf x_{d+1:n} = \mathbf z_{d+1:n} + m_\theta(\mathbf z_{1:d})\)。反向:\(\mathbf z_{d+1:n} = \mathbf x_{d+1:n} - m_\theta(\mathbf x_{1:d})\)。Jacobian 是對角線全為 1 的下三角矩陣,det = 1。
2. RealNVP 一層的 log|det J| 是什麼?為什麼不用算矩陣行列式?
\(\sum_{i=d+1}^n\alpha_\theta(\mathbf z_{1:d})_i\)。Jacobian 是下三角的,對角線是 \(I_d\) 和 \(\mathrm{diag}(\exp\alpha_\theta)\),行列式就是對角線乘積。
3. 為什麼 coupling 層要交替分組?
同一組變數若永遠原樣通過,就永遠不會被變換。交替讓每個變數都有機會被平移和縮放。Glow 用可學的 1×1 卷積推廣了這個「重新排列」。
4. 把 Gaussian autoregressive model 寫成 flow:正向和反向各是什麼?
正向(取樣):\(x_i = \exp(\alpha_i(\mathbf x_{<i}))z_i + \mu_i(\mathbf x_{<i})\),依序。反向(likelihood):\(z_i = (x_i - \mu_i(\mathbf x_{<i}))\exp(-\alpha_i(\mathbf x_{<i}))\),所有 i 可平行。
5. MAF 的取樣為什麼慢?算 likelihood 為什麼快?
取樣時 \(\mu_i,\alpha_i\) 依賴還沒生成的 \(\mathbf x_{<i}\),必須 n 步依序。算 likelihood 時整個 \(\mathbf x\) 已知,所有 \(\mu_i,\alpha_i\) 一次平行算出(例如 MADE)。
6. IAF 為什麼能快速算「自己樣本」的 likelihood?
自己生成時已經有 \(z_1,\dots,z_n\),\(\mu_i(\mathbf z_{<i}),\alpha_i(\mathbf z_{<i})\) 也都算過了。log p = \(\sum_i[\log\mathcal N(z_i) - \alpha_i]\),直接用 cache 的值,不需要依序反推。
7. Parallel WaveNet 為什麼用 KL(s‖t) 而不是 KL(t‖s)?
KL(s‖t) 需要:從學生取樣(IAF 快)、學生在自己樣本上的密度(快)、老師在這些點上的密度(MAF 快)。KL(t‖s) 需要從老師取樣(MAF 慢)和學生在外部點的密度(IAF 慢),全是弱點。
8. MintNet 怎麼保證可逆、行列式好算?
遮罩卷積強制順序,使 Jacobian 為三角矩陣,行列式 = 對角線乘積;只要對角線元素嚴格為正,變換就可逆。
9. 證明 KL 在可逆變換下不變。
兩個密度變換後都乘上同一個 \(|\det J_{g^{-1}}|\),比值不變;再把期望換回原變數,KL 不變。
10. 一維情況下,哪個可逆變換能把任意連續資料變成標準高斯?
\(\Phi^{-1}\circ F_{\text{data}}\):先用資料的 CDF 變成均勻,再用標準高斯的反 CDF 變成高斯。
11. 逐維 Gaussianization 之後為什麼還需要旋轉?
逐維只保證每一維的邊際是高斯,聯合分佈仍可能有彎曲、相關的結構。旋轉把這些結構混到座標軸方向,下一次逐維 Gaussianization 才能處理。高斯是旋轉不變的,所以已經 Gaussian 的部分不會被破壞。
12. 為什麼說 coupling layer 是 autoregressive flow 的特例?代價是什麼?
它相當於只有兩個「區塊」的 autoregressive 順序:第一組不動、第二組依賴第一組。所以正反向都只要一步。代價是每層只變換一半的變數,需要疊更多層才有足夠的表達力。

延伸閱讀