CS236 第 7 講 · Normalizing Flows
Stanford CS236 · Fall 2023 · Lecture 7

Normalizing Flows:可逆變換與變數變換公式

VAE 有潛在變數但算不出 likelihood;autoregressive model 算得出 likelihood 但沒有潛在變數。Flow 兩者兼得:把 VAE 的 \(p(\mathbf x\mid\mathbf z)\) 換成一個確定性、可逆的函數 \(\mathbf x = f_\theta(\mathbf z)\)。給定 \(\mathbf x\) 只有一個 \(\mathbf z\),不用再列舉或猜測,likelihood 就由變數變換公式精確算出:\(p_X(\mathbf x) = p_Z(f^{-1}(\mathbf x))\,\big|\det\frac{\partial f^{-1}(\mathbf x)}{\partial\mathbf x}\big|\)。這講的前半先把 VAE 的 autoencoder 觀點收尾。

讀完這頁你應該能夠

  1. 說明 VAE 的 KL 項為什麼讓它能當生成模型,以及 posterior collapse 是什麼。
  2. 說出 flow 和 VAE 的差別:確定性、可逆、\(\mathbf z\) 和 \(\mathbf x\) 同維度。
  3. 推導一維的變數變換公式,並說明為什麼「直接代入」會錯。
  4. 用平行四邊形面積解釋為什麼要乘上 \(|\det|\),以及 \(\det(A^{-1}) = 1/\det A\)。
  5. 寫出多維變數變換公式的兩種形式(用逆映射的 Jacobian,或用正向映射的 Jacobian 取倒數)。
  6. 說明 flow 的三個需求:容易取樣的先驗、容易正反算的變換、容易算的 Jacobian 行列式(例如三角矩陣)。

