看完立刻理解GAN!初學者也沒關係

2020-12-25 雷鋒網

雷鋒網(公眾號:雷鋒網)按:本文原作者天雨粟,原文載於作者的知乎專欄——機器不學習,雷鋒網經授權發布。

前言

GAN 從 2014 年誕生以來發展的是相當火熱,比較著名的 GAN 的應用有 Pix2Pix、CycleGAN 等。本篇文章主要是讓初學者通過代碼了解 GAN 的結構和運作機制,對理論細節不做過多介紹。我們還是採用 MNIST 手寫數據集(不得不說這個數據集對於新手來說非常好用)來作為我們的訓練數據,我們將構建一個簡單的 GAN 來進行手寫數字圖像的生成。

認識 GAN

GAN 主要包括了兩個部分,即生成器 generator 與判別器 discriminator。生成器主要用來學習真實圖像分布從而讓自身生成的圖像更加真實,以騙過判別器。判別器則需要對接收的圖片進行真假判別。在整個過程中,生成器努力地讓生成的圖像更加真實,而判別器則努力地去識別出圖像的真假,這個過程相當於一個二人博弈,隨著時間的推移,生成器和判別器在不斷地進行對抗,最終兩個網絡達到了一個動態均衡:生成器生成的圖像接近於真實圖像分布,而判別器識別不出真假圖像,對於給定圖像的預測為真的概率基本接近 0.5(相當於隨機猜測類別)。

對於 GAN 更加直觀的理解可以用一個例子來說明:造假幣的團夥相當於生成器,他們想通過偽造金錢來騙過銀行,使得假幣能夠正常交易,而銀行相當於判別器,需要判斷進來的錢是真錢還是假幣。因此假幣團夥的目的是要造出銀行識別不出的假幣而騙過銀行,銀行則是要想辦法準確地識別出假幣。

因此,我們可以將上面的內容進行一個總結。給定真 = 1,假 = 0,那麼有:

  • 對於給定的真實圖片(real image),判別器要為其打上標籤 1;

  • 對於給定的生成圖片(fake image),判別器要為其打上標籤 0;

  • 對於生成器傳給辨別器的生成圖片,生成器希望辨別器打上標籤 1。

有了上面的直觀理解,下面就讓我們來實現一個 GAN 來生成手寫數據吧!還有一些細節會在代碼部分進行介紹。

說明

建議將代碼 pull 下來,有部分代碼實現沒有寫在文章中。

代碼部分

數據加載與查看

數據我們使用 TensorFlow 中給定的 MNIST 數據接口。

在構建模型之前,我們首先來看一下我們需要完成的任務:

  • Inputs

  • generator

  • discriminator

  • 定義參數

  • loss  & optimizer

  • 訓練模型

  • 顯示結果

輸入 inputs

輸入函數主要來定義真實圖片與生成圖片兩個 tensor。

定義生成器

我們的生成器結構如下:

我們使用了一個採用 Leaky ReLU 作為激活函數的隱層,並在輸出層加入 tanh 激活函數。

下面是生成器的代碼。注意在定義生成器和判別器時,我們要指定變量的 scope,這是因為 GAN 中實際上包含生成器與辨別器兩個網絡,在後面進行訓練時是分開訓練的,因此我們要把 scope 定義好,方便訓練時候指定變量。

在這個網絡中,我們使用了一個隱層,並加入 dropout 防止過擬合。通過輸入噪聲圖片,generator 輸出一個與真實圖片一樣大小的圖像。

在這裡我們的隱層激活函數採用的是 Leaky ReLU(中文不知道咋翻譯),這個函數在 ReLU 函數基礎上改變了左半邊的定義。

圖片來自維基百科。Andrej Karpathy 在 CS231n 中也提到有模型通過這個函數取得了不錯的效果。

由於 TensorFlow 中沒有這個函數的實現,在這裡我們通過函數定義實現了 Leaky ReLU,其中 alpha 是一個很小的數。在輸出層我們使用 tanh 函數,這是因為 tanh 在這裡相比 sigmoid 的結果會更好一點(在這裡要注意,由於生成器的生成圖片像素限制在了 (-1, 1) 的取值之間,而 MNIST 數據集的像素區間為 [0, 1],所以在訓練時要對 MNIST 的輸入做處理,具體見訓練部分的代碼)。到此,我們構建好了生成器,它通過接收一個噪聲圖片輸出一個與真實圖片一樣 size 的圖像。

定義判別器

判別器的結構如下:

