VAE與GAN的區別和聯繫

轉載鏈接

1.互懟的藝術:從零直達 WGAN-GP
2.變分自編碼器VAE:原來是這麼一回事 | 附開源代碼

正文

1

前言

GAN,全稱 Generative Adversarial Nets,中文名是生成對抗式網絡。對於 GAN 來說,最通俗的解釋就是“造假者-鑑別者”的解釋,如藝術畫的僞造者和鑑別者。一開始僞造者和鑑別者的水平都不高,但是鑑別者還是比較容易鑑別出僞造者僞造出來的藝術畫。但隨着僞造者對僞造技術的學習後,其僞造的藝術畫會讓鑑別者識別錯誤;或者隨着鑑別者對鑑別技術的學習後,能夠很簡單的鑑別出僞造者僞造的藝術畫。這是一個雙方不斷學習技術,以達到最高的僞造和鑑別水平的過程。 然而,稍微深入瞭解的讀者就會發現,跟現實中的造假者不同,造假者會與時俱進地使用新材料新技術來造假,而 GAN 最神奇而又讓人困惑的地方是它能夠將隨機噪聲映射爲我們所希望的正樣本,有噪聲就有正樣本,這不是無本生意嗎,多划算。

另一個情況是,自從 WGAN 提出以來,基本上 GAN 的主流研究都已經變成了 WGAN 上去了,但 WGAN 的形式事實上已經跟“僞造者-鑑別者”差得比較遠了。而且 WGAN 雖然最後的形式並不複雜,但是推導過程卻用到了諸多複雜的數學,使得我無心研讀原始論文。這迫使我要找從一條簡明直觀的線索來理解 GAN。幸好,經過一段時間的思考,有點收穫。

在正文之前,先聲明:筆者所有的 GAN 的知識,僅僅從網上的科普文所讀而來,我並沒有直接讀過任何關於 GAN 的論文,因此,文中的結果可能跟主流的結果有雷同,也可能有很大出入,而且本文的講述方法並不符合 GAN 的歷史發展進程。嚴謹治學者慎入。

注:如無指明,本文所談到的 GAN 都是廣義的,即包括原始 GAN、WGAN 等等,對它們不作區分。文中出現的正樣本、真實樣本,都是指預先指定的一批樣本,而生成樣本則指的是隨機噪聲通過生成模型 G 變換所得的結果。

2

一道面試題

一道經典的面試題是:如果有一個僞隨機數程序能夠生成 [0,1] 之間的均勻隨機數,那麼如何由它來生成服從正態分佈的僞隨機數?比如怎麼將 U[0,1] 映射成 N(0,1)?

這道題不同的角度有不同的做法,工程上的做法有:同時運行 n 個這樣的僞隨機數程序,每步產生 n 個隨機數,那麼這 n 個數的和就近似服從正態分佈了。不過,這裏不關心工程做法,而關心理論上的做法。理論上的做法是:將 X∼U[0,1] 經過函數 Y=f(X) 映射之後,就有 Y∼N(0,1) 了。設 ρ(x) 是 U[0,1] 是概率密度函數,那麼 [x,x+dx] 和 [y,y+dy] 這兩個區間的概率應該相等,而根據概率密度定義,ρ(x) 不是概率,ρ(x)dx 纔是概率,因此有

那麼:

這裏 Φ(y) 是標準正態分佈的累積分佈函數,所以:

注意到累積分佈函數是無法用初等函數顯式表示出來的,更不用說它的逆函數了。說白了,Y=f(X) 的 f 的確是存在的,但很複雜。正態分佈是常見的、相對簡單的分佈,但這個映射已經這麼複雜了。如果換了任意分佈,甚至概率密度函數都不能顯式寫出來,那麼複雜度可想而知。

3

神經大法好

現在我們將問題一般化:如何找到映射 Y=f(X),把服從均勻分佈 X 映射到指定的分佈?在一般情形下,這個指定的分佈是通過給出一批具體的分佈樣本 Z=(z1,z2,…,zN) 來描述的(比如,給出一批服從正態分佈的隨機數,而不是給出概率密度

)。

這個問題相當一般化,跟 GAN 所做的事情也是一樣的。也就是說,GAN 也是希望把均勻的隨機噪聲映射成特定分佈,這個特定分佈由一組“正樣本”描述。這樣的理解就可以回答我們開頭的一個小問題了:爲什麼 GAN 可以將噪聲變換成正樣本?事實上 GAN 並不是學習噪聲到正樣本的變換,而是學習均勻分佈到指定分佈的變換。假如學習成功了,那麼輸入一個隨機噪聲,那麼就變換成指定分佈的數據,而通常來說我們指定的分佈是一個比較“窄”的分佈(比如指定的正樣本是某一類圖片的集合,但事實上圖片無窮無盡,某一類的圖片是相當窄的),所以都會映射到我們眼中的“正樣本”去。

