GAN畢業手冊:從零到一構建本身的GAN模型

圖片

MNIST 數據集的隱空間可視化html

生成對抗網絡(GAN)的能力已經超乎公衆的想象——由 AI 生成的名人照片 影響了流行文化,創造的藝術品在高級藝術品拍賣會上 售出了數千美圓的價格。git

在本文中,咱們將探討:github

  • GAN 的簡要介紹ubuntu

  • 瞭解和評價 GAN瀏覽器

  • 運行你本身的 GAN網絡

如今網絡上有大量的 GAN 學習資源,所以本文的重點是瞭解如何評價 GAN。咱們還將引導讀者經過運行本身的 GAN,來生成像 MNIST 數據集那樣的手寫數字。app

圖片

GAN 的訓練過程圖,從圖中能夠看出生成的手寫數字隨着訓練過程變得愈來愈真實機器學習

GAN 入門ide

自 2014 年 Ian Goodfellow 的 《生成對抗網絡(Generative Adversarial Networks)》 論文發表以來,GAN 的進展日新月異,生成結果也愈來愈具備照片真實感。post

就在三年前,Ian Goodfellow 在 reddit 上回答 GAN 是否能夠應用在文本領域的問題 時,還認爲 GAN 不能擴展到文本領域。

圖片

Ian Goodfellow 在 Reddit 上針對 GAN 問題的回答

「因爲 GAN 定義在實值數據上,所以 GAN 不能應用於 NLP。

GAN 的工做原理是訓練一個生成網絡,輸出合成數據,而後利用判別網絡判別合成數據。判別網絡根據合成數據輸出的梯度告訴你該如何對合成數據進行微調,使其更真實。

所以只有當合成數據是基於連續數字時,才能對其進行微調。若是是基於離散的數字,就沒有辦法作微小的改變。

例如,若是輸出像素值爲 1.0 的圖像,則下一步能夠將該像素值更改成 1.0001。

但若是輸出單詞‘penguin’,不能在下一步直接將其更改成‘penguin+.001’,由於沒有‘penguin+.001’這樣的單詞。你必須從‘penguin’直接轉變到‘ostrich’。

因爲全部的 NLP 都是基於離散的值,如單詞、字符或字節,因此目前尚未人知道該如何將 GAN 應用於 NLP。」

可是如今,GAN 已經可用於生成各類內容,包括圖像、視頻、音頻和 文本。這些輸出的合成數據既能夠用於訓練其餘的模型,也能夠用於建立一些有趣的項目,如 thispersonnesnotexist.com(這我的不存在)、thisairbnbdoensotexist.com(這家酒店不存在),甚至 This Machine Learning Medium post does not exist(這個機器學習帖子不存在)。

GAN 原理

GAN 由兩個神經網絡組成,一個是合成新樣本的生成器,另外一個是對比訓練樣本與生成樣本的 判別器。判別器的目標是區分「真實」和「虛假」的輸入(對樣原本自模型分佈仍是真實分佈進行分類)。這些樣本能夠是圖像、視頻、音頻片斷和文本。

圖片

GAN 概覽

爲了合成這些新的樣本,生成器的輸入爲隨機噪聲,而後嘗試從訓練數據中學習到的分佈中生成真實的圖像。

判別器網絡(卷積神經網絡)輸出相對於合成數據的梯度,其中包含着如何改變合成數據以使其更具真實感的信息。最終生成器收斂,它能夠生成符合真實數據分佈的樣本,而判別器沒法區分生成數據和真實數據。

GAN Lab 是一個能夠在瀏覽器上訓練 GAN 的項目,能夠利用這個項目查看網絡訓練過程當中數據分佈逐漸收斂的動畫過程。