判別器接收一張圖片,並判斷它的真假,同樣隱層使用了 Leaky ReLU,輸出層為 1 個結點,輸出為 1 的概率。代碼如下:

在這裡,我們需要注意真實圖片與生成圖片是共享判別器的參數的,因此在這裡我們留了 reuse 接口來方便我們後面調用。

定義參數

img_size 是我們真實圖片的 size=32*32=784。

smooth 是進行 Label Smoothing Regularization 的參數,在後面會介紹。

構建網絡

接下來我們來構建我們的網絡,並獲得生成器與判別器返回的變量。

我們分別獲得了生成器與判別器的 logits 和 outputs。注意真實圖片與生成圖片是共享參數的,因此在判別器輸入生成圖片時,需要 reuse 參數。

定義 Loss 和 Optimizer

有了上面的 logits,我們就可以定義我們的 loss 和 Optimizer。在這之前,我們再來回顧一下生成器和判別器各自的目的是什麼:

我們來把上面這三句話轉換成代碼:

d_loss_real 對應著真實圖片的 loss,它儘可能讓判別器的輸出接近於 1。在這裡,我們使用了單邊的 Label Smoothing Regularization,它是一種防止過擬合的方式,在傳統的分類中,我們的目標非 0 即 1,從直覺上來理解的話,這樣的目標不夠 soft,會導致訓練出的模型對於自己的預測結果過於自信。因此我們加入一個平滑值來讓判別器的泛化效果更好。

d_loss_fake 對應著生成圖片的 loss,它儘可能地讓判別器輸出為 0。

d_loss_real 與 d_loss_fake 加起來就是整個判別器的損失。

而在生成器端,它希望讓判別器對自己生成的圖片儘可能輸出為 1,相當於它在於判別器進行對抗。

下面我們定義了優化函數,由於 GAN 中包含了生成器和判別器兩個網絡,因此需要分開進行優化,這也是我們在之前定義 variable_scope 的原因。

訓練模型

由於訓練部分代碼太長,我在這裡就不貼出來了,請前往我的 GitHub 下載代碼。在訓練部分,我們記錄了部分圖像的生成過程,並記錄了訓練數據的 loss 變化。

我們將整個訓練過程的 loss 變化繪製出來:

從圖中可以看出來,最終的判別器總體 loss 在 1 左右波動,而 real loss 和 fake loss 幾乎在一條水平線上波動,這說明判別器最終對於真假圖像已經沒有判別能力,而是進行隨機判斷。

查看過程結果

我們在整個訓練過程中記錄了 25 個樣本在不同階段的 samples 圖像,以序列化的方式進行了保存,我們的將 samples 加載進來。samples 的 size=epochs x 2 x n_samples x 784,我們的迭代次數為 300 輪,25 個樣本,因此,samples 的 size=300 x 2 x 25 x 784。我們將最後一輪的生成結果列印出來:

這就是我們的 GAN 通過學習真實圖片的分布後生成的圖像結果。

那麼有同學可能會問了,我們如果想要看這 300 輪中生成圖像的變化是什麼樣該怎麼辦呢?因為我們已經有了 samples,存儲了每一輪迭代的結果,我們可以挑選幾次迭代,把對應的圖像打出來:

這裡我挑選了第 0, 5, 10, 20, 40, 60, 80, 100, 150, 250 輪的迭代效果圖,在這個圖中,我們可以看到最開始的時候只有中間是白色,背景黑色塊中存在著很多噪聲。隨著迭代次數的不斷增加,生成器製造 「假圖」 的能力也越來越強,它逐漸學得了真實圖片的分布,最明顯的一點就是圖片區分出了黑色背景和白色字符的界限。

生成新的圖片

如果我們想重新生成新的圖片呢?此時我們只需要將我們之前保存好的模型文件加載進來就可以啦。

總結

整篇文章基於 MNIST 數據集構造了一個簡單的 GAN 模型,相信小夥伴看完代碼會對 GAN 有一個初步的了解。從最終的模型結果來看,生成的圖像能夠將背景與數字區分開,黑色塊噪聲逐漸消失,但從顯示結果來看還是有很多模糊區域的。

對於這裡的圖片處理,相信很多小夥伴會想到卷積神經網絡,那麼後面我們還會將生成器和判別器改為卷積神經網絡來構造深度卷積 GAN,它對於圖片的生成會取得更好的效果。

如果覺得不錯,請給 GitHub 點個 Star 吧~

雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知。