前面正態分佈的例子已經表明,這個映射 f 通常都是很複雜的,因此沒必要求它的解析解。這時候“神經大法”就登場了:熟悉神經網絡的讀者都知道,我們總可以用一個神經網絡來擬合任意函數,因此,不妨用一個帶有多個參數的神經網絡 G(X,θ) 去擬合它?只要把參數 θ 訓練好,就可以認爲 Y=G(X,θ) 了。

可是,問題又來了:擬合什麼目標呢?我們怎麼知道 Y=G(X,θ) 跟指定的分佈是很接近的呢?

4

KL 距離?JS 距離?

讓我們把問題再理清楚一下:我們現在有一批服從某個指定分佈的數據 Z=(z1,z2,…,zN),我們希望找到一個神經網絡 Y=G(X,θ),將均勻隨機數 X 映射到這個指定分佈中來。

需要特別指出,我們是要比較兩個分佈的接近程度,而不是比較樣本之間的差距。通常來說,我們會用 KL 距離來描述兩個分佈的差異:設 p1(x),p2(x) 是兩個分佈的概率密度(當然,還有其他距離可以選擇,比如 Wasserstein 距離,但這不改變下面要討論的內容的實質),那麼:

如果是離散概率,則將積分換成求和即可。KL 距離並非真正的度量距離,但是它能夠描述兩個分佈之間的差異,當它是 0 時,表明兩個分佈一致。但因爲它不是對稱的。有時候將它對稱化,得到 JS 距離:

咦?怎麼又回到概率密度了?不是說沒給出概率密度嗎?沒辦法,公式就是這樣,只好估算一下咯。假設我們可以將實數域分若干個不相交的區間 I1,I2,…,IK,那麼就可以估算一下給定分佈 Z 的概率分佈。

其中 #(zj∈Ii) 表示如果 zj∈Ii,那麼取值爲 1,否則爲 0,也就是說大家不要被公式唬住了,上式就是一個簡單的計數函數,用頻率估計概率罷了。

接着我們生成 M 個均勻隨機數 x1,x2,…,xM(這裏不一定要 M=N,還是那句話,我們比較的是分佈,不是樣本本身,因此多一個少一個樣本,對分佈的估算也差不了多少。),根據 Y=G(X,θ) 計算對應的 y1,y2,…,yM,然後根據公式可以計算:

現在有了 pz(Ii) 和 py(Ii),那麼我們就可以算它們的差距了,比如可以選擇 JS 距離:

注意 yi 是由 G(X,θ) 生成的,所以 py(Ii) 是帶有參數 θ 的,因此可以通過最小化 Loss 來得到參數 θ 的最優值,從而決定網絡 Y=G(X,θ)。

5

神經距離

假如我們只研究單變量概率分佈之間的變換,那上述過程完全夠了。然而,很多真正有意義的事情都是多元的,比如在 MNIST 上做實驗,想要將隨機噪聲變換成手寫數字圖像。要注意 MNIST 的圖像是 28*28=784 像素的,假如每個像素都是隨機的,那麼這就是一個 784 元的概率分佈。按照我們前面分區間來計算 KL 距離或者 JS 距離,哪怕每個像素只分兩個區間,那麼就有 2784≈10236 個區間,這是何其巨大的計算量!

終於,有人怒了:“老子幹嘛要用你那逗比的 JS 距離,老子自己用神經網絡造一個距離!”於是他寫出帶參數 Θ 的神經網絡:

也就是說,直接將造出來的 yi 和真實的 zi 都放進去這個神經網絡一算,自動出來距離,多方便。這個思想是里程碑式的,它連距離的定義都直接用神經網絡學了,還有什麼不可能學的呢?

我們來看看,要是真有這麼個 L 存在,它應該是怎麼樣的?首先,對於特定的任務來說,

是給定的,因此它並非變量,我們可以把它當做模型本身的一部分,因此簡寫成:

接着,別忘記我們是描述分佈之間的距離而不是樣本的距離,而分佈本身跟各個 yi 出現的順序是沒有關係的,因此分佈之間的距離跟各個 yi 出現的順序是無關的,也就是說,儘管 L 是各個 yi 的函數,但它必須全對稱的!這是個很強的約束,當然,儘管如此,我們的選擇也有很多,比如:

也就是說,我們先找一個有序的函數 D,然後對所有可能的序求平均,那麼就得到無序的函數了。當然,這樣的計算量是 ��(M!),顯然也不靠譜,那麼我們就選擇最簡單的一種:

這便是無序的最簡單實現,可以簡單的理解爲:分佈之間的距離,等於單個樣本的距離的平均。

6

對抗來了