這裏給你們推薦一些 GAN 的精選介紹指南:  

  • 斯坦福 cs231,Lecture13——生成模型:https://www.youtube.com/watch?v=5WoItGTWV54

  • 基於風格的 GAN:https://www.lyrn.ai/2018/12/26/a-style-based-generator-architecture-for-generative-adversarial-networks/

  • 理解生成對抗網絡:https://towardsdatascience.com/understanding-generative-adversarial-networks-gans-cd6e4651a29

  • 生成對抗網絡簡介:https://heartbeat.fritz.ai/introduction-to-generative-adversarial-networks-gans-35ef44f21193

  • Lillian Weng:從 GAN 到 WGAN:https://lilianweng.github.io/lil-log/2017/08/20/from-GAN-to-WGAN.html

  • 深刻高級 GAN:探索自注意力和譜歸一化:https://medium.freecodecamp.org/dive-head-first-into-advanced-gans-exploring-self-attention-and-spectral-norm-d2f7cdb55ede

  • Guim Perarnau:神奇 GAN 在哪裏:http://guimperarnau.com/blog/2017/03/Fantastic-GANs-and-where-to-find-them

瞭解和評價 GAN

量化 GAN 的表現讓人感受是個很是主觀的問題——「這張生成的臉看起來夠真實嗎?」,「這些生成的圖像足夠多樣化嗎?」——GAN 就像是黑匣子,咱們不清楚模型的哪些部分會影響學習過程或結果的質量。

爲此,麻省理工學院計算機科學與人工智能實驗室(CSAIL)的一個小組最近發表了一篇論文 《GAN 解剖:可視化和理解生成對抗網絡(GAN Dissection: Visualizing and Understanding Generative Adversarial Networks)》,其中介紹了一種可視化 GAN 的方法,而且分析了 GAN 單元如何與圖像中的對象相關聯,以及對象之間的關係。

該論文采用基於分割的網絡解析方法,對生成神經網絡的內部原理進行了分析和可視化。經過尋找 GAN 單元(神經元)和輸出圖像中的概念(如樹、天空、雲等)之間的一致性,咱們可以鑑別出負責特定對象(如建築物或雲)的神經元。

圖片

經過干擾特定的 GAN 單元進行圖像修改

經過強制激活和凍結(消除)這些對象的對應神經元,能夠從這種粒度級別控制神經元,對生成圖像進行編輯(例如,添加或刪除圖像中的樹)。

然而,咱們如今還不清楚網絡是否可以解釋場景中的對象,或者網絡只是記憶這些對象。回答這個問題一個方法是用不實際的方式對圖像進行變形。MIT CSAIL 給出了一個 GAN 繪畫交互網頁演示,其中最使人印象深入的是,模型彷佛可以將這些人爲編輯限制在「真實照片」的變化範圍內。若是你試圖把草地強行畫在天空上,會發生如下狀況:

圖片

GAN Paint 交互式頁面

儘管咱們激活了相應的神經元,但看起來好像 GAN 後面幾層的神經元抑制了相應的信號。

圖片

對象的局部上下文對合成對象可能性的影響(在圖中,在建築物上生成門的機率比在樹上或天空中生成門的機率要高).

另外一個可視化 GAN 的方法是進行 隱空間插值(GAN 經過從所學的隱空間採樣生成新的實例)。這是查看生成樣本之間的轉換是否平滑的一種有效方法。

圖片

隱空間插值

雖然這些可視化方法可以幫助咱們理解 GAN 的內部表示,可是如何找到量化的方法來理解 GAN 的訓練過程和輸出質量仍然是一個活躍的研究方向。

衡量生成圖像質量和多樣性的兩個經常使用評價指標是:起始分數(Inception Score,IS)和Fréchet 初始距離(Fréchet Inception Distance, FID)。在論文 《關於起始分數的筆記(A Note on the Inception Score)》 指出了前者的重要缺點以後,大多數研究人員已經從 IS 轉向了 FID。

Inception Score

IS 由 Salimans 等人在 2016 年的論文 《訓練 GAN 的技術改進(Improved Techniques for Training GANs)》 中提出。Inception Score 的提出受到一個觀點的啓發,即真實樣本應該能被預訓練的分類網絡分類,例如預訓練的 ImageNet 網絡。從技術層面來說,樣本的 softmax 預測矢量的熵應該較低。

