經典論文復現 | InfoGAN:一種無監督生成方法

過去幾年發表於各大 AI 頂會論文提出的 400 多種算法中,公開算法代碼的僅佔 6%,其中三分之一的論文做者分享了測試數據,約 54% 的分享包含「僞代碼」。這是今年 AAAI 會議上一個嚴峻的報告。 人工智能這個蓬勃發展的領域正面臨着實驗重現的危機,就像實驗重現問題過去十年來一直困擾着心理學、醫學以及其餘領域同樣。最根本的問題是研究人員一般不共享他們的源代碼。 javascript


可驗證的知識是科學的基礎,它事關理解。隨着人工智能領域的發展,打破不可復現性將是必要的。爲此,PaperWeekly 聯手百度 PaddlePaddle 共同發起了本次論文有獎復現,咱們但願和來自學界、工業界的研究者一塊兒接力,爲 AI 行業帶來良性循環。java


做者丨黃濤 算法

學校丨中山大學數學學院18級本科生網絡

研究方向丨圖像識別、VQA、生成模型和自編碼器app


640?


論文復現代碼: 函數


http://aistudio.baidu.com/#/projectdetail/23600post


GAN


生成對抗網絡(Generative Adversarial Nets)是一類新興的生成模型,由兩部分組成:一部分是判別模型(discriminator)D(·),用來判別輸入數據是真實數據仍是生成出來的數據;另外一部分是是生成模型(generator)G(·),由輸入的噪聲生成目標數據。GAN 的優化問題能夠表示爲:學習


640


其中 Pdata 是生成樣本,noise 是隨機噪聲。而對於帶標籤的數據,一般用潛碼(latent code)c 來表示這一標籤,做爲生成模型的一個輸入,這樣咱們有:測試


640?


然而當咱們遇到存在潛在的類別差異而沒有標籤數據,要使 GAN 可以在這類數據上擁有更好表現,咱們就須要一類可以無監督地辨別出這類潛在標籤的數據,InfoGAN 就給出了一個較好的解決方案。fetch


互信息(Mutual Information)


互信息是兩個隨機變量依賴程度的量度,能夠表示爲:


640?


要去直接優化 I(c;G(z,c)) 是極其困難的,由於這意味着咱們要可以計算後驗機率(posterior probability)P(c|x),可是咱們能夠用一個輔助分佈(auxiliary distribution)Q(c|x),來近似這一後驗機率。這樣咱們可以給出互信息的一個下界(lower bounding):


640?


InfoGAN


在 InfoGAN 中,爲了可以增長潛碼和生成數據間的依賴程度,咱們能夠增大潛碼和生成數據間的互信息,使生成數據變得與潛碼更相關:


640


640?

 圖1. InfoGAN的總體結構圖


由上面的,對於一個極大化互信息的問題轉化爲一個極大化互信息下界的問題,咱們接下來就能夠定義:


640?


在論文的附錄中,做者證實了:


640?


因而:


640


故 LI (G, Q) 是互信息的一個下界。做者指出,用蒙特卡羅模擬(Monte Carlo simulation)去逼近 LI (G, Q) 是較爲方便的,這樣咱們的優化問題就能夠表示爲:


640?


實現


在實現中,D(x)、G(z, c) 和 Q(x) 分別用一個 CNN (Convolutional Neural Networks)、CNN、DCNN (DeConv Neural Networks) 來實現。同時,潛碼 c 也包含兩部分:一部分是類別,服從 Cat(K = N,p = 1/N),其中 N 爲類別數量;另外一部分是連續的與生成數據有關的參數,服從 Unif(−1,1) 的分佈。 


在此應指出,Q(c|x) 能夠表示爲一個神經網絡 Q(x) 的輸出。對於輸入隨機變量 z 和類別潛碼 c,實際的 LI(G, Q) 能夠表示爲:


640?


其中 · 表示內積(inner product),c 是一個選擇計算哪一個 log 的參數,例如 ci = 1 而 cj = 0(∀j = 1,2,···,i − 1,i + 1,···,n),那麼 z 這時候計算出的 LI(G,Q) 就等於 log(Q(z,c)i)。這裏咱們能夠消去 H(c),由於 c 的分佈是固定的,即優化目標與 H(c) 無關:


640?


而對於參數潛碼,咱們假設它符合正態分佈,神經網絡 Q(x) 則輸出其預測出的該潛碼的均值和標準差, 咱們知道,對於均值 μ,標準差 σ 的隨機變量,其機率密度函數爲:


640


要計算參數潛碼 c 的640,就是要計算 log p(c),即:


640


設 Q(x) 輸出的參數潛碼 c 的均值 μ,標準差 σ 分別爲 Q(x)μ 和 Q(x)σ,那麼對於參數潛碼 c:


640?


一樣的,咱們能夠消去 H(c),由於 c 的分佈是固定的,那麼:


640?


實驗


首先,經過和普通的 GAN 比較 LI ,做者證實了 InfoGAN 確實可以優化這一互信息的下界 2。 