“等等,你的標題是 GAN,你講了那麼一大通,我怎麼沒感覺到半點 GAN 的味道呀?對抗在哪裏?” 這位看官您別急,馬上就有了。

前面說到,用神經網絡來學習一個距離 L,最終簡化版的形式,應該是這樣的:

問題是:D(Y,Θ) 怎麼訓練?別忘了,之前的 G(X,θ) 還沒有訓練好,現在又弄個 D(Y,Θ) 出來,越搞越複雜,小心跳到坑裏出不來了。

對抗終於來了...

因爲 D(Y,Θ) 的均值,也就是 L,是度量兩個分佈的差異程度,這就意味着,L 要能夠將兩個分佈區分開來,即 L 越大越好;但是我們最終的目的,是希望通過均勻分佈而生成我們指定的分佈,所以 G(X,θ) 則希望兩個分佈越來越接近,即 L 越小越好。這時候,一個天才的想法出現了:互懟!不要慫,gan!

首先我們隨機初始化 G(X,θ),固定它,然後生成一批 Y,這時候我們要訓練 D(Y,Θ),既然 L 代表的是“與指定樣本 Z 的差異”,那麼,如果將指定樣本 Z 代入 L,結果應該是越小越好,而將 Y 代入 L,結果應該是越大越好,所以:

然而有兩個目標並不容易平衡,所以乾脆都取同樣的樣本數 B(一個 batch),然後一起訓練就好:

很自然,G(X,θ) 希望它生成的樣本越接近真實樣本越好,因此這時候把 Θ 固定,只訓練 θ 讓 L 越來越小:

這就是天才的對抗網絡!

需要指出的是:

1. 這裏的 Loss 寫法跟傳統的 GAN 相反,習慣性的做法是讓真實樣本的LL越大越好,但這只不過跟本文差了個負號而已,不是本質的問題;

2. 從 GAN 開始,D 這個神經網絡就被賦予了“判別器”的意義,但在這裏 D 本身是沒有意義的(正如我們不能說某個數是不是正態分佈的),只有 D 的平均值 L 才代表着與真實分佈的差距(我們只能根據一批數據來估計它是否服從正態分佈),所以從這裏也可以看到,GAN 不能單個樣本地訓練,至少成批訓練,因爲有一批樣本才能看出統計特徵;

3. 咋看上去 D 只是個二分類問題,而 G 則要把噪聲映射爲正樣本,貌似 D 應該比 G 要簡單得多?事實並非如此,它們兩者的複雜度至少是相當的。我們可以直觀考慮一下它們的工作原理:因爲 D 的均值 L 直接就給出了輸入的數據與指定分佈的差異,而要真的做到這一點,那麼 D 要把所有的“正樣本”(在某種程度上)都“記住”了纔行;而 G 要生成良好的正樣本,基本上也是“記住”了所有的正樣本,並通過隨機數來插值輸出。因此兩個網絡的複雜度應該是相當的(當然這裏的“記住”是形象理解,不是真的強行記住了,不然就是過擬合了);

4. 既然 L1 是真僞樣本的分佈差,那麼 L1 越大,意味着“僞造”的樣本質量越好,所以 L1 同時也指示着 GAN 訓練的進程,L1 越大,訓練得越好。(D 希望 L1 越小越好,G 希望 L1 越大越好,當然是 G 希望的結果,纔是我們希望的。其實也可以這樣理解,G 的損失 L2,其實就相當於 −L1,但是因爲 D 的權重已經固定了,所以有關真實樣本那一項是個常數,因此只剩下僞造樣本那一項,即 L2,但 L2 是個絕對值,我們關心的是相對值,所以 −L1 是我們關心的,它越小越好,相當於 L1 越大越好。)

7

別走,還沒完

稍微思考一下,我們就發現,問題還沒完。我們目前還沒有對 D 做約束,不難發現,無約束的話 Loss 基本上會直接跑到負無窮去了。

因此,有必要給 D 加點條件,一個比較容易想到的方案是約束 D 的範圍,比如能不能給 D 最後的輸出加個 Sigmoid 激活函數,讓它取值在 0 到 1 之間?事實上這個方案在理論上是沒有問題的,然而這會造成訓練的困難。因爲 Sigmoid 函數具有飽和區,一旦 D 進入了飽和區,就很難傳回梯度來更新 G 了。

最好加什麼約束呢?我們應該儘可能從基本原理出發來找尋約束,儘量避免加入人工因素。我們回到距離的作用上來看:距離是爲了表明兩個對象的差距,而如果對象產生的微小的變化,那麼距離的波動也不能太大,這應該是對距離基本的穩定性要求,“失之毫釐,謬以千里”是會產生渾沌的,數學模型不應該是這樣。從這個角度來看,那個所謂的“JS 距離”,根據就不是距離了,因爲就算對於伯努利分佈 {0:0.1,1:0.9} 和 {0:0,1:1},這兩個相似的分佈算出來的“距離”居然是無窮大(因爲出現了 0.1/0 這一項)。