除了高可預測性(低熵),Inception Score 也從生成樣本的多樣性對 GAN 進行評價(例如生產樣本分佈的方差或熵較高),這意味着分類結果中不該該出現任何佔支配性的類別。

若是這兩個特色都知足,Inception Score 的值就會很高。將這兩個標準結合起來的方法是計算樣本的條件標籤分佈與全部樣本的邊緣分佈之間的 KL 散度。

Fréchet Inception Distance

FID 由 Heusel 等人 在 2017 年提出,FID 經過測量圖像生成分佈和真實分佈之間的距離來衡量生成樣本的真實性。FID 經過 Inception Net 的一個特殊層將一組生成的樣本嵌入特徵空間。該嵌入層能夠被視爲一個連續的多元高斯分佈,而後計算生成數據和真實數據的平均值和協方差。這兩個高斯分佈之間的 Fréchet 距離(即 Wasserstein-2 距離)能夠對生成樣本的質量進行量化。FID 較低,則表明生成樣本與真實樣本更類似。

重要的一點是,FID 須要必定的樣本數量才能獲得良好的結果(建議 50K 個樣本)。若是使用的樣本數量太少,就會出現過分估計,而且估計值會有很大的方差。

Neal Jean 的博客中對比了不一樣論文中的 Inception Score 和 FID 分數:https://nealjean.com/ml/frechet-inception-distance/

瞭解更多

Aji Borji 的論文 《GAN 評價策略的好與壞(Pros and Cons of GAN Evaluation Measures)》 中給出了一個更全面的表格,涵蓋了更多的 GAN 評價指標:

圖片

經常使用 GAN 評價指標總結表格

有趣的是,其餘研究人員並無採用這兩種方法,而是採用了其研究領域特定的評價指標。 對於文本 GAN,Guy Tevet 和他的團隊在論文 《將文本 GAN 做爲語言模型進行評價(Evaluating Text GANs as Language Models)》 中提出,使用傳統的基於機率的語言模型指標來評價 GAN 生成文本的分佈。

在論文 《個人 GAN 有多好(How good is my GAN)》 中,Konstantin Shmelkov 和他的團隊使用了兩種基於圖像分類的評價指標:GAN 訓練和 GAN 測試,分別估算 GAN 的召回率(多樣性)和準確率(圖像質量)。你能夠在 Google Brain 的研究論文 《GAN 是生而平等的嗎?(Are GANs created equal)》 中看到這些評價指標的實際應用,他們使用三角形數據集來測量不一樣 GAN 模型的精度和召回率。

圖片

三角形數據集衡量不一樣 GAN 的精度和召回率

運行你本身的 GAN