前置知識檢查

  • CDF 和 PDF 的關係 \(p_X = F_X'\)(B2 補充)
  • 一元微積分的 chain rule、反函數的導數
  • 2×2 矩陣的行列式 \(ad - bc\)、矩陣乘法(B3 補充會講幾何意義)
  • 偏導數與 Jacobian 矩陣(B4 補充)
  • 第 6 講:VAE 的 ELBO = 重建 − KL;reparameterization 的 \(\log q(\mathbf z) = \log p(\boldsymbol\epsilon) - \log|\det\partial\mathbf z/\partial\boldsymbol\epsilon|\)(這講會解釋它的由來)

本頁對照過投影片圖片;標「出處」的補充來自 Lilian Weng〈Flow-based Deep Generative Models〉、Lai, Song, Kim, Mitsufuji & Ermon The Principles of Diffusion Models(arXiv 2510.21890v3)附錄 B、Kingma & Welling (2019)。

Part A · 00:00–34:28

第 6 講最後沒講完的「autoencoder 觀點」(第 6 講投影片 20–21)。ELBO = 重建 − KL 的推導和 Alice / Bob 的故事已寫在第 6 講第 9 節,這裡整理課堂上大量的問答。

A1Autoencoder 觀點的課堂問答

$$\mathcal L(\mathbf x;\theta,\boldsymbol\phi) = \underbrace{\mathbb E_{q_{\boldsymbol\phi}(\mathbf z\mid\mathbf x)}\big[\log p(\mathbf x\mid\mathbf z;\theta)\big]}_{\text{autoencoding(重建)}} - \underbrace{D_{\mathrm{KL}}\big(q_{\boldsymbol\phi}(\mathbf z\mid\mathbf x)\Vert p(\mathbf z)\big)}_{\text{把潛在碼拉向先驗}}$$

只有第一項時,它是一個隨機的 autoencoder:把輸入映射到潛在變數上的一個分佈,從中抽出的 \(\mathbf z\) 要能重建輸入。普通 autoencoder 則是把輸入確定性地映射到一個向量。07:19加上第二項,潛在碼的分佈要像 \(p(\mathbf z)\)。生成時就可以自己從 \(p(\mathbf z)\) 抽 \(\mathbf z\)「騙」decoder,因為它訓練時看到的 \(\mathbf z\) 就長這樣。09:59

關於 KL 項

  • 為什麼是拉近 \(q(\mathbf z\mid\mathbf x)\) 和 \(p(\mathbf z)\),而不是拉近「所有資料的 \(q\) 合起來的邊際分佈」和 \(p(\mathbf z)\)?後者其實是很合理的目標,但算不出來,又會變成一個難解的積分。也有其他方法可以達成類似效果,例如用 discriminator,VAE 的做法只是其中一種。14:30
  • 這樣不會讓每個 \(\mathbf x\) 的 encoder 輸出都一樣嗎?會有這股力量,這是很強的正則化。但重建項會反過來逼 encoder 給不同輸入不同的表示,兩項互相拉扯,訓練找的是最好的折衷。19:11
  • 為什麼叫「損失」,它不是 log-likelihood 嗎?如果 \(p(\mathbf x\mid\mathbf z)\) 是高斯,\(-\log p\) 就是輸入和輸出之間的 L2 距離,所以是 autoencoding loss。真正最佳化的是整個 ELBO = 重建 + 正則化。18:07
  • 怎麼算這個 KL?它只是把 ELBO 換個寫法,原本的形式每一項都算得出來。對角高斯對標準高斯的 KL 還有公式解(第 6 講補充框)。29:13

Posterior collapse 與 mutual information

課堂問答 · 22:53如果近似後驗太接近先驗,就是在忽略 \(\mathbf x\):\(\mathbf z\) 和 \(\mathbf x\) 之間沒有 mutual information,學不到表示。什麼時候會發生?當 \(p(\mathbf x\mid\mathbf z)\) 本身已經很強(例如一個 autoregressive model),它不需要混合多個成分就能擬合資料,\(\mathbf z\) 就沒用了。避免方法之一是用簡單的 \(p(\mathbf x\mid\mathbf z)\),逼模型使用 \(\mathbf z\)。也有 ELBO 的變體可以增加或減少 mutual information。減少的情況是:你不希望表示捕捉到敏感屬性。22:53
Mutual information 是什麼?和 KL 項有什麼關係?

兩個隨機變數的 mutual information(互資訊)衡量「知道其中一個,能減少多少對另一個的不確定性」:

$$I(\mathbf x;\mathbf z) = D_{\mathrm{KL}}\big(p(\mathbf x,\mathbf z)\Vert p(\mathbf x)p(\mathbf z)\big) = H(\mathbf z) - H(\mathbf z\mid\mathbf x) \ge 0$$

獨立時為 0。在 VAE 中,把 KL 項對資料取平均,可以拆成

$$\mathbb E_{p_{\text{data}}(\mathbf x)}\big[D_{\mathrm{KL}}(q(\mathbf z\mid\mathbf x)\Vert p(\mathbf z))\big] = I_q(\mathbf x;\mathbf z) + D_{\mathrm{KL}}\big(q(\mathbf z)\Vert p(\mathbf z)\big)$$

其中 \(q(\mathbf z) = \mathbb E_{p_{\text{data}}}[q(\mathbf z\mid\mathbf x)]\) 是「所有資料的 \(q\) 合起來」的 aggregate posterior。所以 VAE 的 KL 項同時在做兩件事:壓低 \(\mathbf x\) 和 \(\mathbf z\) 的互資訊(這是 posterior collapse 的來源),以及讓 aggregate posterior 像先驗(這才是生成需要的)。上面「為什麼不直接拉近邊際分佈」那個問題,問的就是只保留第二項。

推導:把 \(\log\frac{q(\mathbf z\mid\mathbf x)}{p(\mathbf z)} = \log\frac{q(\mathbf z\mid\mathbf x)}{q(\mathbf z)} + \log\frac{q(\mathbf z)}{p(\mathbf z)}\) 對 \(p_{\text{data}}(\mathbf x)q(\mathbf z\mid\mathbf x)\) 取期望即可。這個拆解出自 Hoffman & Johnson (2016)〈ELBO surgery: yet another way to carve up the variational evidence lower bound〉(PDF)。論文把第二項叫 marginal KL。他們在二值化 MNIST 上實測:維度夠大時,互資訊項接近上限 \(\log N\),代表各資料點的 \(q(\mathbf z\mid\mathbf x)\) 幾乎不重疊;marginal KL 原則上可以很小,實際上卻明顯拉低了 ELBO,表示 encoder 很難讓 aggregate posterior 對上先驗。

Alice 和 Bob 的補充

如果 \(\mathbf z\) 只有 1 個 bit,Alice 只能送 0 或 1。最好的策略是把影像分成兩群,一群送 0、另一群送 1。重建誤差小,就會逼模型發現精簡的特徵,例如「一隻狗、拿著飛盤、在草地上」。KL 小,代表 Bob 能自己從先驗抽出「看起來像 Alice 送的」訊息來生成影像。26:31

其他問答

  • 生成時怎麼取樣?不用 encoder:從先驗抽 \(\mathbf z\),送進 decoder。等於從計算圖的「中間」開始。21:47
  • 資料不是高斯(例如尾巴很厚的金融資料)怎麼辦?高斯只是最簡單的選擇。如果真實後驗不是高斯,就用更有彈性的 \(q\),或重尾分佈。理解 ELBO 的推導就知道什麼行得通。17:07
  • 為什麼不直接從雜訊開始重建?那就退回第 5 講的「從先驗亂猜 \(\mathbf z\)」,大多數猜測和 \(\mathbf x\) 不一致。19:43
  • 訓練時要取最可能的 \(\mathbf z\) 嗎?不要。從 ELBO 的推導來看,要依 \(q\) 抽樣,因為可能有很多合理的補法,要全部涵蓋。多抽幾個樣本可以讓期望的估計更準,但比較貴,實務上常只抽一個。31:49
  • 資料不平衡(1000 隻狗、5 隻貓)?模型在乎的是整體平均表現,常見的類別會被編碼得比較好。想強調某些語意特徵,可以改重建損失(不用單純的 L2),或用有標籤的資料引導 \(\mathbf z\)。29:44
  • 能用模型生成的資料擴充訓練集嗎?有人在研究,也有理論結果顯示在某些假設下,反覆用合成資料訓練會發散(「generative models going mad」)。但那些假設在實務上不一定成立。33:25

「going mad」指的是 Alemohammad et al. (2023)〈Self-Consuming Generative Models Go MAD〉(arXiv 2307.01850),已核對標題。

Part B · 34:28–83:02

本講投影片 1–12。投影片 13–19 時間不夠沒講,整理在 B6,下一講會接續。

B1動機:一個 likelihood 算得出來的潛在變數模型

AutoregressiveVAEFlow
\(p_\theta(\mathbf x)\)\(\prod_i p_\theta(x_i\mid\mathbf x_{<i})\),精確\(\int p_\theta(\mathbf x,\mathbf z)d\mathbf z\),算不出來,用 ELBO變數變換公式,精確
特徵(潛在變數)沒有有 \(\mathbf z\)有 \(\mathbf z = f^{-1}(\mathbf x)\),不需要 encoder
生成逐步一次一次

關鍵問題:能不能設計一個 likelihood 可算的潛在變數模型?可以。35:31

我們想要的模型分佈 \(p_\theta(\mathbf x)\) 有兩個性質:容易算密度(訓練用)、容易取樣(生成用)。高斯、均勻分佈都滿足,但資料分佈複雜得多,是多峰的。

投影片 3 的圖:兩個簡單的熱度圖,一個是中心最亮、向外漸暗的高斯,一個是整片均勻的方塊。下方是資料分佈:一張有好幾團亮點、彼此之間是暗區的多峰熱度圖。37:06

FLOW 的核心想法用可逆變換,把簡單分佈(容易取樣、容易算密度)映射成複雜分佈。

從 VAE 出發(投影片 4)

  1. 從簡單先驗開始:\(\mathbf z\sim\mathcal N(0,I) = p(\mathbf z)\)。
  2. VAE 用 \(p(\mathbf x\mid\mathbf z) = \mathcal N(\boldsymbol\mu_\theta(\mathbf z),\Sigma_\theta(\mathbf z))\) 轉換。
  3. \(p(\mathbf z)\) 簡單但邊際 \(p_\theta(\mathbf x)\) 很有彈性;可惜 \(\int p_\theta(\mathbf x,\mathbf z)d\mathbf z\) 很貴,要列舉所有可能產生 \(\mathbf x\) 的 \(\mathbf z\)。
  4. 如果設計上就能輕易「反轉」\(p(\mathbf x\mid\mathbf z)\)、算出 \(p(\mathbf z\mid\mathbf x)\) 呢?讓 \(\mathbf x = f_\theta(\mathbf z)\) 是 \(\mathbf z\) 的確定性、可逆函數。這樣任何 \(\mathbf x\) 都只對應唯一一個 \(\mathbf z\),不必列舉。40:14

代價:要可逆,\(\mathbf z\) 和 \(\mathbf x\) 必須同維度,不再有「壓縮表示」的概念。41:16

B2一維變數變換

複習:CDF、PDF(投影片 5)

連續隨機變數 \(X\) 的 CDF(累積分佈函數)是 \(F_X(a) = P(X\le a)\),PDF(機率密度函數)是它的導數 \(p_X(a) = F_X'(a)\)。通常用參數化的密度描述,例如高斯 \(p_X(x) = \frac{1}{\sigma\sqrt{2\pi}}e^{-(x-\mu)^2/2\sigma^2}\)、均勻 \(p_X(x) = \frac{1}{b-a}\mathbf 1[a\le x\le b]\),多維則用聯合 PDF。這些簡單分佈的形狀只由少數參數決定,表達力很有限。42:16

直接代入是錯的(投影片 6)

\(Z\sim U[0,2]\),所以 \(p_Z(1) = 1/2\)(檢查:\(\int_0^2\frac12 = 1\))。令 \(X = 4Z\),\(p_X(4)\) 是多少?44:55

$$p_X(4) \overset{?}{=} p(X=4) = p(4Z=4) = p(Z=1) = p_Z(1) = 1/2 \qquad\textbf{錯!}$$

顯然 \(X\) 是 \([0,8]\) 上的均勻分佈,所以 \(p_X(4) = 1/8\)。錯在把密度當成機率:「\(p(X=4)\)」對連續變數沒有意義(是 0),密度是「每單位長度」的機率。把區間拉長 4 倍,每單位長度的機率就變成 1/4。

變數變換公式(投影片 7–8)

一維若 \(X = f(Z)\),\(f\) 單調,反函數 \(Z = f^{-1}(X) = h(X)\),則 $$p_X(x) = p_Z(h(x))\,|h'(x)| \qquad\text{等價地}\qquad p_X(x) = p_Z(z)\,\frac{1}{|f'(z)|},\quad z = h(x)$$
  • 剛才的例子:\(h(x) = x/4\),\(p_X(4) = p_Z(1)\,|h'(4)| = \frac12\times\frac14 = \frac18\)。「直接代入」的 \(p_Z(1)\) 只差了 \(|h'|\) 這個縮放因子。46:27
  • 更有趣的:\(X = e^Z\),\(Z\sim U[0,2]\)。\(h(x) = \ln x\),\(p_X(x) = p_Z(\ln x)\,|1/x| = \frac{1}{2x}\),\(x\in[1, e^2]\)。從一個常數密度,變成了形狀 \(1/x\) 的密度:變換改變了分佈的形狀。48:36
證明:從 CDF 出發(投影片 8)

設 \(f\) 遞增(遞減時同理,會多一個負號,所以要加絕對值)。

$$F_X(x) = P[X\le x] = P[f(Z)\le x] = P[Z\le h(x)] = F_Z(h(x))$$

第三個等號用了「\(f\) 遞增,所以兩邊同時套 \(h\) 不改變不等號」。兩邊對 \(x\) 微分,用 chain rule:

$$p_X(x) = \frac{dF_X(x)}{dx} = \frac{dF_Z(h(x))}{dx} = p_Z(h(x))\,h'(x)$$

反函數的導數:\(h'(x) = [f^{-1}]'(x) = \dfrac{1}{f'(f^{-1}(x))}\)。直覺:如果 \(f\) 在某處把長度拉長 3 倍,\(f^{-1}\) 在對應處就縮短成 1/3。所以兩種寫法等價:用逆映射的導數相乘,或用正向映射的導數相除。52:50

為什麼 \(f'\) 不能是 0?\(f'=0\) 的地方,函數在局部是平的,不同的 \(z\) 被壓到同一點,不再可逆,公式會除以 0。54:25

另一個直覺:機率質量守恆

一小段區間 \([z, z+\Delta z]\) 裡的機率約是 \(p_Z(z)\Delta z\)。這段區間被 \(f\) 映射成長度 \(\Delta x\approx|f'(z)|\Delta z\) 的區間,而裡面的機率不會憑空增減:

$$p_X(x)\,\Delta x = p_Z(z)\,\Delta z \quad\Longrightarrow\quad p_X(x) = p_Z(z)\left|\frac{\Delta z}{\Delta x}\right| = \frac{p_Z(z)}{|f'(z)|}$$

區間被拉長的地方密度變稀,被壓縮的地方密度變濃。Lilian Weng 的文章把 \(|(f^{-1})'(x)|\) 描述成兩個座標系下無限細的矩形面積比;Lai 等人的書則強調「機率質量守恆,所以密度要用體積變化的倒數補償」。

出處:Lilian Weng,〈Flow-based Deep Generative Models〉"Change of Variable Theorem";Lai et al. (2026) 附錄 B §B.1。

延伸 補充課 C §3 變數變換 = 質量守恆:用等機率色帶看密度為什麼要除以 |T′|

Demo A一維變數變換:公式 vs. 直方圖

從 \(Z\) 抽 20,000 個樣本,算 \(X = f(Z)\) 的直方圖(灰),和變數變換公式算出的 \(p_X\)(藍)比較。橘色虛線是忘了乘 \(|h'(x)|\) 的錯誤公式。

p_Z(z)
x = f(z)
p_X(x)
樣本直方圖p_Z(h(x)) |h′(x)|錯誤:p_Z(h(x))探針

移動探針,看三個數字:\(z = h(x)\)、\(p_Z(z)\)、縮放因子 \(|h'(x)|\)。中間的圖裡,\(f\) 越陡的地方(\(f'\) 大),\(x\) 方向被拉長,密度變稀。sigmoid 把整條實數線壓進 \((0,1)\),兩端被極度壓縮,密度在 0 和 1 附近堆高,這是高斯經過 sigmoid 的常見現象。

B3線性變換與行列式

先看線性情況:\(Z\) 在單位超立方體 \([0,1]^n\) 上均勻分佈,\(X = AZ\),\(A\) 是可逆方陣,反矩陣 \(W = A^{-1}\)。\(X\) 是什麼分佈?54:55

幾何上,\(A\) 把單位超立方體映射成一個平行多面體(parallelotope,平行四邊形的高維推廣)。

投影片 9 的圖:左邊是綠色的單位正方形,四角 (0,0)、(1,0)、(0,1)、(1,1);右邊是紅色的平行四邊形,四角是 (0,0)、(a,b)、(c,d)、(a+c,b+d)。也就是把四個角分別乘上 \(A = \begin{pmatrix}a&c\\b&d\end{pmatrix}\)。56:30

\(X\) 在這個平行四邊形上均勻分佈。平行四邊形的面積是 \(|\det A| = |ad - bc|\)(投影片 10 用一個大矩形減掉周圍幾塊三角形和矩形證明)。所以58:33

線性 $$p_X(\mathbf x) = \frac{p_Z(W\mathbf x)}{|\det A|} = p_Z(W\mathbf x)\,|\det W|,\qquad \det W = \det(A^{-1}) = \frac{1}{\det A}$$ 和一維公式 \(p_Z(h(x))|h'(x)|\) 完全對應:\(W\) 是逆映射,\(|\det W|\) 是它的「導數」。
  • 這個公式不限於均勻分佈,任何 \(p_Z\) 都適用(例如高斯)。61:06
  • 為什麼叫 normalizing flow?除以行列式正是為了讓結果保持正規化(積分為 1):面積放大多少,密度就降多少。63:40
行列式的幾何意義與四個好用的性質

\(|\det A|\) 是 \(A\) 把單位體積放大的倍數;\(\det A\) 的正負號表示方向是否被翻轉(鏡射)。\(\det A = 0\) 代表某個方向被壓扁成 0,不可逆。

  1. \(\det(AB) = \det A\cdot\det B\):先放大 \(\det B\) 倍、再放大 \(\det A\) 倍。這讓多層 flow 的 log 行列式可以相加。
  2. \(\det(A^{-1}) = 1/\det A\):因為 \(\det A\cdot\det A^{-1} = \det I = 1\)。
  3. 三角矩陣(上三角或下三角)的行列式 = 對角線元素的乘積,只要 \(O(n)\)。一般矩陣要 \(O(n^3)\)。這是 flow 設計的關鍵(B6)。
  4. 對角矩陣 \(\mathrm{diag}(\sigma_1,\dots,\sigma_n)\) 的行列式是 \(\prod_i\sigma_i\):每個軸各自縮放。第 6 講 reparameterization 的 \(\mathbf z = \boldsymbol\mu + \boldsymbol\sigma\odot\boldsymbol\epsilon\) 就是這個情況,所以 \(\log q(\mathbf z) = \log p(\boldsymbol\epsilon) - \sum_i\log\sigma_i\)。

延伸 補充課 A §4 行列式與特徵值:行列式就是面積的縮放

Demo B正方形變平行四邊形

1,500 個點在單位正方形(綠)中均勻分佈,乘上 \(A\) 之後在平行四邊形(紅)中仍然均勻,只是更稀或更密。剪切的行列式是 1:形狀變了,面積和密度都不變。鏡射的行列式是 −1:方向翻轉,面積不變。退化的行列式是 0:整片被壓成一條線,無法反轉,密度沒有定義。

B4非線性:Jacobian 行列式

線性變換的體積變化是 \(\det A\);非線性變換在每一點附近局部線性化(一階 Taylor 展開),局部的體積變化就是 Jacobian 矩陣的行列式。65:45

一般情況(投影片 11)\(f:\mathbb R^n\to\mathbb R^n\) 可逆,\(X = f(Z)\),\(Z = f^{-1}(X)\): $$p_X(\mathbf x) = p_Z\big(f^{-1}(\mathbf x)\big)\left|\det\left(\frac{\partial f^{-1}(\mathbf x)}{\partial\mathbf x}\right)\right| = p_Z(\mathbf z)\left|\det\left(\frac{\partial f(\mathbf z)}{\partial\mathbf z}\right)\right|^{-1},\quad\mathbf z = f^{-1}(\mathbf x)$$
  • 注意 0:它推廣了一維的 \(p_X(x) = p_Z(h(x))|h'(x)|\)。
  • 注意 1:和 VAE 不同,\(\mathbf x\)、\(\mathbf z\) 必須是連續的而且同維度。
  • 注意 2:任何可逆矩陣 \(\det(A^{-1}) = \det(A)^{-1}\),所以兩種寫法等價。依 \(f\) 怎麼用神經網路參數化,有時正向的 Jacobian 好算,有時逆向的好算。67:21
Jacobian 矩陣是什麼?為什麼局部線性化就夠?

\(f:\mathbb R^n\to\mathbb R^n\) 的 Jacobian 是所有一階偏導數排成的 \(n\times n\) 矩陣:

$$J = \frac{\partial f}{\partial\mathbf z} = \begin{pmatrix}\frac{\partial f_1}{\partial z_1}&\cdots&\frac{\partial f_1}{\partial z_n}\\\vdots&\ddots&\vdots\\\frac{\partial f_n}{\partial z_1}&\cdots&\frac{\partial f_n}{\partial z_n}\end{pmatrix}$$

第 \(i\) 列是「第 \(i\) 個輸出對每個輸入的敏感度」。在 \(\mathbf z\) 附近,\(f(\mathbf z+\Delta\mathbf z)\approx f(\mathbf z) + J\Delta\mathbf z\):一個極小的方塊被映射成一個極小的平行多面體,體積放大 \(|\det J|\) 倍,正好套用 B3 的線性結果。把空間切成無限多個小方塊,每塊各自套用,就得到一般公式。

Lai 等人的書把它寫成積分的變數變換 \(d\mathbf y = |\det(\partial_{\mathbf x}\Psi)|\,d\mathbf x\),並把同一個公式一路推廣:多個雙射的合成、連續時間極限下的 continuity equation(之後的 flow matching),以及加入高斯雜訊後的 Fokker–Planck equation(diffusion model)。現在先記住:這講的公式是後面所有這些東西的起點。

出處:Lai et al. (2026) 附錄 B §B.1,圖 B.1 "A unified change-of-variables formula"。

二維的具體寫法(投影片 12)

\(Z_1, Z_2\) 有聯合密度 \(p_{Z_1,Z_2}\)。\(\mathbf u = (u_1,u_2):\mathbb R^2\to\mathbb R^2\) 可逆,逆映射 \(\mathbf v = (v_1,v_2)\)。\(X_1 = u_1(Z_1,Z_2)\)、\(X_2 = u_2(Z_1,Z_2)\)。73:07

$$p_{X_1,X_2}(x_1,x_2) = p_{Z_1,Z_2}\big(v_1(x_1,x_2), v_2(x_1,x_2)\big)\left|\det\begin{pmatrix}\frac{\partial v_1}{\partial x_1}&\frac{\partial v_1}{\partial x_2}\\\frac{\partial v_2}{\partial x_1}&\frac{\partial v_2}{\partial x_2}\end{pmatrix}\right| = p_{Z_1,Z_2}(z_1,z_2)\left|\det\begin{pmatrix}\frac{\partial u_1}{\partial z_1}&\frac{\partial u_1}{\partial z_2}\\\frac{\partial u_2}{\partial z_1}&\frac{\partial u_2}{\partial z_2}\end{pmatrix}\right|^{-1}$$

前者叫 inverse 形式,後者叫 forward 形式。步驟永遠一樣:把輸出反推回輸入、在輸入的密度上取值、再乘上局部體積變化的修正。

延伸 補充課 A §6 散度與 trace:一小塊面積怎麼被流動撐開;補充課 C §6 沿著軌跡的 log p:連續時間版本:log|det J| 變成散度的積分

B5課堂問答整理

  • 影像是離散的(0–255),怎麼用連續的 flow?可以把影像當成連續的,或在訓練資料上加一點雜訊。實務上不是問題。70:29
  • 如果 \(f\) 不是真的可逆會怎樣?那就可能有多個 \(\mathbf z\) 映到同一個 \(\mathbf x\),要對它們求和,又回到 VAE 的世界,需要 encoder 和 ELBO。也有研究「幾乎可逆」(每個 \(\mathbf x\) 最多 \(k\) 個原像)的延伸。70:59
  • Flow 實際上有用嗎?很有用。Diffusion model 有一種詮釋就是「無限深的 flow model」,評估 diffusion model 的 likelihood 用的就是這個公式的延伸。若把 diffusion 看成疊起來的 VAE,則沒有 likelihood。77:19
  • 維度高時算行列式不就是 \(O(n^3)\)?對,所以下一步要設計特殊的神經網路,讓它容易反轉、容易算 Jacobian 行列式。78:52
  • \(\mathbf z\) 和 \(\mathbf x\) 同維度,還能叫潛在變數嗎?某種程度上是,但它沒有壓縮任何東西,比較像換單位或換座標系。線性縮放就像把公尺換成英尺;非線性的 flow 是用更複雜的方式拉伸、彎曲座標軸,讓資料在新座標下看起來是高斯,容易建模。沒有任何資訊損失。80:55
  • 離散資料能用 flow 嗎?有延伸,但離散空間中可逆映射相當於某種排列(permutation),失去了很多連續情況下的數學和計算優勢。訓練時最好把東西當成連續的。81:55
Dequantization:把離散像素變成連續值的標準作法

像素值是整數 \(\mathbf x\in\{0,\dots,255\}^D\),直接拿連續密度去擬合,模型可以把密度集中在這些整數點上,likelihood 衝到無限大,毫無意義。標準作法是加均勻雜訊:\(\mathbf y = \mathbf x + \mathbf u\),\(\mathbf u\sim U[0,1)^D\),在連續的 \(\mathbf y\) 上訓練 flow。

可以證明連續模型在 \(\mathbf y\) 上的 log 密度期望,是對應離散模型 \(P(\mathbf x) = \int_{[0,1)^D}p(\mathbf x+\mathbf u)d\mathbf u\) 的 log-likelihood 的下界(又是 Jensen 不等式)。所以不會被高估,論文報告的 bits/dim 才能和離散模型(PixelCNN 等)比較。

這是 RealNVP、Glow 等論文的標準作法,推導出自 Theis, van den Oord & Bethge (2016)〈A note on the evaluation of generative models〉§3.1(arXiv 1511.01844),用的正是 Jensen 不等式,已對照原文。

B6投影片 13–19:時間不夠沒講到的部分

影片在投影片 12 的二維例子之後結束。以下是剩下的投影片,第 8 講開頭講了這些投影片(含課堂問答)。

Normalizing flow 模型(投影片 13)

有向的潛在變數模型,\(\mathbf Z\to\mathbf X\) 的映射 \(f_\theta:\mathbb R^n\to\mathbb R^n\) 是確定性且可逆的:\(X = f_\theta(Z)\)、\(Z = f_\theta^{-1}(X)\)。

$$p_X(\mathbf x;\theta) = p_Z\big(f_\theta^{-1}(\mathbf x)\big)\left|\det\left(\frac{\partial f_\theta^{-1}(\mathbf x)}{\partial\mathbf x}\right)\right|$$

投影片 13 的圖:上方節點 z、下方灰色節點 x,左邊向下的箭頭標 \(f_\theta\),右邊向上的箭頭標 \(f_\theta^{-1}\)。兩個方向都走得通,這是和 VAE 圖最大的不同。

Flow:變換可以疊起來(投影片 14)

Normalizing:變數變換在可逆變換之後仍給出正規化的密度。Flow:可逆變換可以互相合成:

$$\mathbf z_m = f_\theta^m\circ\cdots\circ f_\theta^1(\mathbf z_0) = f_\theta^m\big(f_\theta^{m-1}(\cdots(f_\theta^1(\mathbf z_0)))\big) \triangleq f_\theta(\mathbf z_0)$$

從簡單的 \(\mathbf z_0\)(例如高斯)開始,連續套 \(M\) 個可逆變換得到 \(\mathbf x = \mathbf z_M\)。由於乘積的行列式等於行列式的乘積:

$$p_X(\mathbf x;\theta) = p_Z\big(f_\theta^{-1}(\mathbf x)\big)\prod_{m=1}^{M}\left|\det\left(\frac{\partial(f_\theta^m)^{-1}(\mathbf z_m)}{\partial\mathbf z_m}\right)\right| \quad\Longleftrightarrow\quad \log p_X(\mathbf x) = \log p_Z(\mathbf z_0) - \sum_{m=1}^{M}\log\left|\det\frac{\partial f^m}{\partial\mathbf z_{m-1}}\right|$$

右邊的 log 形式出自 Lilian Weng 的文章,實作時都用這個形式:每層各自算 log 行列式再相加。

Planar flow(投影片 15、19)

$$\mathbf x = f_\theta(\mathbf z) = \mathbf z + \mathbf u\,h(\mathbf w^\top\mathbf z + b),\qquad \theta = (\mathbf w,\mathbf u,b),\quad h\text{ 是非線性函數}$$
$$\left|\det\frac{\partial f_\theta(\mathbf z)}{\partial\mathbf z}\right| = \left|\det\big(I + h'(\mathbf w^\top\mathbf z+b)\,\mathbf u\mathbf w^\top\big)\right| = \left|1 + h'(\mathbf w^\top\mathbf z+b)\,\mathbf u^\top\mathbf w\right|$$

第二個等號用的是 matrix determinant lemma。要保證可逆,必須限制參數和非線性,例如 \(h=\tanh\) 且 \(h'(\mathbf w^\top\mathbf z+b)\,\mathbf u^\top\mathbf w\ge-1\)。

投影片 15 的圖:兩列,每列四格(\(K\) = 1、2、10 個 planar 變換)。上列從單位高斯出發:K=1 時圓形被擠成橢圓並在中間切出一條暗線,K=10 時變成一個環加中間一團的複雜形狀。下列從均勻分佈出發:方塊逐漸被扭成好幾塊彎曲的區域。結論:10 個 planar 變換就能把簡單分佈變得相當複雜。Demo C 重現這張圖。

Matrix determinant lemma 與 planar flow 的可逆條件

Lemma:對可逆矩陣 \(A\) 和向量 \(\mathbf u,\mathbf v\),\(\det(A + \mathbf u\mathbf v^\top) = (1 + \mathbf v^\top A^{-1}\mathbf u)\det A\)。取 \(A = I\),就是 \(\det(I + \mathbf u\mathbf v^\top) = 1 + \mathbf v^\top\mathbf u\)。直覺:\(I + \mathbf u\mathbf v^\top\) 只在一個方向上和單位矩陣不同,所以行列式只差一個純量因子。這讓 \(n\times n\) 的行列式變成 \(O(n)\) 的內積。

為什麼需要條件:沿著 \(\mathbf w\) 方向看,\(\mathbf w^\top\mathbf x = \mathbf w^\top\mathbf z + (\mathbf w^\top\mathbf u)\,h(\mathbf w^\top\mathbf z+b)\),這是一個一維函數。它單調遞增(可逆)的條件是導數 \(1 + (\mathbf w^\top\mathbf u)h'(\cdot) > 0\)。\(h=\tanh\) 時 \(h'\in(0,1]\),所以 \(\mathbf w^\top\mathbf u\ge-1\) 就夠了。Rezende & Mohamed 的作法是把任意的 \(\mathbf u\) 修正成 \(\hat{\mathbf u}\),讓 \(\mathbf w^\top\hat{\mathbf u} = -1 + \log(1+e^{\mathbf w^\top\mathbf u})\ge-1\)。Demo C 用的就是這個修正。

缺點:planar flow 沒有解析的反函數,算 \(f^{-1}(\mathbf x)\) 要解方程。所以它適合「從 \(\mathbf z\) 正向抽樣並算密度」,例如當 VAE 的 \(q\),不適合在資料上做 MLE。這正是下一講 NICE、RealNVP 要解決的問題。

出處:Rezende & Mohamed (2015) 附錄 A.1「Planar flows」:\(\hat{\mathbf u} = \mathbf u + [m(\mathbf w^\top\mathbf u) - \mathbf w^\top\mathbf u]\,\mathbf w/\Vert\mathbf w\Vert^2\),\(m(x) = -1 + \log(1+e^x)\),已對照 TeX 原文。投影片 15、19 把這篇論文標成 2016 年,實際是 ICML 2015。

學習與推論(投影片 16)

$$\max_\theta\log p_X(\mathcal D;\theta) = \sum_{\mathbf x\in\mathcal D}\left[\log p_Z\big(f_\theta^{-1}(\mathbf x)\big) + \log\left|\det\left(\frac{\partial f_\theta^{-1}(\mathbf x)}{\partial\mathbf x}\right)\right|\right]$$
  • 精確的 likelihood:用逆變換 \(\mathbf x\mapsto\mathbf z\) 加變數變換公式。直接做 maximum likelihood,不需要 ELBO。
  • 取樣:用正向變換 \(\mathbf z\mapsto\mathbf x\),\(\mathbf z\sim p_Z(\mathbf z)\),\(\mathbf x = f_\theta(\mathbf z)\)。
  • 潛在表示:用逆變換 \(\mathbf z = f_\theta^{-1}(\mathbf x)\),不需要推論網路。

Flow 的需求(投影片 17–18)

  • 簡單的先驗 \(p_Z(\mathbf z)\):容易取樣、容易算 likelihood,例如各向同性高斯。
  • 可逆變換的兩個方向都要好算:算 likelihood 需要 \(\mathbf x\mapsto\mathbf z\),取樣需要 \(\mathbf z\mapsto\mathbf x\)。
  • 算 likelihood 還要 \(n\times n\) Jacobian 的行列式,\(n\) 是資料維度。一般要 \(O(n^3)\),在訓練迴圈裡太貴。
  • 關鍵想法:選讓 Jacobian 有特殊結構的變換。例如三角矩陣的行列式是對角線乘積,只要 \(O(n)\)。
三角 JACOBIAN\(\mathbf x = (x_1,\dots,x_n) = f(\mathbf z) = (f_1(\mathbf z),\dots,f_n(\mathbf z))\)。若 \(x_i = f_i(\mathbf z)\) 只依賴 \(\mathbf z_{\le i}\),則 \(\partial f_i/\partial z_j = 0\)(\(j>i\)),Jacobian 是下三角,行列式可以線性時間算出。若 \(x_i\) 只依賴 \(\mathbf z_{\ge i}\),則是上三角。這正是 autoregressive 的結構:第 3 講的 MADE 會在下一講變成 MAF / IAF 的積木。

Demo CPlanar flow:把高斯扭成目標形狀

從二維標準高斯出發,疊 \(K\) 層 planar flow。左圖是 flow 的密度:把 \(\mathbf z\) 平面的小格子正向映射到 \(\mathbf x\) 平面,每格的密度 = \(p_Z(\mathbf z)/\prod_k|1+h'\mathbf u^\top\mathbf w|\)。右圖是目標密度(Rezende & Mohamed 論文中的一個二維能量函數)。按「訓練」用梯度下降最小化 \(D_{\mathrm{KL}}(q_{\text{flow}}\Vert p_{\text{target}})\):只需要從 \(\mathbf z\) 正向抽樣、算 \(\log q\),不需要反函數,正好是 planar flow 擅長的。

flow 的密度 q(x)
目標密度 p(x) ∝ exp(−U(x))
  • K=1 時只能沿一個方向擠壓或拉伸,和投影片 15 的第一格一樣。K 越大,能扭出的形狀越複雜。
  • 這裡最小化的是 reverse KL(第 4 講):預設的「環」其實是左右兩段弧,訓練後 flow 常常只抓住其中一段;「兩團」也常只抓住一團,或在中間拉出一條細橋。這是 mode-seeking。實測時用預設設定訓練 600 步,flow 只抓住了左邊那段弧。
  • 按「隨機參數」看沒有訓練的 planar flow 能產生哪些奇怪形狀,有時會出現投影片 15 那種中間被切開的暗線:那是 \(1+h'\mathbf u^\top\mathbf w\) 接近 0、局部被極度拉伸的地方。

常見誤解

誤解:「\(p_X(x) = p_Z(f^{-1}(x))\),直接代入就好」。這把密度當成機率。一定要乘上逆映射的 \(|\text{導數}|\) 或 \(|\det\text{Jacobian}|\),否則積分不為 1。
誤解:「密度大於 1 就錯了」。壓縮區間會讓密度變大,可以遠大於 1(例如 sigmoid 兩端)。要等於 1 的是積分。
誤解:「flow 的 z 是壓縮的表示」。\(\mathbf z\) 和 \(\mathbf x\) 同維度、一一對應,沒有資訊損失,比較像換座標系。
誤解:「任何神經網路都能當 flow」。必須可逆,而且 Jacobian 行列式要好算。一般的網路兩者都不滿足,要特別設計(三角結構、coupling 等)。
誤解:「行列式的正負號不重要」。公式用的是絕對值,正負號只表示方向是否翻轉。但 \(\det = 0\) 很重要:代表不可逆,公式失效。

自我測驗

1. Flow 和 VAE 在模型結構上的三個差別是什麼?
(1) \(\mathbf x = f(\mathbf z)\) 是確定性的,不是一個條件分佈;(2) \(f\) 可逆,給定 \(\mathbf x\) 只有一個 \(\mathbf z\);(3) \(\mathbf z\) 和 \(\mathbf x\) 同維度、都必須連續。結果是 likelihood 可以精確算、不需要 encoder。
2. Z ~ U[0, 2],X = 4Z。p_X(4) = ? 為什麼 1/2 是錯的?
1/8。1/2 是把密度當機率直接代入,忘了區間被拉長 4 倍、每單位長度的機率變成 1/4,即 \(|h'(x)| = 1/4\)。
3. Z ~ U[0, 2],X = exp(Z)。求 p_X(x)。
\(h(x) = \ln x\),\(h'(x) = 1/x\),\(p_X(x) = \frac12\cdot\frac1x = \frac{1}{2x}\),\(x\in[1,e^2]\)。檢查:\(\int_1^{e^2}\frac{1}{2x}dx = \frac12(2-0) = 1\)。
4. 用 CDF 證明一維變數變換公式(f 遞增)。
\(F_X(x) = P[f(Z)\le x] = P[Z\le h(x)] = F_Z(h(x))\),兩邊微分得 \(p_X(x) = p_Z(h(x))h'(x)\)。
5. A = (2, 1; 0, 3),Z 在單位正方形均勻。X = AZ 的密度是多少?
\(\det A = 6\),X 在面積 6 的平行四邊形上均勻,密度 1/6(在平行四邊形內)。
6. 寫出多維變數變換公式的兩種形式,並說明為什麼等價。
\(p_X(\mathbf x) = p_Z(f^{-1}(\mathbf x))|\det\partial f^{-1}/\partial\mathbf x| = p_Z(\mathbf z)|\det\partial f/\partial\mathbf z|^{-1}\)。因為反函數的 Jacobian 是原函數 Jacobian 的反矩陣,而 \(\det(A^{-1}) = 1/\det A\)。
7. 為什麼叫「normalizing」flow?
變數變換公式中的行列式項保證變換後的密度仍然正規化(積分為 1)。
8. 三層 flow 的 log-likelihood 怎麼算?
\(\log p(\mathbf x) = \log p_Z(\mathbf z_0) - \sum_{m=1}^{3}\log|\det\partial f^m/\partial\mathbf z_{m-1}|\),其中 \(\mathbf z_0 = (f^1)^{-1}\circ(f^2)^{-1}\circ(f^3)^{-1}(\mathbf x)\)。
9. 為什麼 flow 要設計成三角 Jacobian?
一般 \(n\times n\) 行列式要 \(O(n^3)\),在每個訓練步驟算太貴。三角矩陣的行列式是對角線乘積,只要 \(O(n)\)。當 \(x_i\) 只依賴 \(\mathbf z_{\le i}\)(autoregressive 結構)時,Jacobian 就是下三角的。
10. Planar flow 的 Jacobian 行列式為什麼可以 O(n) 算出?它的主要缺點是什麼?
Jacobian 是 \(I + h'\,\mathbf u\mathbf w^\top\)(單位矩陣加秩一矩陣),由 matrix determinant lemma,行列式 = \(1 + h'\,\mathbf u^\top\mathbf w\)。缺點:沒有解析的反函數,要算資料的 likelihood 不方便。
11. VAE 中 posterior collapse 是什麼?什麼時候容易發生?
\(q(\mathbf z\mid\mathbf x)\approx p(\mathbf z)\),潛在碼完全不帶 \(\mathbf x\) 的資訊。當 decoder 很強(例如 autoregressive)時,不用 \(\mathbf z\) 也能擬合資料,KL 項就把 \(q\) 推向先驗。
12. 為什麼離散像素不能直接用連續 flow 做 MLE?怎麼處理?
連續密度可以把質量集中在整數點上,likelihood 衝到無限大。加上 \(U[0,1)\) 雜訊做 dequantization,連續模型的期望 log 密度會成為離散 log-likelihood 的下界。

延伸閱讀