放到我們的 D 中,這個約束我們該怎麼體現呢?假如某個樣本不是 yi 而是 y′i,假設 ‖yi−y′i‖(用兩豎表示歐式距離,因爲 y 可能是個多元向量)並不是十分大,那麼會對分佈造成一定的影響。這個影響有多大呢?顯然不會大,因爲分佈是一批樣本的統計特徵,如果只是稍微改變了一個樣本,那麼分佈的變化顯然不能大的。而我們知道,分佈的距離用 D 的均值 L 來描述,只改變一個 yi,所造成的分佈差正比於:

我們希望 yi′→yi 時,自然地就有怎麼實現這一點呢?一個簡單的方案是 D 滿足以下約束:

這裏 α>0,而最簡單的方案就是:

這就是數學中常見的 Lipschitz 約束。如果能夠滿足這個約束,那麼距離就能滿足穩定性要求。注意這是個充分條件,不是必要條件,也可以使用其他方案。但不得不說,這是個簡單明瞭的方案。而使得函數 D 滿足 Lipschitz 約束的一個充分條件就是:

8

“罰”出來的成果

當然懲罰是“軟約束”,最終的結果不一定滿足這個約束,但卻會在約束上下波動。也就是說雖然我們指定了 C=1,但最終的 C 卻不一定等於 1,不過會在 1 上下波動,而這也不過是一個更寬鬆的 Lipschitz 約束而已,我們不在乎 C 的具體大小,只要 C 有上界就好。另外,約束的加法不是唯一的,WGAN 的作者 Martin Arjovsky 在他的論文中提出的加法爲:

哪個好?實驗結果好像都差不多。

不過,上面的懲罰項都是形式而已,我們還沒給出具體的計算方法。理論上最好能夠對所有的 y(全空間)都算一遍

然後取平均,顯然這是做不到的。那麼只好用一個退而求其次的方案:只對真實樣本 zi 和生成樣本 yi 算。但這樣約束範圍貌似也太小了,所以乾脆在真實樣本和生成樣本之間隨機插值,希望這個約束可以“佈滿”真實樣本和生成樣本之間的空間,即:

以及:

這裏的 εi 是 U[0,1] 的隨機數,這應該已經是我們“力所能及”的最優的方案了。後面這個就是 Martin Arjovsky 提出的最新的 Lipschitz 約束的方案,而實驗結果表明前一個方案效果也不錯。目前它們的大名叫“WGAN-GP”,全稱 Wasserstein Generative Adversarial Nets - Gradient Penalty。

最後,有人會反駁,梯度有上界,只不過是 Lipschitz 約束的充分條件,爲啥不直接將 Lipschitz 約束以差分形式加入到懲罰中去呢?(其實有這個疑問的最主要的原因,是很多深度學習框架並沒有提供梯度函數;另外,儘管 tensorflow 提供了梯度函數,但如果判別器用的是 RNN,那麼梯度函數也是不可用的。)事實上,這樣做某種意義上更加合理,我覺得 Martin Arjovsky 直接用梯度,不過是想寫得簡單一點,這時候懲罰是:

以及:

這裏 yi,j=εi,jyi+(1−εi,j)zi,也就是每步插值兩次,然後用插值的結果算差分。

9

然後呢?

暫時沒有然後了,終於寫完了。這便是我理解的 GAN。

通過本文,我們可以一氣呵成地直達 WGAN-GP,而不需要很多的歷史知識和數學知識。有趣的是,我們的推導過程表明,WGAN-GP 其實跟 Wasserstein 距離沒有直接的聯繫,儘管當初 WGAN 的作者是從 Wasserstein 距離將它們推導出來的。也就是說,WGAN 跟 W 沒啥關係,這就尷尬了。另外,有人提問“WGAN 相比原始的 GAN 有什麼優勢?”,如果根據本文的理論推導,那麼原始的 GAN 根本就不是 GAN,因爲它不能改寫爲本文的某個特例。(原因在於,本文的推導基於分佈的擬合,而原始 GAN 的推導基於博弈論,出發點不同。)

這個 Loss 還有一定的改進空間,比如 Loss Sensitive GAN(LS-GAN),還有更廣義的 CLS-GAN(將 LS-GAN 和 WGAN 統一起來了),這些推廣我們就不討論了。不過這些推廣都建立在 Lipschitz 約束之上,只不過微調了 Loss,也許未來會有人發現比 Lipschitz 約束更好的對 D 的約束。

10

WGAN-GP 的例子

最後,分享一個 WGAN-GP 的實現,以 MNIST爲 數據集,讀者可以自己改着玩:

https://github.com/bojone/gan/

訓練進度顯示:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章