爲了進一步介紹 GAN,咱們採用了來自 Wouter Bulten 的 教程,該教程使用 Keras 和 MNIST 數據集訓練 GAN,生成手寫數字。(完整筆記連接:https://gist.github.com/ceceshao1/935ea6000c8509a28130d4c55b32fcd6)

圖片

咱們對損失和準確率曲線進行可視化,而且經過 Comet.ml 檢查輸出,來記錄 GAN 的訓練過程。

該 GAN 模型將 MNIST 訓練數據和隨機噪聲做爲輸入(噪聲的隨機矢量)來生成如下內容:

  • 圖像(在本例中,爲手寫數字的圖像)。最終,這些生成的圖像將模擬 MNIST 數據集的數據分佈。

  • 判別器對生成圖像的預測。

生成器判別器 一塊兒構成對抗模型,在本例中,若是對抗模型將生成的圖像分類爲真實圖像,說明生成器訓練良好。

完整代碼連接:

https://gist.github.com/ceceshao1/935ea6000c8509a28130d4c55b32fcd6

完整實驗結果連接:

https://www.comet.ml/ceceshao1/mnist-gan

記錄模型的進度

咱們可使用 Comet.ml 記錄 生成器判別器 模型的訓練進度。

咱們爲判別器和對抗模型繪製準確率和損失曲線圖,兩個須要記錄的最重要的指標以下:

  • 判別器損失(見右圖藍線)-dis_loss

  • 對抗模型的準確率(見左圖藍線)-acc_adv

實驗訓練過程連接:

https://www.comet.ml/ceceshao1/mnist-gan/cf310adacd724bf280323e2eef92d1cd/chart

圖片

判別器和對抗模型的損失和精度曲線圖

還須要確認訓練過程使用的是 GPU,能夠在 Comet 系統指標選項卡 中檢查這一項。

圖片

GPU 內存和使用狀況

請注意,咱們的訓練代碼中包括從測試向量中顯示圖像的代碼:  

if i % 500 == 0:
# Visualize the performance of the generator by producing images from the test vector
images = net_generator.predict(vis_noise)
# Map back to original range
#images = (images + 1 ) * 0.5
plt.figure(figsize=(10,10))

for im in range(images.shape[0]):
plt.subplot(44, im+1)
image = images[im, :, :, :]
image = np.reshape(image, [2828])

plt.imshow(image, cmap='gray')
plt.axis('off')

plt.tight_layout()
# plt.savefig('/home/ubuntu/cecelia/deeplearning-resources/output/mnist-normal/{}.png'.format(i))
plt.savefig(r'output/mnist-normal/{}.png'.format(i))
experiment.log_image(r'output/mnist-normal/{}.png'.format(i))
plt.close('all')

咱們每隔幾步顯示生成的圖像,部分緣由是爲了讓咱們可以更直觀地分析生成器在生成手寫數字方面的表現,以及判別器將生成的數字進行正確分類的表現。

讓咱們看看這些生成的輸出!

在這個 Comet 實驗 中,你能夠看到生成的輸出圖像。

能夠看到生成器模型是從這個模糊的、灰色的輸出(下面的 0.png)開始的,它看起來徹底不像咱們所指望的手寫數字。

圖片

隨着訓練的進展,模型的損失降低,生成的數字變得愈來愈清晰。在不一樣步數生成的輸出:

步數 500:

圖片

步數 1000:

圖片

步數 1500:

圖片

最後,在 步數 10000 時,下圖紅框標出了一些 GAN 生成的手寫數字示例。

圖片

一旦 GAN 模型完成了訓練,咱們能夠在 Comet 的 圖形選項卡 中查看由輸出組成的動畫,只須要按下播放按鈕便可。

圖片

要完成實驗,請確保運行 experiment.end(),能夠查看有關模型和 GPU 使用狀況的一些統計信息。

圖片

模型迭代

咱們能夠增長模型的訓練時間,觀察它對性能的影響,可是首先讓咱們嘗試使用一些不一樣的參數進行模型迭代。

咱們調整的參數包括:

  • 判別器的優化器

  • 學習率

  • dropout 隨機失活率

  • batchsize 批尺寸

Wouter 在本身的 博客文章 中,提到了他在測試參數方面作的工做:

「我測試了 SGD、RMSprop 和 Adam 做爲判別器的優化器的效果,其中 RMSprop 的性能最好。RMSprop 的學習率很低,我將學習率的值壓縮到 -1 和 1 之間。學習速率的輕微衰減有助於網絡穩定。」

咱們嘗試將判別器的 dropout 隨機失活率從 0.4 提升到 0.5,並同時提升判別器的學習率(從 0.008 提升到 0.0009)和生成器的學習率(從 0.0004 提升到 0.0006)。很容易看到這些變化對訓練形成的影響。

要建立一個不一樣的實驗,只需再次運行實驗定義單元,Comet 將爲你的新實驗分配一個新的 url。記錄下每次的實驗是一個好習慣,能夠方便比較不一樣之處:

圖片

不幸的是,咱們的調整沒有提升模型的性能,反而獲得了一些奇怪的輸出圖像:

圖片

相關文章
相關標籤/搜索