深入淺出 Normalizing Flow: Generative Model不只有 GAN跟 VAE
深入淺出 Normalizing Flow: Generative Model不只有 GAN跟 VAE
在這幾年的類神經網路發展中,生成模型 (generative model) 網路是很熱門的一個題目。而這之中最常被提起的則是** VAE (Variational Auto-Encoder)與GAN (Generative Adversarial Network)。實際上,還有一種有意思生成模型方法叫Normalizing Flow (通常簡稱NF)**,但可能因為他較複雜的數學原理,導致較少人知曉。
Normalizing Flow是一種 generative model的實現方法。以統計的角度來看,generative model的目標就是 modeling目標資料的分布,通常是利用 maximize likelihood estimation (MLE),或說 minimize some divergence來達成。對比 VAE與 GAN, NF是最精準貼近 MLE的方法,而且每一個步驟基本上都可以用機率與數學解釋,讓導入 prior knowledge變得更容易想像與實現。
Tip
文章難度:★★★☆☆
閱讀建議: 這篇文章是 Normalizing Flow的入門介紹,一開始會快速過一些簡單的 generative model作為背景知識,而後著重介紹 Normalzing的概念,以及其背後的相關機率原理,最後再簡單介紹幾個常用的 NF模型。在介紹相關機率原理時,因為 NF本質就是貼著機率的數學原理在走,所以這邊會牽扯到比較多數學推導。
推薦背景知識: Machine Learning, Deep Learning, Generative Model, VAE (Variational Auto-Encoder), GAN (Generative Adversarial Network), Maximize Likelihood Estimation (MLE), Density Estimation, Change of Variables, Jacobean.
Generative Model
以統計的角度來看,
生成模型 (generative model)的目標是 modeling目標資料的分布。
比如說,我們手邊有一萬張人臉的照片,但我們希望可以獲得更多人臉的照片,或者說想要依照某些情境生成更多人臉的照片。而使用 generative model來 modeling目標資料的分布,可以確保生成出來的是人臉的照片,而不是貓狗的照片,或是四不像的照片。
不考慮條件的 generative model的概念大致如下圖,首先會從一個已知的分布中採樣,將樣本放到 generative model生成目標資料,最後要讓這些生成資料的分布與真實資料的分布越接近越好。
很直覺地,要讓兩種資料的分布接近,也就是** maximize likelihood estimation (MLE),或說 minimize some divergence**。但描述真實資料的分布其實就是一個很難的問題,更遑論計算什麼 likelihood或 divergence。
其中一個知名的生成網路方法就是Generative Adversarial Network (GAN) [1]。 GAN的想法很單純,既然我們不會算 divergence,那就把這個問題也丟給另一個網路 (稱為 discriminator) 去算。總之,最後透過一些 tricky的設計,讓 discriminator確實可以衡量 divergence。
除了GAN,Variational Auto-Encoder (VAE) [2]也是一個常見的方法。 VAE對於大多搞 deep learning的是最好理解的。基於 auto-encoder,透過一個網路將輸入 x變成一組編碼,再透過另一個網路解碼回 x達成 unsupervised target。除此之外,VAE在編碼時額外讓已知的機率分布介入,限制編碼的範圍,這樣訓練完成後就可以透過採樣出來、不同的隨機值生成資料。
更精確地說,所謂的 generative model全名應該是 PGM。
Probabilistic Generative Model (PGM)是對隨機變數 X的機率分布,其 Probability Density Function (PDF)使用參數 θ描述,而 θ透過 X的觀測點學習。
這 PGM的描述聽起來有點難,白話點解釋一下結果,因為 PGM是一個機率分布,所以從 PGM sample出來的點就就是屬於 X的資料。換句話,從 PGM中 sample點就等價於「生成資料」這個動作。而這個點的 density (將從 x帶入 PDF中 p(x)
),就是有點像是這個資料出現在這個分布的機率了。
有些時候研究 PGM並不是單純為了生成資料,在某些應用情境上評估 p(x)
也是很關鍵的,這可能很難三言兩語在這邊解釋。總之,如果有些時候能夠計算p(x)可以更有效地結合一些題目的 prior knowledge。
因此,GAN在機率原理上有兩個缺點,其一是GAN無法計算`p(x),其二則是GAN說穿了只是在近似 divergence estimation,而不是真正的在算 divergence。而 VAE則是可以計算p(x),但其 auto-encoder的設計,讓他優化的並不是 maximize likelihood,而是 ELBO(Evidence Lower Bound)。
這時候看到 ELBO可能一頭霧水,不過這可能不影響理解 Normalizing Flow,可以暫時理解成-優化目標設計不夠好。細節可以參考一下CMU的課程投影片 [3],或李宏毅老師的課程錄影 [4]。
總之,
這些 GAN與 VAE所不能之處,恰恰就是 Normalizing Flow的厲害之處。
Normalizing Flow (NF) 基本概念
以圖片生成為例, Normalizing Flow ** [5] 的想法是想要找到一個可逆的函式 f,對於圖像集合 X,可以將 X的分布轉換到某種已知的簡單分布 (如 Gaussian分布)。那麼生成圖型就變得很簡單了,只要從已知的簡單分布中 sample出點,然後透過 f的反函式,就可以生成圖片**了。
整理一下問題: p_Z是已知分布, p_X是想要求得的分布,那麼這就是一個 maximum likelihood estimation的問題了。換句話說,找到某個網路 (其中參數用 θ表示),最佳化以下目標。
為了求取函式 f,需要找到一個方法描述兩個 domain之間的關係。其實在機率學上** X domain與 Z domain可以使用機率模型去描述**,也就是所謂的PDF (Probability Density Function)。
那麼 X與 Z domain之間的轉換,或者說 p_X與 p_Z之間的轉換,就可以使用常見的change of variables 的公式來描述。
如果對機率不熟,突然看到這個式子好像有些資訊量過多,可以先分成兩半來看。先看忽略右邊絕對值內的東西,剩下的其實都懂,就是可以從兩個分布中找到一組對應的點,然後乘上某個神奇 scalar,就可以得到對應關係。
那剩下的就是絕對值裡面的東西了,這個部分稱為volume correction。其中**Df(x)代表 f(x)的 Jacobian matrix ,而det代表行列式 (determinant) **。
Jacobian matrix是當轉換為可微分函式時常用的工具:**如果函數 f : X→ Z在點 x 可微的話,在點 x 的 Jacobian matrix即為該函數在該點的最佳線性逼近。**白話地說, Jacobian matrix是描述了 X與 Z兩個 domain在點 x的關係。
Determinant (行列式) 是在方塊矩陣上計算得到的純量,而他的幾何意義則是面積或體積在 Euclidean space的推廣。比如說以下圖 2x2矩陣的 determinant其實就是 (a, b)與 (c, d)向量圍成的平行四邊形面積,而 3x3矩陣則是立方體的體積。
因為 determinant有正有負,所以在代表幾何意義時,通常都會取絕對值。
因此在 change of variables這邊,對於變數為度為 N,** PDF的機率可以想像成 在 N+1維上的數值,並且這一個維度的數值總合為一**。那麼Jacobian determinant就可以合理想像成面積或體積的修正量,這也是為什麼稱為 volume correction。
總之,訓練的最終目標就是把前面 maximum likelihood式子中的 p_X使用 change of variables formula代換掉,然後簡單地推導一下。
那麼為了讓這個參數 θ的網路可以被訓練,並且能夠作為 generative model,以下三個條件就是必須的:
- 可逆 (invertible): 因為 f的反函數才是真正生成要用的。
- 可微 (differentiable): 才能使用 gradient來訓練。
- 有效率地計算 Jacobian determinant以及有效率地計算反函數。
實作設計 Flow Model
回顧一下 Normalizing flow的概念與流程。一個可逆的函式 f,可以將 X的分布轉換到某種已知的簡單分布 (如 Gaussian分布)。
因此,Normalizing flow中有兩個重要的 components:
- Base measurement: 上圖右邊的 p_z(z),常用如高斯分布。
- Flow: 上圖的 f,而且必須可逆 (invertible) 且可微 (differentiable),又能夠有效率地計算 Jacobian determinant以及有效率地計算反函數。。
最簡單的 flow model可以是一個 linear model,也就是f(x) = Ax + b。這樣的 model確實簡單地可逆、可微、又好計算,但表述能力可能就不太夠了。
Coupling flow就是一個簡單、精巧的方法,將表述力很強、但不符合 flow model原則的模型藏在一個合法的 flow model中。
首先,對於輸入 x,先把 x拆成 (A, B) 兩半。其中A部分通過一個複雜的網路後,再與 B部分一起通過某種簡單 transform,比如說的簡單的 element-wise add或是 affine transform。最後,再與原封不動的 A部分 concatenate再一起。到此為止,所有的計算都是可微分的。
接下來看一下 Jacobian determinant的計算。以下用 A或上半部指那些沒動過的部分, B或下半部則指那些有轉換的部分。
- Jacobean matrix左上部分:X的上半部對 Z的上半部的影響,因為上半部根本都沒動過,也就是自己跟自己計算,所以等於identity。
- Jacobean matrix右上部分:是X的下半部分對 Z的上半部分的影響,也就是沒影響,所以都是 0。
- Jacobean matrix左下部分:因為 Jacobean matrix右上部分微零,計算 determinant時全部都不重要。
- Jacobean matrix右下部分:計算整個 Jacobean matrix determinant等同計算這邊的 determinant。而且這邊的 matrix基本上就是 coupling network的輸出,所以計算起來就也很簡單。
總而言之,我們可以把表述能力很強的模型放到 coupling network,然後完全不用擔心 Jacobian determinant很難算。到這裡,我們又實現了有效率地計算 Jacobian determinant。
最後,剩下的就是反函式。但其實也很簡單,拆分方法一樣、coupling network也不動,只要把「簡單 transform」變成 inverse就好。比如說,如果是 element-wise add θ(x),那就變 element-wise add (-θ(z))。
那麼到此為止,可逆 (invertible) 且可微 (differentiable)、有效率地計算 Jacobian determinant以及有效率地計算反函數就都符合了。
雖然我們可以把強大的模型當成 coupling network,但還是不能改變單一 coupling flow實際執行的 transform還是很簡單,並不能夠構成一個足夠強大的 function。但這也沒什麼問題,就像是類神經網路一層不夠強,那就繼續疊下去吧! Flow model也是可以一層一層的堆疊的,這樣就可以獲得夠好的表述能力。
另外,先前提到的 coupling flow雖然計算快速,但其實有些缺點-沒有經過 transform的上半部的資訊可能一直都沒有好好被利用。而要處理的方法其實也可以很單純,就是在拆成 (A, B) 兩半前,先通過簡單的 transform,再搭配上層層堆疊的 flow,就可以確保資訊的利用程度。
在簡單的 transform部分,常見的幾個例子包含: NICE使用簡單的 diagonal linear、RealNVP使用更粗暴的 permutation、或是後來 GLOW與 Flow++使用的 channel-wise linear。
這篇文章說道這邊真的是有點過長了,最後就簡單附上一組比較表格 (當然除了上列還有其他不同),代表從 2014年的 NICE [6]、 到2016年的 RealNVP [7]、 2018年的Glow ** [8]、 2019年的 Flow++ [9] **這一系列經典 NF模型的發展。事實上 2020年後 NF越來越常出現,而其結合 prior knowledge的優勢也越顯明顯 (如 [10])。
總之,現在的趨勢上看起來,單論生成的品質還是 GAN與 VAE較具優勢,但是各種跨領域的操作 Normalizing Flow真的是越來越精彩,不過其背後的數學原理讓 NF學起來,所花費的時間相信會比 GAN與 VAE還要長一些。
好了~這篇文章就先到這邊。老話一句,Deep Learning領域每年都會有大量高質量的論文產出,說真的要跟緊不是一件容易的事。所以我的觀點可能也會存在瑕疵,若有發現什麼錯誤或值得討論的地方,歡迎回覆文章或來信一起討論 :)
Reference
- Generative Adversarial Networks[NIPS 2014]
- Auto-Encoding Variational Bayes[ICLR 2014]
- Variational Autoencoders[slides from CMU]
- ML Lecture 18: Unsupervised Learning — Deep Generative Model (Part II)[YouTube]
- Variational Inference with Normalizing Flows[ICML 2015]
- NICE: Non-linear Independent Components Estimation[ICLR 2015]
- Density estimation using Real NVP[ICLR 2017]
- Glow: Generative Flow with Invertible 1×1 Convolutions[NIPS 2018]
- Flow++: Improving Flow-Based Generative Models with Variational Dequantization and Architecture Design[ICML 2019]
- Human Pose Regression with Residual Log-likelihood Estimation[ICCV 2021]
- Flow-based Generative Model[YouTube]
- Introduction to Normalizing Flows (ECCV2020 Tutorial)[YouTube]