相關焦點

  • 經典GAN實戰教程:理解並運行自己的GAN生成手寫數字
    、運行自己的GAN3個方面,試圖讓讀者理解生成性對抗性網絡(GAN)研究和評估是如何開發的,然後實現用自己的GAN來生成手寫數字。本文主要是以下3個部分:了解什麼是GAN理解和評估GAN運行自己的GAN希望通過本文,讀者能夠了解如何評估GAN,並最終能夠動手運行自己的GAN生成MNIST等手寫數字。
  • 手把手教你用keras搭建GAN
    致力於為機器學習、深度學習、數據挖掘等AI技術的「初
  • 瑜伽初學者如何自學瑜伽?馬上看懂!
    瑜伽初學者如何自學瑜伽?相信許多的初學者對於瑜伽的認識,剛開始都會有一些問題需要解答,這邊幫助你解決瑜伽上的認知疑問,同時整理出初學者的必備瑜伽用品,以及基本瑜伽熱身動作,幫助初學者以瑜伽書籍、瑜伽教學視頻,或是瑜伽在線課程,來了解瑜伽的實際動作練習和理論概念。瑜伽初學者如何自學瑜伽?
  • 初學者如何正確理解日語漢字
    但很多漢語為母語的初學者往往誤認為日語漢字是漢語的繁體字,意思是一樣的,又誤認為日語漢字發音沒有規律等等。日語裡的漢字並不像我們所想像的那麼容易記憶和理解,很多漢字需要我們重新認識和學習,否則會在理解上出現很多錯誤。日語裡的漢字使用廣泛,種類繁多,很難掌握,所以在日語詞彙的學習中,要特別注意漢字的學習和歸納,正確理解日語漢字。
  • 初學者學習速寫的六大技巧,你掌握了嗎?
    今天給大家分享的內容就是初學者學習速寫要掌握的六大技巧,希望通過今天的分享,大家在今後學習速寫的路上可以走得快一些!初期大量臨摹初學者在開始學習速寫後,由於不懂如何去系統的學習,會糾結先畫人物頭部還是眼睛、還是鼻子、或者是腳。其實這時候這些都不重要,只需要找一些範畫進行臨摹,就可以快速的入門。
  • TF - GAN入門:TensorFlow 2.0 的輕量級 GAN 庫
    具影響力的論文:https://github.com/tensorflow/gan#who-uses-tf-gan今天,各個推出 TF-GAN 的新版本。此版本擁有諸多升級和新功能:Cloud TPU 支持:您現在可以使用 TF-GAN 在 Google 的 Cloud TPU 上訓練 GAN。
  • 初學者如何從零學習人工智慧?看完你就懂了
    (點擊尾部閱讀原文前往)原文:https://medium.com/digitalmind/artificial-intelligence-resources-f4efeac949b4#.ndykohymp此文是想要進入人工智慧這個領域、但不知道從哪裡開始的初學者最佳的學習資源列表
  • 訓練GAN,你應該知道的二三事
    眾所周知,GANs 的訓練尤其困難,筆者自從跳入了 GANs 這個領域(坑),就一直在跟如何訓練 GANs 做「對抗訓練」,受啟發於 ganhacks,並結合自己的經驗記錄總結了一些常用的訓練 GANs 的方法,以備後用。(本篇不是 GANs 的入門掃盲篇,初學者慎入。)
  • 不是每一句對不起,都能換來一句沒關係,看完淚奔
    不是每一句對不起,都能換來一句沒關係,看完淚奔我們每一個人好像真的都傷害過人。一句不經意的話,也許就能讓別人在意,並且覺得很傷心。一件事情,也許自己沒覺得什麼,就無意中的傷害了另一個人。當你去道歉的時候,也許會得不到原諒,畢竟真的傷害過。
  • 能生成Deepfake也能診斷癌症,GAN與惡的距離
    看完視頻是不是發現除了Excel,其他都猜對了。早在2014年,Ian Goodfellow提出了這個革命性的想法——讓兩個神經網絡互相競爭(或合作,這是一個視角問題)。感興趣的同學可以查看Ian Goodfellow 提出GAN時的原文。
  • GAN快速入門資料推薦:17種變體的Keras開原始碼,附相關論文
    乾貨往下看:https://github.com/eriklindernoren/Keras-GANAC-GAN帶輔助分類器的GAN,全稱Auxiliary Classifier GAN。Code:https://github.com/eriklindernoren/Keras-GAN/blob/master/dcgan/dcgan.pyPaper:Unsupervised Representation Learning with
  • 初學者必讀:從迭代的五個層面理解機器學習
    這篇文章是針對初學者寫的,但更有經驗的讀者也不妨一讀。為什麼討論迭代問題?迭代是機器學習的核心概念,它在許多方面至關重要。了解這個簡單的概念在機器學習工作流程中的確切位置,這會帶來很多切實的好處:1. 你能更好地理解算法2. 你能制定出更實際的項目進度時間表3.
  • 初學者如何學好素描?理解這六點很重要!
    很多美術愛好者在剛接觸素描的時候都很迷茫,不懂怎麼去畫,今天給大家分享的就是小編總結的一些關於初學者在初學素描時會遇到的問題,相信看完本次分享的內容後,大家會有所成長的!1.初學素描要做哪些準備初學者需要準備好2H、HB、2B、4B、6B鉛筆即可,還有素描專用的橡皮和素描紙。然後還需要購買畫架和畫板,這些加起來大約80元左右,學習繪畫的成本還是比較低的。
  • 為什麼生完孩子,老人不讓立刻公布喜訊?這些考慮並非沒有道理
    導讀:為什麼生完孩子,老人不讓立刻公布喜訊?這些考慮並非沒有道理各位點開這篇文章的朋友們,想必都是很高的顏值吧,我們真的是很有緣哦,小編每天都會給大家帶來不一樣的育兒資訊,如果對小編的文章或者其他的什麼,有什麼一些意見的話歡迎在下方積極評論哦,小編每條都會認真看的。那麼本期的內容是:為什麼生完孩子,老人不讓立刻公布喜訊?這些考慮並非沒有道理!那麼我們就來看看吧!
  • 百萬會計初學者的好消息-借貸理解四境界
    然而,隨著開學熱情的逐步消退,會計知識的入門將會略顯艱難,其中,最讓初學者痛苦萬分、甚至高年級學生都雲裡霧裡的,一定要算是「借貸」的理解了。今天,川哥將要梳理出理解借貸的四重境界,定會讓你耳目一新。 川哥點評:這就是現行的記帳法則,如何理解「借貸」二字?注意了,千萬別理解,記住就行了,一旦去理解,就誤入歧途了。此種理解方法,晦澀難懂,如在深淵,不見天日。
  • 初學者如何學化妝 正確步驟應該是這樣的
    沒關係,今天小編就為化妝的初學者準備了化妝的步驟教程,新手們趕緊學起來吧。來源:站酷作者:Svetography現在很多女生都會畫個淡妝之後再出門, 精緻的妝容會使她們更加自信。那對於一些化妝新手來說,化妝不知從何下手?
  • 初學者該買什麼價位的民謠吉他,如何定位
    其實要看自己對吉他的興趣,如果對吉他興趣不很大,只是隨便玩玩的話,那建議買把好看的就行了。2. 新手吉他如何選擇才合適?音準:音準是關鍵所在,音準不好,每個音相互幹擾嚴重,就不用去談音色了,對初學者的耳朵也有害處。按吉他的定音標準是調校好各弦後彈出一弦第12品的泛音,假如它與該弦第12品的音高一致則為合格。
  • 基礎| 初學者必讀:從迭代的五個層面理解機器學習
    這篇文章是針對初學者寫的,但更有經驗的讀者也不妨一讀。為什麼討論迭代問題?迭代是機器學習的核心概念,它在許多方面至關重要。了解這個簡單的概念在機器學習工作流程中的確切位置,這會帶來很多切實的好處:1. 你能更好地理解算法2. 你能制定出更實際的項目進度時間表3. 你會發現更容易實現的模型改進方法4.
  • 基礎 初學者必讀:從迭代的五個層面理解機器學習
    這篇文章是針對初學者寫的,但更有經驗的讀者也不妨一讀。為什麼討論迭代問題?迭代是機器學習的核心概念,它在許多方面至關重要。了解這個簡單的概念在機器學習工作流程中的確切位置,這會帶來很多切實的好處:1. 你能更好地理解算法2. 你能制定出更實際的項目進度時間表3.
  • 初學者疑惑:看綜藝動漫學日語是坑?
    但如果仔細想想日語初學者的學習方式,就不難理解為什麼會出現這樣的問題了。經常上網找日語學習攻略的同學應該不難發現一些分享自己學習方法的人有著這樣的觀點:猛看日本綜藝節目,水平從五十音到立馬過了N2。跟著動漫裡面的人物一起講臺詞,不僅有意思,日語水平也進步很快。的確,他們說的話不無道理,這些做法在一定程度上也很適合初學者。