# Generative Adversarial Network(GAN) ###### tags: `學習紀錄` [toc] --- ## Before Meeting :::success Facebook AI 大師 Yann LeCun 在接受Quora專訪時說『GAN及其變形是近十年最有趣的想法(This, and the variations that are now being proposed is the most interesting idea in the last 10 years in ML, in my opinion.)』,我就忍不住想知道它是甚麼東東? 一探究竟,滿篇數學,應用領域又廣,請參閱 gan-zoo,苦讀多日,只懂一點皮毛,還不到小學程度,厚顏僅就所知,作一概念性的介紹。 ::: [refer](https://ithelp.ithome.com.tw/articles/10196257) [refer](https://medium.com/@gau820827/%E6%95%99%E9%9B%BB%E8%85%A6%E7%95%AB%E7%95%AB-%E5%88%9D%E5%BF%83%E8%80%85%E7%9A%84%E7%94%9F%E6%88%90%E5%BC%8F%E5%B0%8D%E6%8A%97%E7%B6%B2%E8%B7%AF-gan-%E5%85%A5%E9%96%80%E7%AD%86%E8%A8%98-tensorflow-python3-dfad71662952) [refer](http://cs231n.github.io/convolutional-networks/) [refer](https://github.com/gau820827/GAN_tutorial) [refer](https://arxiv.org/pdf/1406.2661.pdf) [refer]() --- ## Recent Paper --- ### :::success #### Abstracion - 首先需要大致瞭解GAN的運作模式:這裡面有兩個需要被訓練的model,一個是Discriminator network,另一個是Generator network;我們姑且稱之為偵探和工匠(腦海中第一個浮現的名詞,爬了一下其他文也有人稱畫家與鑑賞家):我們現在手上有真的data,工匠要做的事就是偽造出假的data,而偵探則是要分辨現在給他的data是真的還是假的,並且會給出一個回饋。工匠根據這個回饋來「訓練」他現在的工藝,也就是調整model的parameter;一旦工匠的工藝成熟到偵探分辨不出來誰真誰假,就可以說我們訓練出了一個能夠模擬真正data分布的model。 -  ::: :::info #### Detail - 題目設定&環境 - 這次Tutorial設定的task是MNIST手寫辨識資料集,採用的神經網路framework是TensorFlow(1.2),語言是Python3.6。 - 偵探(Discriminator network) -  - 偵探的目的就是要分辨真假資料,在這個task上就是給一張圖片,然後輸出一個「相似度」的分數—越高表示這張圖片越像從真的dataset出來,反之則是由工匠偽造的。 - 一個比較特別的是,這邊最後輸出的value並沒有像一般的CNN加上sigmoid layer或softmax layer讓他維持在[1,0]之間(機率分布),這個設定是根據實際經驗得來的:這樣作有可能會讓偵探過於強大,也就是輸出的分數極端地偏向1或0,而沒有辦法有價值的回饋給工匠改進。想像一下問卷調查的結果如果只有「極度討厭」和「極度喜歡」這兩個選項,店家也很難根據武斷的評論作改善,有點類似這個情境。 - 這個模型包含了兩個(5*5)convolution layer和兩個fully connected layer,首先我們在第一層以5*5 convolution大小抽出32個feature map,第二層64個,最後兩次fully connected輸出一個value。 - 工匠(Generator network) -  - 接下來就是工匠了,工匠的目的是要偽造圖片,因此輸出入跟偵探是相反的:工匠要輸出一個圖片,而輸入則是一個隨機數。這邊比較不太直觀,我們可以把他想成是一個random_number_generator,吃了不同的seed會輸出不同的數字;而工匠則是吃了不同的seed會輸出不同的圖片,而若是工匠訓練地非常完美,他就可以不斷地輸出跟真實手寫數字相差無幾的圖片。 - 工匠採用的模型像是一個逆向的CNN,假設d=100,首先我們把產生出的d-dimensional noise vector投射到3136維的vector上,接著reshape成56*56,再利用3*3的convolution layer產生50個feature map,接著25個feature map,最後把25個feature map輸出成最後的一個map。 - 如何訓練 - 一行文的話就是:Gz = 假圖、Dx = 真圖的分數、Dg = 假圖的分數 - 要出遠門最重要的就是找一個好的導航,要訓練一個模型最重要的就是定義好他的loss function。在GAN裡面會有兩個導航方向,一個是讓偵探(discriminator)往柯南的方向移動,另一個是讓工匠(generator)往魯班的方向移動。 - 要讓偵探變柯南,就要分別提高偵探認出真圖的能力和認出假圖的能力,也就是 - 讓真圖分數和真值(1)差別最小化 - 讓假圖分數和假值(0)差別最小化 - 我們知道Dx是真圖分數,Dg是假圖分數,因此分別對這兩個分數與真值(1)和假值(0)取cross_entropy,又我們要把分數scale到一個機率分布之間,因此可以使用TensorFlow內的tf.nn.sigmoid_cross_entropy_with_logits函式,這個函式和cross_entropy一樣,只是會先對未scale過的x值取sigmoid,公式如下: -  - 最佳化loss function - 定義完loss function後,我們要設法讓loss function最佳化(ML的核心思想)。理解這部份需要的預備知識稍微多一點,有興趣可以參考這個。總之,最佳化loss function採用的方法叫做gradient descent(GD),而GD又有不同的操作方法。在這個Tutorial裡選擇的是Adam optimization。 - 參數是作夢夢到的,不要問為什麼(誤)。原Tutorial的作者說他們調了很久才發現較低的learning rate會有比較好的結果,這部份也是經驗法則。 - 一個細節是,對偵探作最佳化的時候,我們希望調整的是偵探的參數,而對工匠最佳化時亦然。不管是誰的loss function,在做計算時都有用到對方模型的參數(eg. 在算d_loss_fake時,會使用到Gz),但我們不希望optimize時一起調整,因此要限定調整的參數值,寫在minimize(var_list=…)這個變量裡。 - 只要事先用tf.get_variable()定義好的話,TensorFlow的架構可以容易讓我們取得不同變量的名稱。 - 開始訓練 - 再複習一下GAN的架構:我們有真圖,工匠出假圖;偵探認圖最佳化,工匠造假最佳化。OK,我們首先用所有的真圖和沒有訓練過的工匠做出的假圖給偵探一個新手教學。 - 根據原Tutorial,這個步驟的功用是讓一開始的偵探可以具有給出有方向性的feedback回工匠的能力(gradient),有點像是新人訓練的感覺。 - 接下來我們開始偵探 — 工匠的循環訓練。 - 這部份就滿直覺的了,每次的iteration都會batch出真圖和假圖,然後餵給偵探訓練;接下來出假圖,給訓練過的偵探送feedback回工匠訓練。就這樣持續不斷地來回最佳化。 - 一些隨想 - 其實在跟著實作的過程中,一直想到NP問題(笑)。在驗證一個問題是不是NP問題時,我們假設有一個上帝會給你小抄(certificate),只要你能在polynomial time裡檢驗這個小抄上的答案是不是對的,就可以說這是一個NP問題。偵探和鐵匠的關係給人一種類似的類比,當然在意義上是完全不同的。 - 在這過程中完全沒有用到label,因此是一種unsupervised learning。這給人很大的想像空間:GAN可以套用到任何的dataset中,並模擬出他們的distribution。所以可以訓練出各式各樣的generator:圖像的generator、影片的generator、語言的generator……。 - GAN結合了不同的model並交互訓練,有種用model訓練model的感覺。 - 很多設定和參數的調整其實都只是概念和heuristic,還有一大部分的數學細節尚未理解……。 - 如果直接用generator作training呢?loss function如何設計?這一定有人想過但不知道有沒有相關的成果。(書讀太少QQ) ::: :::warning #### Conclusion - 在原Tutorial的最後有提到GAN訓練非常的困難:從參數調整、不同的模型選擇、到訓練程序,所有的選項都有巨量的分支可以選擇,而且訓練時間非常長,要驗證又是另一個難題。不過,正因為這是一個新興的領域(2014年由Ian Goodfellow提出),還有許多的可能性可以繼續探索,所以……繼續交給那些被壓榨的phd研究(還有Google Brain),看有沒有human-generator被做出來的一天吧(笑)。 - 最後偷渡個敝校大老Yann LeCun說的話 — ”Generative Adversarial Network is the most interesting idea in the last ten years in machine learning.” ::: [refer]() --- :::success #### Abstracion - 不用再花大量人力標註資料了,直接利用GAN模型生成即可,『監督式學習』(Supervised)就變成『非監督式學習』(Unsupervised)。 [refer](https://ithelp.ithome.com.tw/upload/images/20180107/200019763yAUV33659.png) -  - 風格轉換(Style Transfer):透過生成,就可以輕易把梵谷畫風轉移到另一張照片上了。更厲害的是,也可以反過來,把梵谷畫作轉換成照片。 [refer](https://ithelp.ithome.com.tw/upload/images/20180107/20001976sACmaSoOc9.png) -  [refer](https://ithelp.ithome.com.tw/upload/images/20180107/2000197698d7FWLnbq.png) 圖. 大師畫作轉換為照片, -  - 高解析度影像生成:透過不斷的生成與判別,模型最後可以訓練出比原圖更高解析度的圖像。 [refer](https://ithelp.ithome.com.tw/upload/images/20180107/20001976645LG4mSXy.png) -  - 壓縮圖像:在網路傳輸大量圖像時,為節省頻寬,常需要壓縮圖像,我們也可以利用GAN生成。 [refer](https://ithelp.ithome.com.tw/upload/images/20180107/20001976MVSPath6z9.png) -  - 其他還有醫學、天文、...等應用,簡直無所不能(有點過頭了)。 [refer](https://ithelp.ithome.com.tw/upload/images/20180107/20001976hxhZ1i6xtH.png) -  ::: :::info #### Detail - 演算法說明 - 參考下圖,GAN的目標函數(即損失函數)就是紅色框框的數學式,是G與D的目標函數加總,其中G是生成模型(偽造者),D是判別模型(警察),兩者是零和遊戲,D要從生成的圖像判斷真偽,G是想盡辦法要呼巄 D,所以,G、D目標函數是反向(log(D(x))、log(1 - D(G(z))),z 是噪音(Noise),假設 z 是服從『均勻分配』(Uniform distribution) 或是『常態分配』(Normal distribution or Gaussian distribution),優化目標是使 G 的機率分配趨近於 D 的機率分配,也就是生成的圖像接近真實的圖像,求解的方法是用『最大似然估計』(Maximum likelihood Estimation,MLE)。 -  - 生成模型(Generative Models)有很多種演算法,GAN是屬於其中的一種。 -  - 下圖左方是判別函數D,優化D(X),求逼近1的最佳解,右方是生成函數G,取亂數z(噪音)加到訓練資料中,優化D(G(z)),求逼近1的最佳解。 -  - 演算法 psuedocode 如下圖,D(x)越高越好,D(G(z))越低越好。 -  ::: :::warning #### Conclusion - 『生成對抗網路』(Generative Adversarial Network,GAN)經由小量真實資料,產生大量的訓練資料,儼然是一個『非監督式』(Unsupervised)的模型,對照之前的CNN/RNN都是『監督式』(Supervised)的模型,必須仰賴大量的標註資料,是 Neural Network 的一大進展,另外,對於沒有資源可以投入標註資料的小公司,應該是一大福音,GAN 透過金庸小說『老頑童周伯通雙手互搏』類似的理念,雙手互相切磋(AlphaGo 好像也是這樣),一方面改善模型的準確度,另一方面也可以產生高品質的訓練資料,難怪相關論文成長量一飛沖天,期待未來能花更多的時間,徹底搞懂它。 ::: [refer]() ---
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up