做者在 MNIST 手寫數字數據集(3)、3D 面部數據集(4)、3D 椅子數據集(5)、SVHN 街景房號數據集(6)以及 CelebA 人臉數據集(7)上進行了模型的相關測試。 


640?

 圖2. MNIST手寫字符數據集上的結果


640?

 圖3. 3D面部數據集上的結果


640?

 圖4. 3D椅子數據集上的結果


640

 圖5. SVHN街景房號數據集上的結果


640?

 圖6. CelebA人臉數據集上的結果


做者展現了這些數據集上學習到的類別潛碼(從上至下變化)和參數潛碼(從左至右變化,由 -2 到 2),咱們能夠看出,InfoGAN 不只可以很好地學習數據之間的類型差異,也可以很好地學習到數據自己的一些易於區分的特色,並且生成模型對這些特色的泛化能力仍是很好的。


再論InfoGAN的LI


讀完論文,咱們發現,對於類別潛碼,這個 LI 本質上是 x 與 G(z, c) 之間的 KL 散度:


640?


也就是說:


640?


而 min DKL(c||Q(G(z, c))) 意味着減少 c 與 Q(G(z, c)) 的差異。


640?

 圖7. 普通GAN和InfoGAN的LI在訓練過程當中的比較


若是咱們不考慮 Q(x)σ 的影響,LI 的優化過程:


640?


640?也意味着減少 c 與 Q(G(z, c))μ 的差。


再縱觀整個模型,咱們會發現這一對 LI 優化的過程,實質上是以 G 爲編碼器(Encoder), Q 爲解碼器(Decoder),生成的圖像做爲咱們要編碼的碼(code),訓練一個自編碼器(Autoencoder),也就是說,做者口中的信息論優化問題,本質上是無監督訓練問題。


關於PaddlePaddle


PaddlePaddle 中,一個極爲重要的概念便是 fluid.Program(),在官方文檔裏常見的 exe.run(program= fluid.default_startup_program())的 fluid.default_startup_program() 就是其中一個例子。


在這一使用中能夠了解到,咱們要用 exe.run() 中的 program 參數運行指定的 fluid.Program(),而官方文檔指出,當該參數未指定時,會運行 fluid.default_main_program(),而 fluid.default_main_program() 表明的是未指定 fluid.Program() 的全部操做


注意,這裏說的是「全部」,因爲 PaddlePaddle 沒有計算依賴檢測機制,即便在計算 fetch_list 中的值的時候不會用到操做也會被計算,這一點與 TensorFlow 極其不一樣,做者本人在使用過程當中踩了很大的坑,還望各位注意。在執行多種任務的時候不要一股腦所有寫在 fluid.default_main_program() 之中, 這樣極其浪費資源,也容易形成一些問題。


一個新的 fluid.Program() 被建立以後,能夠在 fluid.program_guard() 中指定該 fluid.Program() 中的操做與變量:


 
  


PaddlePaddle 中還須要注意的一點是,fluid.Variable 的命名空間是全局的,也就是說在同一或者不一樣 fluid. Program() 間,同名(fluid.Variable 的 name 屬性相同)的 fluid.Variable 所指向的變量是相同的,因此同一名稱在同一或者不一樣 fluid.Program () 中能夠被使用屢次,而不用擔憂 TensorFlow 中會出現的 reuse 問題。 


要對一個操做的中的權值的名稱進行定義(權值命名爲 W1,偏置命名爲 b1):


 
  


要在以後使用這些 fluid.Variable,例如在 Optimizer 中使用:


 
  


在構建完基本的運算操做後,即可以開始初始化操做了:


 
  


初始化完成後,能夠開始訓練啦:


 
  


GAN實現


生成對抗網絡(Generative Adversarial Nets)是一類新興的生成模型,由兩部分組成:一部分是判別模型(discriminator)D(·),用來判別輸入數據是真實數據仍是生成出來的數據;另外一部分是是生成模型(generator)G(·),由輸入的噪聲生成目標數據。GAN 的優化問題能夠表示爲:


640?


其中 Pdata 是生成樣本,noise 是隨機噪聲。咱們用一個雙層的 MLP 來演示:


 
  


一般,一個 GAN 的訓練由兩部分組成,第一部分是對 D(·) 進行訓練,極大化目標函數:


640?


第二部分是對 G(·) 進行訓練,極小化目標函數:


640?


如下是兩部分優化的定義:


 
  


在定義好這些以後,是時候開訓練了:


 
  


若欲測試模型效果,可再定義一個 Inference:


 
  


而後再這樣獲取 samples:


 
  


後記


本文先前於今年 8 月完成,共享於 PaddlePaddle 論文復現羣內,在 10 月 LSGAN 的復現公開之 後,參考該復現更改了模型參數命名和參數列表的實現方法,在此感謝 Todd 同窗的復現對本文的幫助。


640?


轉載來源:PaperWeekly


640?wx_fmt=png

本文分享 CSDN - 飛槳PaddlePaddle。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索