[論文閱讀] (06) 萬字詳解什么是生成對抗網(wǎng)絡(luò)GAN?經(jīng)典論文及案例普及
前一篇文章分享了Pvop老師的分享,題目為《高手是怎樣學(xué)習(xí)NLP》。這篇文章將詳細(xì)介紹生成對抗網(wǎng)絡(luò)GAN的基礎(chǔ)知識(shí),包括什么是GAN、常用算法(CGAN、DCGAN、infoGAN、WGAN)、發(fā)展歷程、預(yù)備知識(shí),并通過Keras搭建最簡答的手寫數(shù)字圖片生成案例。本文主要學(xué)習(xí)小象學(xué)院老師的視頻,并結(jié)合論文介紹,希望對您有所幫助!不服GAN,讓我們開始吧~

小象學(xué)院的老師 & B站 joe liu 老師分享
https://www.bilibili.com/video/BV1ht411c79k
文章目錄
一.GAN簡介
1.GAN背景知識(shí)
2.GAN原理解析
3.GAN經(jīng)典案例
二.GAN預(yù)備知識(shí)
1.什么是神經(jīng)網(wǎng)絡(luò)
2.全連接層
3.激活函數(shù)
4.反向傳播
5.優(yōu)化器選擇
6.卷積層
7.池化層
8.圖像問題基本思路
三.GAN網(wǎng)絡(luò)實(shí)戰(zhàn)分析
1.GAN模型解析
(1) 目標(biāo)函數(shù)
(2) GAN圖片生成
2.生成手寫數(shù)字demo分析
3.其他常見GAN網(wǎng)絡(luò)
(1) CGAN
(2) DCGAN
(3) ACGAN
(4) infoGAN
(5) LAPGAN
(6) EBGAN
4.GAN改進(jìn)策略
四.總結(jié)
前文賞析:
[論文閱讀] (01) 拿什么來拯救我的拖延癥?初學(xué)者如何提升編程興趣及LATEX入門詳解
[論文閱讀] (02) SP2019-Neural Cleanse: 神經(jīng)網(wǎng)絡(luò)中的后門攻擊識(shí)別與緩解
[論文閱讀] (03) 清華張超老師 - Fuzzing漏洞挖掘詳細(xì)總結(jié) GreyOne
[論文閱讀] (04) 人工智能真的安全嗎?浙大團(tuán)隊(duì)分享AI對抗樣本技術(shù)
[論文閱讀] (05) NLP知識(shí)總結(jié)及NLP論文撰寫之道——Pvop老師
[論文閱讀] (06) 萬字詳解什么是生成對抗網(wǎng)絡(luò)GAN?經(jīng)典論文及案例普及
注意,本文代碼采用GPU+Pycharm實(shí)現(xiàn),如果你的電腦是CPU實(shí)現(xiàn),將相關(guān)GPU操作注釋即可。這里僅做簡單的對比實(shí)驗(yàn),不進(jìn)行參數(shù)優(yōu)化、實(shí)驗(yàn)原因分析及詳細(xì)的效果提升,后面文章會(huì)介紹優(yōu)化、參數(shù)選擇、實(shí)驗(yàn)評估等。
一.GAN簡介
1.GAN背景知識(shí)
Ian Goodfellow?因提出了生成對抗網(wǎng)絡(luò)(GANs,Generative Adversarial Networks)而聞名, GAN最早由Ian Goodfellow于2014年提出,以其優(yōu)越的性能,在不到兩年時(shí)間里,迅速成為一大研究熱點(diǎn)。他也被譽(yù)為“GANs之父”,甚至被推舉為人工智能領(lǐng)域的頂級專家。
GAN原文:https://arxiv.org/abs/1406.2661
實(shí)驗(yàn)運(yùn)行結(jié)果如下圖所示,生成了對應(yīng)的圖像。
在2016年,Ian Goodfellow大佬又通過50多頁的論文詳細(xì)介紹了GAN,這篇文章也推薦大家去學(xué)習(xí)。
https://arxiv.org/pdf/1701.00160.pdf
Yann LeCun稱GAN為“過去十年機(jī)器學(xué)習(xí)界最有趣的idea”。GAN在github上的火熱程度如下圖所示,呈指數(shù)增漲,出現(xiàn)各種變形。當(dāng)然,其中也存在很多比較水的文章,推薦大家盡量學(xué)習(xí)比較經(jīng)典的模型。
https://github.com/hindupuravinash/the-gan-zoo
2.GAN原理解析
首先,什么是GAN?
GANs(Generativeadversarial networks,對抗式生成網(wǎng)絡(luò))可以把這三個(gè)單詞拆分理解。
Generative:生成式模型
Adversarial:采取對抗的策略
Networks:網(wǎng)絡(luò)(不一定是深度學(xué)習(xí))
正如shunliz大佬總結(jié):
GANs是一類生成模型,從字面意思不難猜到它會(huì)涉及兩個(gè)“對手”,一個(gè)稱為Generator(生成者),一個(gè)稱為Discriminator(判別者)。Goodfellow最初arxiv上掛出的GAN tutorial文章中將它們分別比喻為偽造者(Generator)和警察(Discriminator)。偽造者總想著制造出能夠以假亂真的鈔票,而警察則試圖用更先進(jìn)的技術(shù)甄別真假。兩者在博弈過程中不斷升級自己的技術(shù)。
從博弈論的角度來看,如果是零和博弈(zero-sum game),兩者最終會(huì)達(dá)到納什均衡(Nash equilibrium),即存在一組策略(g, d),如果Generator不選擇策略g,那么對于Discriminator來說,總存在一種策略使得Generator輸?shù)酶鼞K;同樣地,將Generator換成Discriminator也成立。
如果GANs定義的lossfunction滿足零和博弈,并且有足夠多的樣本,雙方都有充足的學(xué)習(xí)能力情況,在這種情況下,Generator和Discriminator的最優(yōu)策略即為納什均衡點(diǎn),也即:Generator產(chǎn)生的都是“真鈔”(材料、工藝技術(shù)與真鈔一樣,只是沒有得到授權(quán)),Discriminator會(huì)把任何一張鈔票以1/2的概率判定為真鈔。
那么,GAN究竟能做什么呢?
如下圖所示,這是一張非常有意思的圖,最左邊是真實(shí)的圖,我們希望去預(yù)測視頻后幾幀的模樣,中間這張圖是用MSE做的,最右邊的圖是生成對抗網(wǎng)絡(luò)做的。通過細(xì)節(jié)分析,我們可以看到中間這張圖的耳朵和眼睛都是模糊的,而GAN生成的效果明顯更好。
接著我們在看一個(gè)超分辨率的實(shí)例。首先給出一張超分辨率的圖,最左邊的圖像是原始高分辨率圖像(original),然后要對其進(jìn)行下采樣,得到低分辨率圖像,接著采用不同的方法對低分辨率圖像進(jìn)行恢復(fù),具體工作如下:
bicubic
:第二張圖是bicubic方法恢復(fù)的圖像。經(jīng)過壓縮再拉伸還原圖像,通過插值運(yùn)算實(shí)現(xiàn),但其圖像會(huì)變得模糊。
SRResNet
:第三張圖像是通過SRResNet實(shí)現(xiàn)的恢復(fù),比如先壓縮圖像再用MSE和神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)和真實(shí)值的差別,再進(jìn)行恢復(fù)。(SRResNet is a neural network trained with mean squared error)
SRGAN
:第四張圖是通過SRGAN實(shí)現(xiàn)的,其恢復(fù)效果更優(yōu)。SRGAN是在GAN基礎(chǔ)上的改進(jìn),它能夠理解有多個(gè)正確的答案,而不是在許多答案中給出一個(gè)最佳輸出。
我們注意觀察圖像頭部雕飾的細(xì)節(jié),發(fā)現(xiàn)GAN恢復(fù)的輪廓更清晰。該實(shí)驗(yàn)顯示了使用經(jīng)過訓(xùn)練的生成模型從多模態(tài)分布生成真實(shí)樣本的優(yōu)勢。
現(xiàn)假設(shè)要解決一個(gè)問題:
能不能解決超分辨率,從一個(gè)低分辨率的圖像恢復(fù)成一個(gè)高分辨率的圖像,那怎么做呢?
他們通過增加兩個(gè)卷積層的網(wǎng)絡(luò)就解決了一個(gè)實(shí)際問題,并且這篇文章發(fā)了一個(gè)頂會(huì)。
https://link.springer.com/chapter/10.1007/978-3-319-10593-2_13
更詳細(xì)的介紹參考知乎oneTaken大佬的分享。
這是第一篇將端到端的深度學(xué)習(xí)訓(xùn)練來進(jìn)行超分的論文,整篇論文的的過程現(xiàn)在看起來還是比較簡單的,先將低分辨率圖片雙三次插值上采樣到高分辨率圖片,然后再使用兩層卷積來進(jìn)行特征映射,最后使用MSE來作為重建損失函數(shù)進(jìn)行訓(xùn)練。從現(xiàn)在來看很多東西還是比較粗糙的,但這篇論文也成為很多超分論文的baseline。
整篇論文的創(chuàng)新點(diǎn)有:
(1) 使用了一個(gè)卷積神經(jīng)網(wǎng)絡(luò)來進(jìn)行超分,端到端的學(xué)習(xí)低分辨率與超分辨率之間的映射。
(2) 將提出的神經(jīng)網(wǎng)絡(luò)模型與傳統(tǒng)的稀疏編碼方法之間建立聯(lián)系,這種聯(lián)系還指導(dǎo)用來設(shè)計(jì)神經(jīng)網(wǎng)絡(luò)模型。
(3) 實(shí)驗(yàn)結(jié)果表明深度學(xué)習(xí)方法可以用于超分中,可以獲得較好的質(zhì)量和較快的速度。
整個(gè)的模型架構(gòu)非常的簡單,先是對于輸入圖片進(jìn)行雙三次插值采樣到高分辨空間,然后使用一層卷積進(jìn)行特征提取,再用ReLU進(jìn)行非線性映射,最后使用一個(gè)卷積來進(jìn)行重建,使用MSE來作為重建損失。中間一個(gè)插曲是將傳統(tǒng)用于超分的稀疏編碼算法進(jìn)行了延伸,可以看作是一種具有不同非線性映射的卷積神經(jīng)網(wǎng)絡(luò)模型。
3.GAN經(jīng)典案例
GNN究竟能做什么呢?
下面來看看一些比較有趣的GAN案例。
首先是一個(gè)視頻,這篇文章中介紹了Zhu等人開發(fā)了交互式(interactive)生成對抗網(wǎng)絡(luò)(iGAN),用戶可以繪制圖像的粗略草圖,就使用GAN生成相似的真實(shí)圖像。在這個(gè)例子中,用戶潦草地畫了幾條綠線,就把它變成一塊草地,用戶再花了一條黑色的三角形,就創(chuàng)建了一個(gè)山包。
另一個(gè)比較經(jīng)典的案例是左側(cè)輸入的皮包簡圖最終生成接近真實(shí)包的圖像,或者將衛(wèi)星照片轉(zhuǎn)換成地圖,將閾值車輛圖像轉(zhuǎn)換為現(xiàn)實(shí)中逼真的圖像。
再比如通過GAN去預(yù)測視頻中下一幀動(dòng)畫會(huì)發(fā)生什么,比如右下角給了一張火車的靜態(tài)圖片,會(huì)生成一段火車跑動(dòng)的動(dòng)態(tài)視頻。
Wu等在NIPS 2016中通過GAN實(shí)現(xiàn)了用噪聲去生成一張3D椅子模型。
下圖是starGAN。左側(cè)輸入的是一張人臉,然后GAN會(huì)生成對應(yīng)的喜怒哀樂表情,這篇文章的創(chuàng)新不是說GAN能做這件事,而是提出一個(gè)方案,所有的核心功能都在一起,只訓(xùn)練一個(gè)生成器,即不是生成多對多的生成器,而只訓(xùn)練一個(gè)生成器就能實(shí)現(xiàn)這些功能。
starGAN轉(zhuǎn)移從RaFD數(shù)據(jù)集中學(xué)到的知識(shí),在CelebA數(shù)據(jù)集上的多域圖像轉(zhuǎn)換結(jié)果。第一和第六列顯示輸入圖像,其余列是由starGAN生成的圖像。請注意,這些圖像是由一個(gè)單一的生成器網(wǎng)絡(luò)生成的,而憤怒、快樂和恐懼等面部表情標(biāo)簽都來自RaFD,而不是CelebA。
http://cn.arxiv.org/pdf/1711.09020.pdf
二.GAN預(yù)備知識(shí)
1.什么是神經(jīng)網(wǎng)絡(luò)
首先,深度學(xué)習(xí)就是模擬人的腦神經(jīng)(生物神經(jīng)網(wǎng)絡(luò)),比如下圖左上方①中的神經(jīng)元,可以認(rèn)為是神經(jīng)網(wǎng)絡(luò)的接收端,它有很多的樹突接收信號,對應(yīng)Neuron的公式如下:
其中,a表示信號(樹突接收),w表示對應(yīng)的權(quán)重,它們會(huì)進(jìn)行加權(quán)求和組合且包含一個(gè)偏置b。通過激活函數(shù)判斷能否給下一個(gè)神經(jīng)元傳遞信號。
有了這個(gè)神經(jīng)元之后,我們需要構(gòu)建網(wǎng)絡(luò),如右下方②所示。經(jīng)過一層、兩層、三層神經(jīng)網(wǎng)絡(luò),我們最后會(huì)有一個(gè)判斷,如右上方③所示,經(jīng)過Softmax函數(shù)判斷,決策這幅圖像是什么,比如貓或狗。
其次,深度學(xué)習(xí)有哪些知識(shí)點(diǎn)呢?
深度學(xué)習(xí)的網(wǎng)絡(luò)設(shè)計(jì)如下圖所示:
神經(jīng)網(wǎng)絡(luò)常見層
全連接層、激活層、BN層、Dropout層、卷積層、池化層、循環(huán)層、Embedding層、Merege層等
網(wǎng)絡(luò)配置
損失函數(shù)、優(yōu)化器、激活函數(shù)、性能評估、初始化方法、正則項(xiàng)等
網(wǎng)絡(luò)訓(xùn)練流程
預(yù)訓(xùn)練模型、訓(xùn)練流程、數(shù)據(jù)預(yù)處理(歸一化、Embedding)、數(shù)據(jù)增強(qiáng)(圖片翻轉(zhuǎn)旋轉(zhuǎn)曝光生成海量樣本)等
補(bǔ)充:
深度學(xué)習(xí)的可解釋性非常差,很多時(shí)候不知道它為什么正確。NLP會(huì)議上也經(jīng)常討論這個(gè)可解釋性到底重不重要。個(gè)人認(rèn)為,如果用傳統(tǒng)的方法效果能達(dá)到80%,而深度學(xué)習(xí)如果提升非常大,比如10%,個(gè)人感覺工業(yè)界還是會(huì)用的,因?yàn)槟芴嵘阅懿⒔鉀Q問題。除非比如風(fēng)控任務(wù),美團(tuán)檢測異常刷單情況,此時(shí)需要準(zhǔn)確的確認(rèn)是否刷單。
2.全連接層
隱藏層的輸入和輸出都有關(guān)聯(lián),即全連接層的每一個(gè)結(jié)點(diǎn)都與上一層的所有結(jié)點(diǎn)相連,用來把前邊提取到的特征綜合起來。由于其全相連的特性,一般全連接層的參數(shù)也是最多的。
全連接層包括神經(jīng)元的計(jì)算公式、維度(神經(jīng)元個(gè)數(shù))、激活函數(shù)、權(quán)值初始化方法(w、b)、正則項(xiàng)。
3.激活函數(shù)
激活函數(shù)(activation function)會(huì)讓某一部分神經(jīng)元先激活,然后把激活的信息傳遞給后面一層的神經(jīng)系統(tǒng)中。比如,某些神經(jīng)元看到貓的圖片,它會(huì)對貓的眼睛特別感興趣,那當(dāng)神經(jīng)元看到貓的眼睛時(shí),它就被激勵(lì)了,它的數(shù)值就會(huì)被提高。
激活函數(shù)相當(dāng)于一個(gè)過濾器或激勵(lì)器,它把特有的信息或特征激活,常見的激活函數(shù)包括softplus、sigmoid、relu、softmax、elu、tanh等。
對于隱藏層,我們可以使用relu、tanh、softplus等非線性關(guān)系;
對于分類問題,我們可以使用sigmoid(值越小越接近于0,值越大越接近于1)、softmax函數(shù),對每個(gè)類求概率,最后以最大的概率作為結(jié)果;
對于回歸問題,可以使用線性函數(shù)(linear function)來實(shí)驗(yàn)。
[Python人工智能] 三.TensorFlow基礎(chǔ)之Session、變量、傳入值和激勵(lì)函數(shù)
常用的激活函數(shù)Sigmoid、tanh、ReLU、Leaky ReLU曲線如下圖所示:
4.反向傳播
BP神經(jīng)網(wǎng)絡(luò)是非常經(jīng)典的網(wǎng)絡(luò),這里通過知乎EdisonGzq大佬的兩張圖來解釋神經(jīng)網(wǎng)絡(luò)的反向傳播。對于一個(gè)神經(jīng)元而言,就是計(jì)算最后的誤差傳回來對每個(gè)權(quán)重的影響,即計(jì)算每層反向傳遞的梯度變化。
對于多個(gè)神經(jīng)元而言,它是兩條線的輸出反向傳遞,如下圖所示Eo1和Eo2。
5.優(yōu)化器選擇
存在梯度變化后,會(huì)有一個(gè)迭代的方案,這種方案會(huì)有很多選擇。優(yōu)化器有很多種,但大體分兩類:
一種優(yōu)化器是跟著梯度走,每次只觀察自己的梯度,它不帶重量
一種優(yōu)化器是帶重量的
class tf.train.Optimizer是優(yōu)化器(optimizers)類的基類。優(yōu)化器有很多不同的種類,最基本的一種是GradientsDescentOptimizer,它也是機(jī)器學(xué)習(xí)中最重要或最基礎(chǔ)的線性優(yōu)化。七種常見的優(yōu)化器包括:
class tf.train.GradientDescentOptimizer
class tf.train.AdagradOptimizer
class tf.train.AdadeltaOptimizer
class tf.train.MomentumOptimizer
class tf.train.AdamOptimizer
class tf.train.FtrlOptimizer
class tf.train.RMSPropOptimizer
下面簡單介紹其中四個(gè)常用的優(yōu)化器:(推薦?優(yōu)化器總結(jié)?)
GradientDescentOptimizer
梯度下降GD取決于傳進(jìn)數(shù)據(jù)的size,比如只傳進(jìn)去全部數(shù)據(jù)的十分之一,Gradient Descent Optimizer就變成了SGD,它只考慮一部分的數(shù)據(jù),一部分一部分的學(xué)習(xí),其優(yōu)勢是能更快地學(xué)習(xí)到去往全局最小量(Global minimum)的路徑。
MomentumOptimizer
它是基于學(xué)習(xí)效率的改變,它不僅僅考慮這一步的學(xué)習(xí)效率,還加載了上一步的學(xué)習(xí)效率趨勢,然后上一步加這一步的learning_rate,它會(huì)比GradientDescentOptimizer更快到達(dá)全局最小量。
AdamOptimizer
Adam名字來源于自適應(yīng)矩估計(jì)(Adaptive Moment Estimation),也是梯度下降算法的一種變形,但是每次迭代參數(shù)的學(xué)習(xí)率都有一定的范圍,不會(huì)因?yàn)樘荻群艽蠖鴮?dǎo)致學(xué)習(xí)率(步長)也變得很大,參數(shù)的值相對比較穩(wěn)定。Adam算法利用梯度的一階矩估計(jì)和二階矩估計(jì)動(dòng)態(tài)調(diào)整每個(gè)參數(shù)的學(xué)習(xí)率。
RMSPropOptimizer
Google用它來優(yōu)化阿爾法狗的學(xué)習(xí)效率。RMSProp算法修改了AdaGrad的梯度積累為指數(shù)加權(quán)的移動(dòng)平均,使得其在非凸設(shè)定下效果更好。
各種優(yōu)化器用的是不同的優(yōu)化算法(如Mmentum、SGD、Adam等),本質(zhì)上都是梯度下降算法的拓展。下圖通過可視化對各種優(yōu)化器進(jìn)行了對比分析,機(jī)器學(xué)習(xí)從目標(biāo)學(xué)習(xí)到最優(yōu)的過程,有不同的學(xué)習(xí)路徑,由于Momentum考慮了上一步的學(xué)習(xí)(learning_rate),走的路徑會(huì)很長;GradientDescent的學(xué)習(xí)時(shí)間會(huì)非常慢。建議如下:
如果您是初學(xué)者,建議使用GradientDescentOptimizer即可,如果您有一定的基礎(chǔ),可以考慮下MomentumOptimizer、AdamOptimizer兩個(gè)常用的優(yōu)化器,高階的話,可以嘗試學(xué)習(xí)RMSPropOptimizer優(yōu)化器??傊?,您最好結(jié)合具體的研究問題,選擇適當(dāng)?shù)膬?yōu)化器。
6.卷積層
為什么會(huì)提出卷積層呢?因?yàn)槿B接層存在一個(gè)核心痛點(diǎn):
圖片參數(shù)太多,比如1000*1000的圖片,加一個(gè)隱藏層,隱藏層節(jié)點(diǎn)同輸入維數(shù),全連接的參數(shù)是10^12,根本訓(xùn)練不過來這么多參數(shù)。
利器一:局部感知野
提出了一個(gè)卷積核的概念,局部感知信息。
利器二:參數(shù)共享
從圖像的左上角按照3x3掃描至右下角,獲得如右圖所示的結(jié)果,通過卷積共享減少了參數(shù)個(gè)數(shù)。注意,這里的卷積核是如下:
\left[ \begin{matrix} 1 & 0 & 1 \ 0 & 1 & 0 \ 1 & 0 & 1 \end{matrix} \right]?? 101 010 101 ??
當(dāng)前掃描的區(qū)域?yàn)槿缦拢罱K計(jì)算結(jié)果為2。
\left[ \begin{matrix} 0 & 1 & 1 \ 0 & 0 & 1 \ 0 & 0 & 1 \end{matrix} \right]?? 000 100 111 ??
卷積層的核心知識(shí)點(diǎn)如下:
卷積核數(shù)目
卷積核大?。喝缟厦?x3卷積核
卷積核數(shù)目
卷積核步長:上面的步長是1,同樣可以調(diào)格
激活函數(shù)
Padding:比如上圖需要輸出5x5的結(jié)果圖,我們需要對其外圓補(bǔ)零
是否使用偏置
學(xué)習(xí)率
初始化
下圖展示了五層卷積層,每層輸出的內(nèi)容。它從最初簡單的圖形學(xué)習(xí)到后續(xù)的復(fù)雜圖形。
7.池化層
池化層主要解決的問題是:
使特征圖變小,簡化網(wǎng)絡(luò);特征壓縮,提取主要特征
常用池化層包括:
最大池化:比如從左上角紅色區(qū)域中選擇最大的6,接著是8、3、4
平均池化:選擇平均值
基本知識(shí)點(diǎn)如下圖所示:
8.圖像問題基本思路
此時(shí),我們通過介紹的全連接層、卷積層、池化層,就能解決實(shí)際的問題。如下圖所示:
輸入層
如NLP句子、句對,圖像的像素矩陣,語音的音頻信息
表示成
DNN:全連接+非線性(特征非線性融合)
CNN:Conv1d、Conv2d、Pooling
RNN:LSTM、GRU(選擇記憶性)
應(yīng)用層
分類、回歸、序列預(yù)測、匹配
可以將圖像問題基本思路簡化為下圖的模型。
至此,預(yù)備知識(shí)介紹完畢!接下來我們進(jìn)入GAN網(wǎng)絡(luò)實(shí)戰(zhàn)分析。
三.GAN網(wǎng)絡(luò)實(shí)戰(zhàn)分析
GANs(Generativeadversarial networks)對抗式生成網(wǎng)絡(luò)
Generative:生成式模型
Adversarial:采取對抗的策略
Networks:網(wǎng)絡(luò)
1.GAN模型解析
首先,我們先說說GAN要做什么呢?
最開始在圖(a)中我們生成綠線,即生成樣本的概率分布,黑色的散點(diǎn)是真實(shí)樣本的概率分布,這條藍(lán)線是一個(gè)判決器,判斷什么時(shí)候應(yīng)該是真的或假的。
我們第一件要做的事是把判決器判斷準(zhǔn),如圖(b)中藍(lán)線,假設(shè)在0.5的位置下降,之前的認(rèn)為是真實(shí)樣本,之后的認(rèn)為是假的樣本。
當(dāng)它固定完成后,在圖?中,生成器想辦法去和真實(shí)數(shù)據(jù)作擬合,想辦法去誤導(dǎo)判決器。
最終輸出圖(d),如果你真實(shí)的樣本和生成的樣本完全一致,分布完全一致,判決器就傻了,無法繼續(xù)判斷。
可能大家還比較蒙,下面我們再詳細(xì)介紹一個(gè)思路。
生成器:學(xué)習(xí)真實(shí)樣本以假亂真
判別器:小孩通過學(xué)習(xí)成驗(yàn)鈔機(jī)的水平
GAN的整體思路是一個(gè)生成器,一個(gè)判別器,并且GoodFellow論文證明了GAN全局最小點(diǎn)的充分必要條件是:生成器的概率分布和真實(shí)值的概率分布是一致的時(shí)候。
Global Optimality of p_g=p_{data}GlobalOptimalityofpg =pdata
其次,GAN還需要分析哪些問題呢?
目標(biāo)函數(shù)如何設(shè)定?
如何生成圖片?
G生成器和D判決器應(yīng)該如何設(shè)置?
如何進(jìn)行訓(xùn)練?
(1) 目標(biāo)函數(shù)
該目標(biāo)函數(shù)如下所示,其中:
max()式子是第一步,表示把生成器G固定,讓判別器盡量區(qū)分真實(shí)樣本和假樣本,即希望生成器不動(dòng)的情況下,判別器能將真實(shí)的樣本和生成的樣本區(qū)分開。
min()式子是第二步,即整個(gè)式子。判別器D固定,通過調(diào)整生成器,希望判別器出現(xiàn)失誤,盡可能不要讓它區(qū)分開。
這也是一個(gè)博弈的過程。
整個(gè)公式的具體含義如下:
式子由兩項(xiàng)構(gòu)成,x表示真實(shí)圖片,z表示輸入G網(wǎng)絡(luò)的噪聲,而G(z)表示G網(wǎng)絡(luò)生成的圖片。
D(x)表示D網(wǎng)絡(luò)判斷真實(shí)圖片是否真實(shí)的概率(因?yàn)閤就是真實(shí)的,所以對于D來說,這個(gè)值越接近1越好)。
D(G(z))是D網(wǎng)絡(luò)判斷G生成的圖片是否真實(shí)的概率。
G的目的:G應(yīng)該希望自己生成的的圖片越接近真實(shí)越好。
D的目的:D的能力越強(qiáng),D(x)應(yīng)該越大,D(G(x))應(yīng)該越小,這時(shí)V(D,G)會(huì)變大,因此式子對于D來說是求最大(max_D)。
trick:為了前期加快訓(xùn)練,生成器的訓(xùn)練可以把log(1-D(G(z)))換成-log(D(G(z)))損失函數(shù)。
接著我們回到大神的原論文,看看其算法(Algorithm 1)流程。
最外層是一個(gè)for循環(huán),接著是k次for循環(huán),中間迭代的是判決器。
k次for循環(huán)結(jié)束之后,再迭代生成器。
最后結(jié)束循環(huán)。
(2) GAN圖片生成
接著我們介紹訓(xùn)練方案,通過GAN生成圖片。
第一步(左圖):希望判決器盡可能地分開真實(shí)數(shù)據(jù)和我生成的數(shù)據(jù)。那么,怎么實(shí)現(xiàn)呢?我的真實(shí)數(shù)據(jù)就是input1(Real World images),我生成的數(shù)據(jù)是input2(Generator)。input1的正常輸出是1,input2的正常輸出是0,對于一個(gè)判決器(Discriminator)而言,我希望它判決好,首先把生成器固定?。ㄌ摼€T),然后生成一批樣本和真實(shí)數(shù)據(jù)混合給判決器去判斷。此時(shí),經(jīng)過訓(xùn)練的判決器變強(qiáng),即
固定生成器且訓(xùn)練判決器
。
第二步(右圖):固定住判決器(虛線T),我想辦法去混淆它,剛才經(jīng)過訓(xùn)練的判決器很厲害,此時(shí)我們想辦法調(diào)整生成器,從而混淆判別器,即通過
固定判決器并調(diào)整生成器
,使得最后的輸出output讓生成的數(shù)據(jù)也輸出1(第一步為0)。
GAN的核心就是這些,再簡單總結(jié)下,即:
步驟1是在生成器固定的時(shí)候,我讓它產(chǎn)生一批樣本,然后讓判決器正確區(qū)分真實(shí)樣本和生成樣本。(生成器標(biāo)簽0、真實(shí)樣本標(biāo)簽1)
步驟2是固定判決器,通過調(diào)整生成器去盡可能的瞞混判決器,所以實(shí)際上此時(shí)訓(xùn)練的是生成器。(生成器的標(biāo)簽需要讓判決器識(shí)別為1,即真實(shí)樣本)
其偽代碼如下:
for 迭代 in range(迭代總數(shù)): for batch in range(batch_size): 新batch = input1的batch + input2的batch (batch加倍) for 輪數(shù) in range(判別器中輪數(shù)): 步驟一 訓(xùn)練D 步驟二 訓(xùn)練G
2.生成手寫數(shù)字demo分析
接下來我們通過手寫數(shù)字圖像生成代碼來加深讀者的印象。這是一個(gè)比較經(jīng)典的共有數(shù)據(jù)集,包括圖像分類各種案例較多,這里我們主要是生成手寫數(shù)字圖像。
首先,我們看看生成器是如何生成一個(gè)圖像(從噪音生成)?
核心代碼如下,它首先要隨機(jī)生成一個(gè)噪音(noise),所有生成的圖片都是靠噪音實(shí)現(xiàn)的。Keras參考代碼:
https://github.com/jacobgil/keras-dcgan/blob/master/dcgan.py
(1) 生成器G
生成器總共包括:
全連接層:輸入100維,輸出1024維
全連接層:128x7x7表示圖片128通道,大小7x7
BatchNormalization:如果不加它DCGAN程序會(huì)奔潰
UpSampling2D:對卷積結(jié)果進(jìn)行上采樣從而將特征圖放大 14x14
Conv2D:卷積操作像素尺度不變(same)
UpSampling2D:生成28x28
Conv2D:卷積操作
Activation:激活函數(shù)tanh
(2) 判別器D
判別器就是做一個(gè)二分類的問題,要么真要么假。
Conv2D:卷積層
MaxPooling2D:池化層
Conv2D:卷積層
MaxPooling2D:池化層
Flatten:拉直一維
Dense:全連接層
Activation:sigmoid二分類
(3) 輔助函數(shù)
如何把D固定去調(diào)整G的函數(shù)generator_containing_discriminator。
model.add(g):加載生成器G
d.trainable=False:判決器D固定
combine_images函數(shù)實(shí)現(xiàn)合并圖像的操作。
(4) GAN圖片生成訓(xùn)練
GAN核心流程包括:
load_data:載入圖片
d = discriminator_model:定義判別器D
g = generator_model:定義生成器G
generator_containing_discriminator:固定D調(diào)整G
SGD、compile:定義參數(shù)、學(xué)習(xí)率
for epoch in range、for index in rangeBATCH
X = np.concatenate:圖像數(shù)據(jù)和生成數(shù)據(jù)混合
y = [1] x BATCH_SIZE + [0] x BTCH_SIZE:輸出label
d_loss = d.train_on_batch(X,y):訓(xùn)練D判別器(步驟一)
d.trainable = False:固定D
g_loss = d_on_g.train_on_batch(noise, [1]xBATCH_SIZE):訓(xùn)練G生成器(步驟二),混淆
d.trainable = True:打開D重復(fù)操作
保存參數(shù)和模型
(5) 生成
模型訓(xùn)練好之后,我們想辦法用GAN生成圖片。
g = generator_model:定義生成器模型
g.load_weights:載入訓(xùn)練好的生成器(generator)
noise:隨機(jī)產(chǎn)生噪聲
然后用G生成一幅圖像,該圖像就能欺騙判別器D
完整代碼如下:
這段代碼更像一個(gè)簡單的GAN生成圖片。
# -*- coding: utf-8 -*- """ Created on 2021-03-19 @author: xiuzhang Eastmount CSDN 參考:https://github.com/jacobgil/keras-dcgan """ from keras.models import Sequential from keras.layers import Dense from keras.layers import Reshape from keras.layers.core import Activation from keras.layers.normalization import BatchNormalization from keras.layers.convolutional import UpSampling2D from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.layers.core import Flatten from keras.optimizers import SGD from keras.datasets import mnist import tensorflow as tf import numpy as np from PIL import Image import argparse import math import os ## GPU處理 讀者如果是CPU注釋該部分代碼即可 ## 指定每個(gè)GPU進(jìn)程中使用顯存的上限 0.9表示可以使用GPU 90%的資源進(jìn)行訓(xùn)練 os.environ["CUDA_DEVICES_ORDER"] = "PCI_BUS_IS" os.environ["CUDA_VISIBLE_DEVICES"] = "0" gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.8) sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) #---------------------------------------------------------------- #生成器 def generator_model(): model = Sequential() model.add(Dense(input_dim=100, output_dim=1024)) model.add(Activation('tanh')) model.add(Dense(128*7*7)) #7x7 128通道 model.add(BatchNormalization()) model.add(Activation('tanh')) model.add(Reshape((7, 7, 128), input_shape=(128*7*7,))) model.add(UpSampling2D(size=(2, 2))) model.add(Conv2D(64, (5, 5), padding='same')) model.add(Activation('tanh')) model.add(UpSampling2D(size=(2, 2))) model.add(Conv2D(1, (5, 5), padding='same')) model.add(Activation('tanh')) return model #---------------------------------------------------------------- #判別器 def discriminator_model(): model = Sequential() model.add( Conv2D(64, (5, 5), padding='same', input_shape=(28, 28, 1)) ) model.add(Activation('tanh')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(128, (5, 5))) model.add(Activation('tanh')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(1024)) model.add(Activation('tanh')) model.add(Dense(1)) model.add(Activation('sigmoid')) return model #---------------------------------------------------------------- #輔助函數(shù) 固定D調(diào)整G def generator_containing_discriminator(g, d): model = Sequential() model.add(g) d.trainable = False model.add(d) return model #輔助函數(shù) 合并圖像 def combine_images(generated_images): num = generated_images.shape[0] width = int(math.sqrt(num)) height = int(math.ceil(float(num)/width)) shape = generated_images.shape[1:3] image = np.zeros((height*shape[0], width*shape[1]), dtype=generated_images.dtype) for index, img in enumerate(generated_images): i = int(index/width) j = index % width image[i*shape[0]:(i+1)*shape[0], j*shape[1]:(j+1)*shape[1]] = \ img[:, :, 0] return image #---------------------------------------------------------------- #訓(xùn)練 def train(BATCH_SIZE): (X_train, y_train), (X_test, y_test) = mnist.load_data() X_train = (X_train.astype(np.float32) - 127.5)/127.5 X_train = X_train[:, :, :, None] X_test = X_test[:, :, :, None] #X_train = X_train.reshape((X_train.shape, 1) + X_train.shape[1:]) d = discriminator_model() g = generator_model() d_on_g = generator_containing_discriminator(g, d) d_optim = SGD(lr=0.0005, momentum=0.9, nesterov=True) g_optim = SGD(lr=0.0005, momentum=0.9, nesterov=True) g.compile(loss='binary_crossentropy', optimizer="SGD") d_on_g.compile(loss='binary_crossentropy', optimizer=g_optim) d.trainable = True d.compile(loss='binary_crossentropy', optimizer=d_optim) for epoch in range(100): print("Epoch is", epoch) print("Number of batches", int(X_train.shape[0]/BATCH_SIZE)) for index in range(int(X_train.shape[0]/BATCH_SIZE)): noise = np.random.uniform(-1, 1, size=(BATCH_SIZE, 100)) image_batch = X_train[index*BATCH_SIZE:(index+1)*BATCH_SIZE] generated_images = g.predict(noise, verbose=0) if index % 20 == 0: image = combine_images(generated_images) image = image*127.5+127.5 Image.fromarray(image.astype(np.uint8)).save( str(epoch)+"_"+str(index)+".png") X = np.concatenate((image_batch, generated_images)) y = [1] * BATCH_SIZE + [0] * BATCH_SIZE d_loss = d.train_on_batch(X, y) print("batch %d d_loss : %f" % (index, d_loss)) noise = np.random.uniform(-1, 1, (BATCH_SIZE, 100)) d.trainable = False g_loss = d_on_g.train_on_batch(noise, [1] * BATCH_SIZE) d.trainable = True print("batch %d g_loss : %f" % (index, g_loss)) if index % 10 == 9: g.save_weights('generator', True) d.save_weights('discriminator', True) #---------------------------------------------------------------- #GAN圖片生成 def generate(BATCH_SIZE, nice=False): g = generator_model() g.compile(loss='binary_crossentropy', optimizer="SGD") g.load_weights('generator') if nice: d = discriminator_model() d.compile(loss='binary_crossentropy', optimizer="SGD") d.load_weights('discriminator') noise = np.random.uniform(-1, 1, (BATCH_SIZE*20, 100)) generated_images = g.predict(noise, verbose=1) d_pret = d.predict(generated_images, verbose=1) index = np.arange(0, BATCH_SIZE*20) index.resize((BATCH_SIZE*20, 1)) pre_with_index = list(np.append(d_pret, index, axis=1)) pre_with_index.sort(key=lambda x: x[0], reverse=True) nice_images = np.zeros((BATCH_SIZE,) + generated_images.shape[1:3], dtype=np.float32) nice_images = nice_images[:, :, :, None] for i in range(BATCH_SIZE): idx = int(pre_with_index[i][1]) nice_images[i, :, :, 0] = generated_images[idx, :, :, 0] image = combine_images(nice_images) else: noise = np.random.uniform(-1, 1, (BATCH_SIZE, 100)) generated_images = g.predict(noise, verbose=1) image = combine_images(generated_images) image = image*127.5+127.5 Image.fromarray(image.astype(np.uint8)).save( "generated_image.png") #參數(shù)設(shè)置 def get_args(): parser = argparse.ArgumentParser() parser.add_argument("--mode", type=str) parser.add_argument("--batch_size", type=int, default=128) parser.add_argument("--nice", dest="nice", action="store_true") parser.set_defaults(nice=False) args = parser.parse_args() return args if __name__ == "__main__": """ args = get_args() if args.mode == "train": train(BATCH_SIZE=args.batch_size) elif args.mode == "generate": generate(BATCH_SIZE=args.batch_size, nice=args.nice) """ mode = "train" if mode == "train": train(BATCH_SIZE=128) elif mode == "generate": generate(BATCH_SIZE=128)
代碼執(zhí)行參數(shù):
Training: python dcgan.py --mode train --batch_size
訓(xùn)練過程,首先手寫數(shù)字MNIST圖片數(shù)據(jù)集可以下載存儲(chǔ)至該位置,也可以運(yùn)行代碼在線下載。
Epoch is 0 Number of batches 468 batch 0 d_loss : 0.648902 batch 0 g_loss : 0.672132 batch 1 d_loss : 0.649307 .... batch 466 g_loss : 1.305099 batch 467 d_loss : 0.375284 batch 467 g_loss : 1.298173 Epoch is 1 Number of batches 468 batch 0 d_loss : 0.461435 batch 0 g_loss : 1.231795 batch 1 d_loss : 0.412679 ....
運(yùn)行過程中會(huì)生成很多圖像,隨著訓(xùn)練次數(shù)增加圖像會(huì)越來越清晰。
然后參數(shù)設(shè)置為“generate”,利用GAN最終生成圖像,如下圖所示。
3.其他常見GAN網(wǎng)絡(luò)
(1) CGAN
首先,GAN如何輸出指定類的圖像呢?
CGAN出場。這里簡單介紹下GAN和CGAN的區(qū)別:GAN只能判斷生成的東西是真的或假的,如果想指定生成圖像如1、2、3呢?GAN會(huì)先生成100張圖像,然后從中去挑選出1、2、3,這確實(shí)不方便。
在2014年提出GAN時(shí),CGAN也被提出來了。CGAN除了生成以外,還要把條件帶出去,即帶著我們要生成一個(gè)什么樣的圖條件去混淆,如下右圖:
噪聲z向量+條件c向量去生成
。
所以整套流程大體不變,接著我們看看公式,它在D(x|y)和G(z|y)中增加了y。其中,y不一定是指定類的輸出,可以是一些條件。
(2) DCGAN
DCGAN(Deep Convolutional Generative Adversarial Networks)
卷積神經(jīng)網(wǎng)絡(luò)和對抗神經(jīng)網(wǎng)絡(luò)結(jié)合起來的一篇經(jīng)典論文,核心要素是:
在不改變GAN原理的情況下提出一些有助于增強(qiáng)穩(wěn)定性的tricks
。注意,這一點(diǎn)很重要。因?yàn)镚AN訓(xùn)練時(shí)并沒有想象的穩(wěn)定,生成器最后經(jīng)常產(chǎn)生無意義的輸出或奔潰,但是DCGAN按照tricks能生成較好的圖像。
https://arxiv.org/pdf/1511.06434.pdf
DCGAN論文使用的tricks包括:
所有pooling都用strided convolutions代替,pooling的下采樣是損失信息的,strided convolutions可以讓模型自己學(xué)習(xí)損失的信息
生成器G和判別器D都要用BN層(解決過擬合)
把全連接層去掉,用全卷積層代替
生成器除了輸出層,激活函數(shù)統(tǒng)一使用ReLU,輸出層用Tanh
判別器所有層的激活函數(shù)統(tǒng)一都是LeakyReLU
(3) ACGAN
ACGAN(既能生成圖像又能進(jìn)行分類)
Conditional Image Synthesis with Auxiliary Classifier GANs,該判別器不僅要判斷是真(real)或假(fake),還要判斷其屬于哪一類。
https://arxiv.org/pdf/1610.09585.pdf
(4) infoGAN
InfoGAN:Interpretable Representation Learning by Information Maximizing Generative Adversarial Networks。這個(gè)號稱是OpenAI在2016年的五大突破之一。
D網(wǎng)絡(luò)的輸入只有x,不加c
Q網(wǎng)絡(luò)和D網(wǎng)絡(luò)共享同一個(gè)網(wǎng)絡(luò),只是到最后一層獨(dú)立輸出
G(z)的輸出和條件c區(qū)別大
原文地址:https://arxiv.org/abs/1606.03657
其理論如下:
整個(gè)網(wǎng)絡(luò)的訓(xùn)練在原目標(biāo)函數(shù)的基礎(chǔ)上,增加互信息下界L(G,Q),因此InfoGAN的目標(biāo)函數(shù)最終表示為:
實(shí)驗(yàn)結(jié)果如下圖所示:
(5) LAPGAN
下面介紹一個(gè)比較有趣的網(wǎng)絡(luò)拉普拉斯GAN。我們的目標(biāo)是如何通過噪音生成一張圖片,噪聲本身生成圖片比較困難,不可控量太多,所以我們逐層生成(生成從右往左看)。
首先用噪聲去生成一個(gè)小的圖片,分辨率極低,我們對其拉伸。
拉伸之后,想辦法通過之前訓(xùn)練好的GAN網(wǎng)絡(luò)生成一個(gè)它的殘差。
殘差和拉伸圖相加就生成一張更大的圖片,以此類推,拉普拉斯生成一張大圖。
那么,如何訓(xùn)練呢?對原來這個(gè)大圖的鳥進(jìn)行壓縮,再生成一張圖去判別,依次逐層訓(xùn)練即可。
(6) EBGAN
再來看一個(gè)EBGAN(Energy-based GAN),它拋棄了之前說的對和錯(cuò)的概念。它增加了一個(gè)叫能量的東西,經(jīng)過自動(dòng)編碼器Enc(中間提取特征)和Dec解碼器(輸出),它希望生成一個(gè)跟真實(shí)圖片的能量盡可能小,跟假的圖片能量更大。
《Energy-based Generative Adversarial Network》Junbo Zhao, arXiv:1609.03126v2
其生成器和判別器的損失函數(shù)計(jì)算公式如下(分段函數(shù)):
下圖展示了GAN、EBGAN、EBGAN-PT模型生成的圖像。
4.GAN改進(jìn)策略
你以為解決了所有問題了嗎?too young.
如下圖所示誤差,我們無法判斷GAN訓(xùn)練的好壞。
GAN需要重視:穩(wěn)定(訓(xùn)練不奔)、多樣性(各種樣本)、清晰度(質(zhì)量好),現(xiàn)在很多工作也是解決這三個(gè)問題。
G、D迭代的方式能達(dá)到全局最優(yōu)解嗎?大部分情況是局部最優(yōu)解。
不一定收斂,學(xué)習(xí)率不能高,G、D要共同成長,不能其中一個(gè)成長的過快
– 判別器訓(xùn)練得太好,生成器梯度消失,生成器loss降不下去
– 判別器訓(xùn)練得不好,生成器梯度不準(zhǔn),四處亂跑
奔潰的問題,通俗說G找到D的漏洞,每次都生成一樣的騙D
無需預(yù)先建模,模型過于自由,不可控
為什么GAN存在這些問題,這是因?yàn)镚AN原論文將GAN目標(biāo)轉(zhuǎn)換成了KL散度的問題,KL散度就是存在這些坑。
最終導(dǎo)致偏向于生成“穩(wěn)妥”的樣本,如下圖所示,目標(biāo)target是均勻分布的,但最終生成偏穩(wěn)妥的樣本。
“生成器沒能生成真實(shí)的樣本” 懲罰小
“生成器生成不真實(shí)的樣本” 懲罰大
那么,有沒有解決方法呢?
WGAN(Wasserstein GAN)在2017年被提出,也算是GAN中里程碑式的論文,它從原理上解決了GAN的問題。具體思路為:
判別器最后一層去掉sigmoid
生成器和判別器的loss不取log
每次更新判別器的參數(shù)之后把它們的絕對值截?cái)嗟讲怀^一個(gè)固定的常數(shù)c
不要用基于動(dòng)量的優(yōu)化算法(包括Momentum和Adam),推薦使用RMSProp、SGD
用Wasserstein距離代替KL散度,訓(xùn)練網(wǎng)絡(luò)穩(wěn)定性大大增強(qiáng),不用拘泥DCGAN的那些策略(tricks)
后續(xù)接著改進(jìn),提出了WGAN-GP(WGAN with gradient penalty),不截?cái)啵粚μ荻仍黾討土P項(xiàng)生成質(zhì)量更高的圖像。它一度被稱為“state of the art”。
接下來,做GAN的就會(huì)出來反駁“誰說GAN就不如WGAN,我們加上Gradient Penalty,大家效果都差不多”。
https://arxiv.org/pdf/1705.07215.pdf
效果如下圖所示:
《Google Brain: Are GANs Created Equal? A Large-Scale Study》?這篇論文詳細(xì)對比了各GAN模型點(diǎn)心LOSS優(yōu)化變種。
https://arxiv.org/pdf/1711.10337.pdf
https://arxiv.org/pdf/1706.08500.pdf
這篇文章比較的結(jié)論為:特定的數(shù)據(jù)集說特定的事情,沒有哪一種碾壓其他。好的算法還得看成本,時(shí)間短的效果某家強(qiáng),但訓(xùn)練時(shí)間長了,反倒會(huì)變差。根據(jù)評價(jià)標(biāo)準(zhǔn)的不同,場景的不同,效果差的算法也可以逆襲。工業(yè)界更看重穩(wěn)定性,比如WGAN。
參考知乎蘇劍林老師的回答
首先,從理論完備的角度來看,原始的GAN(SGAN)就是一個(gè)完整的GAN框架,只不過它可能存在梯度消失的風(fēng)險(xiǎn)。而論文比較的是
“大家都能穩(wěn)定訓(xùn)練到收斂的情況下,誰的效果更好”
的問題,這答案是顯然易見的:不管是SGAN還是WGAN,大家都是理論完備的,只是從不同角度看待概率分布的問題而已,所以效果差不多是正常的。
甚至可以說,SGAN的理論更完備一些(因?yàn)閃GAN需要L約束,而目前L約束的各種加法都有各自的缺點(diǎn)),所以通常來說SGAN的效果還比WGAN效果好一些。那么WGAN它們的貢獻(xiàn)是什么呢?WGAN的特點(diǎn)就是基本上都能
“穩(wěn)定訓(xùn)練到收斂”
,而SGAN相對而言崩潰的概率更大。所以,如果在“大家都能穩(wěn)定訓(xùn)練到收斂”的前提下比較效果,那對于WGAN這些模型本來就很不公平的,因?yàn)樗鼈兌际侵铝τ谠趺床拍堋胺€(wěn)定訓(xùn)練到收斂”,而這篇論文直接將它作為大前提,直接抹殺了WGAN所作的貢獻(xiàn)了。
四.總結(jié)
一.GAN簡介
1.GAN背景知識(shí)、2.GAN原理解析、3.GAN經(jīng)典案例
二.GAN預(yù)備知識(shí)
1.什么是神經(jīng)網(wǎng)絡(luò)、2.全連接層、3.激活函數(shù)、4.反向傳播
5.優(yōu)化器選擇、6.卷積層、7.池化層、8.圖像問題基本思路
三.GAN網(wǎng)絡(luò)實(shí)戰(zhàn)分析
1.GAN模型解析
2.生成手寫數(shù)字demo分析
3.CGAN、DCGAN、ACGAN、infoGAN、LAPGAN、EBGAN
4.GAN改進(jìn)策略
希望您喜歡這篇文章,從看視頻到撰寫代碼,我真的寫了一周時(shí)間,再次感謝參考文獻(xiàn)的老師們。真心希望這篇文章對您有所幫助,加油~
https://github.com/eastmountyxz/AI-for-Keras
https://github.com/eastmountyxz/AI-for-TensorFlow
感恩能與大家在華為云遇見!
希望能與大家一起在華為云社區(qū)共同成長。原文地址:https://blog.csdn.net/Eastmount/article/details/115346166
(By:Eastmount 2021-12-07 夜于武漢)
參考文獻(xiàn):
https://www.bilibili.com/video/BV1ht411c79k
https://arxiv.org/abs/1406.2661
https://www.cntofu.com/book/85/dl/gan/gan.md
https://github.com/hindupuravinash/the-gan-zoo
https://arxiv.org/pdf/1701.00160.pdf
https://link.springer.com/chapter/10.1007/978-3-319-10593-2_13
https://zhuanlan.zhihu.com/p/76520991
http://cn.arxiv.org/pdf/1711.09020.pdf
https://www.sohu.com/a/121189842_465975
https://www.jianshu.com/p/88bb976ccbd9
https://zhuanlan.zhihu.com/p/23270674
ttps://blog.csdn.net/weixin_40170902/article/details/80092628
https://www.jiqizhixin.com/articles/2016-11-21-4
https://github.com/jacobgil/keras-dcgan/blob/master/dcgan.py
https://arxiv.org/abs/1511.06434
https://arxiv.org/pdf/1511.06434.pdf
https://blog.csdn.net/weixin_41697507/article/details/87900133
https://zhuanlan.zhihu.com/p/91592775
https://liuxiaofei.com.cn/blog/acgan與cgan的區(qū)別/
https://arxiv.org/abs/1606.03657
https://blog.csdn.net/sdnuwjw/article/details/83614977
《Energy-based Generative Adversarial Network》Junbo Zhao, arXiv:1609.03126v2
https://www.jiqizhixin.com/articles/2017-03-27-4
https://zhuanlan.zhihu.com/p/25071913
https://arxiv.org/pdf/1705.07215.pdf
https://arxiv.org/pdf/1706.08500.pdf
https://arxiv.org/pdf/1711.10337.pdf
https://www.zhihu.com/question/263383926
深度學(xué)習(xí)
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。