過去幾年發表於各大 AI 頂會論文提出的 400 多種算法中,公開算法代碼的僅佔 6%,其中三分之一的論文做者分享了測試數據,約 54% 的分享包含「僞代碼」。這是今年 AAAI 會議上一個嚴峻的報告。 人工智能這個蓬勃發展的領域正面臨着實驗重現的危機,就像實驗重現問題過去十年來一直困擾着心理學、醫學以及其餘領域同樣。最根本的問題是研究人員一般不共享他們的源代碼。 javascript
可驗證的知識是科學的基礎,它事關理解。隨着人工智能領域的發展,打破不可復現性將是必要的。爲此,PaperWeekly 聯手百度 PaddlePaddle 共同發起了本次論文有獎復現,咱們但願和來自學界、工業界的研究者一塊兒接力,爲 AI 行業帶來良性循環。java
做者丨黃濤 算法
學校丨中山大學數學學院18級本科生網絡
研究方向丨圖像識別、VQA、生成模型和自編碼器app
論文復現代碼: 函數
http://aistudio.baidu.com/#/projectdetail/23600post
GAN
生成對抗網絡(Generative Adversarial Nets)是一類新興的生成模型,由兩部分組成:一部分是判別模型(discriminator)D(·),用來判別輸入數據是真實數據仍是生成出來的數據;另外一部分是是生成模型(generator)G(·),由輸入的噪聲生成目標數據。GAN 的優化問題能夠表示爲:學習
其中 Pdata 是生成樣本,noise 是隨機噪聲。而對於帶標籤的數據,一般用潛碼(latent code)c 來表示這一標籤,做爲生成模型的一個輸入,這樣咱們有:測試
然而當咱們遇到存在潛在的類別差異而沒有標籤數據,要使 GAN 可以在這類數據上擁有更好表現,咱們就須要一類可以無監督地辨別出這類潛在標籤的數據,InfoGAN 就給出了一個較好的解決方案。fetch
互信息(Mutual Information)
互信息是兩個隨機變量依賴程度的量度,能夠表示爲:
要去直接優化 I(c;G(z,c)) 是極其困難的,由於這意味着咱們要可以計算後驗機率(posterior probability)P(c|x),可是咱們能夠用一個輔助分佈(auxiliary distribution)Q(c|x),來近似這一後驗機率。這樣咱們可以給出互信息的一個下界(lower bounding):
InfoGAN
在 InfoGAN 中,爲了可以增長潛碼和生成數據間的依賴程度,咱們能夠增大潛碼和生成數據間的互信息,使生成數據變得與潛碼更相關:
▲ 圖1. InfoGAN的總體結構圖
由上面的,對於一個極大化互信息的問題轉化爲一個極大化互信息下界的問題,咱們接下來就能夠定義:
在論文的附錄中,做者證實了:
因而:
故 LI (G, Q) 是互信息的一個下界。做者指出,用蒙特卡羅模擬(Monte Carlo simulation)去逼近 LI (G, Q) 是較爲方便的,這樣咱們的優化問題就能夠表示爲:
實現
在實現中,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) 能夠表示爲:
其中 · 表示內積(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) 無關:
而對於參數潛碼,咱們假設它符合正態分佈,神經網絡 Q(x) 則輸出其預測出的該潛碼的均值和標準差, 咱們知道,對於均值 μ,標準差 σ 的隨機變量,其機率密度函數爲:
要計算參數潛碼 c 的,就是要計算 log p(c),即:
設 Q(x) 輸出的參數潛碼 c 的均值 μ,標準差 σ 分別爲 Q(x)μ 和 Q(x)σ,那麼對於參數潛碼 c:
一樣的,咱們能夠消去 H(c),由於 c 的分佈是固定的,那麼:
實驗
首先,經過和普通的 GAN 比較 LI ,做者證實了 InfoGAN 確實可以優化這一互信息的下界 2。
做者在 MNIST 手寫數字數據集(3)、3D 面部數據集(4)、3D 椅子數據集(5)、SVHN 街景房號數據集(6)以及 CelebA 人臉數據集(7)上進行了模型的相關測試。
▲ 圖2. MNIST手寫字符數據集上的結果
▲ 圖3. 3D面部數據集上的結果
▲ 圖4. 3D椅子數據集上的結果
▲ 圖5. SVHN街景房號數據集上的結果
▲ 圖6. CelebA人臉數據集上的結果
做者展現了這些數據集上學習到的類別潛碼(從上至下變化)和參數潛碼(從左至右變化,由 -2 到 2),咱們能夠看出,InfoGAN 不只可以很好地學習數據之間的類型差異,也可以很好地學習到數據自己的一些易於區分的特色,並且生成模型對這些特色的泛化能力仍是很好的。
再論InfoGAN的LI
讀完論文,咱們發現,對於類別潛碼,這個 LI 本質上是 x 與 G(z, c) 之間的 KL 散度:
也就是說:
而 min DKL(c||Q(G(z, c))) 意味着減少 c 與 Q(G(z, c)) 的差異。
▲ 圖7. 普通GAN和InfoGAN的LI在訓練過程當中的比較
若是咱們不考慮 Q(x)σ 的影響,LI 的優化過程:
而也意味着減少 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 的優化問題能夠表示爲:
其中 Pdata 是生成樣本,noise 是隨機噪聲。咱們用一個雙層的 MLP 來演示:
一般,一個 GAN 的訓練由兩部分組成,第一部分是對 D(·) 進行訓練,極大化目標函數:
第二部分是對 G(·) 進行訓練,極小化目標函數:
如下是兩部分優化的定義:
在定義好這些以後,是時候開訓練了:
若欲測試模型效果,可再定義一個 Inference:
而後再這樣獲取 samples:
後記
本文先前於今年 8 月完成,共享於 PaddlePaddle 論文復現羣內,在 10 月 LSGAN 的復現公開之 後,參考該復現更改了模型參數命名和參數列表的實現方法,在此感謝 Todd 同窗的復現對本文的幫助。
轉載來源:PaperWeekly
本文分享 CSDN - 飛槳PaddlePaddle。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。