原文地址:https://blog.csdn.net/Sakura55/article/details/81514828
1.GAN
先來看看公式:
GAN網絡主要由兩個網絡構成,生成網絡G和辨別網絡D,生成模型G的思想是將一個噪聲包裝成一個逼真的樣本,判別模型D則需要判斷送入的樣本是真實的還是假的樣本,即共同進步的過程,辨別模型D對樣本的判別能力不斷上升,生成模型G的造假能力也不斷上升!
需要注意的是,生成模型G的輸入是服從-1~1均勻分布的隨機變量,輸出為一張圖片(或者其他,這里我們需要圖片而已),因此,生成網絡的結構是一個反卷積網絡,即對應CNN中的可視化操作,由隨機變量生成圖片的過程!
GAN則是在學習從隨機變量到訓練樣本的映射關系,其中隨機變量可以選擇服從正太分布,那么就能得到一個由多層感知機組成的生成網絡,網絡的輸入是一個一維的隨機變量,輸出是一張圖片。如何讓輸出的偽造圖片看起來像訓練樣本,Goodfellow采用了這樣一種方法,在生成網絡后面接上一個多層感知機組成的判別網絡,這個網絡的輸入是隨機選擇一張真實樣本或者生成網絡的輸出,輸出是輸入圖片來自於真實樣本或者生成網絡的概率,當判別網絡能夠很好的分辨出輸入是不是真實樣本時,也能通過梯度的方式說明什么樣的輸入更加像真實樣本,從而通過這個信息來調整生成網絡。從而需要盡可能的讓自己的輸出像真實樣本,而則盡可能的將不是真實樣本的情況分辨出來。
下圖左邊是GAN算法的概率解釋,右邊是模型構成。
GAN的優化是一個極小極大博弈問題,最終的目的是generator的輸出給discriminator時很難判斷是真實or偽造的,即極大化的判斷能力,極小化將的輸出判斷為偽造的概率,公式如下。論文[5]中將下面式子轉化成了Jensen-shannon散度的形式證明了僅當時能得到全局最小值,即生成網絡能完全的還原出真實樣本分布,並且證明了下式能夠收斂。(算法流程論文講的很清楚,這里就不說了,后面結合代碼一起解釋。)
以上是關於最基本GAN的介紹,最開始我看了論文后產生了幾個疑問,
1.為什么不能直接學習,即直接學習一個到一個?
2.具體是如何訓練的?
3.在訓練的時候跟是一一對應關系嗎?在對代碼理解之后大概能夠給出一個解釋。
1.為什么不能直接學習,即直接學習一個到一個?
2.具體是如何訓練的?
3.在訓練的時候跟是一一對應關系嗎?在對代碼理解之后大概能夠給出一個解釋。
代碼解釋
這部分主要結合tensorflow實現代碼[7]、算法流程和下面的變化圖[5]解釋一下具體如何使用DCGAN來生成手寫體圖片。
下圖中黑色虛線是真實數據的高斯分布,綠色的線是生成網絡學習到的偽造分布,藍色的線是判別網絡判定為真實圖片的概率,標x的橫線代表服從高斯分布x的采樣空間,標z的橫線代表服從均勻分布z的采樣空間。可以看出就是學習了從z的空間到x的空間的映射關系。
2.CGAN
條件GAN
原始GAN 提出,與其他生成式模型相比,GAN這種競爭的方式不再要求一個假設的數據分布,即不需要formulate p(x),而是使用一種分布直接進行采樣sampling,從而真正達到理論上可以完全逼近真實數據,這也是GAN最大的優勢。然而,這種不需要預先建模的方法缺點是太過自由了,對於較大的圖片,較多的 pixel的情形,基於簡單 GAN 的方式就不太可控了。
為了解決GAN太過自由這個問題,一個很自然的想法是給GAN加一些約束,於是便有了Conditional Generative Adversarial Nets(CGAN)【Mirza M, Osindero S. Conditional】。這項工作提出了一種帶條件約束的GAN,在生成模型(D)和判別模型(G)的建模中均引入條件變量y(conditional variable y),使用額外信息y對模型增加條件,可以指導數據生成過程。這些條件變量y可以基於多種信息,例如類別標簽,用於圖像修復的部分數據[2],來自不同模態(modality)的數據。如果條件變量y是類別標簽,可以看做CGAN 是把純無監督的 GAN 變成有監督的模型的一種改進。這個簡單直接的改進被證明非常有效,並廣泛用於后續的相關工作中[3,4]。Mehdi Mirza et al. 的工作是在MNIST數據集上以類別標簽為條件變量,生成指定類別的圖像。作者還探索了CGAN在用於圖像自動標注的多模態學習上的應用,在MIR Flickr25000數據集上,以圖像特征為條件變量,生成該圖像的tag的詞向量。
原始GAN 提出,與其他生成式模型相比,GAN這種競爭的方式不再要求一個假設的數據分布,即不需要formulate p(x),而是使用一種分布直接進行采樣sampling,從而真正達到理論上可以完全逼近真實數據,這也是GAN最大的優勢。然而,這種不需要預先建模的方法缺點是太過自由了,對於較大的圖片,較多的 pixel的情形,基於簡單 GAN 的方式就不太可控了。
為了解決GAN太過自由這個問題,一個很自然的想法是給GAN加一些約束,於是便有了Conditional Generative Adversarial Nets(CGAN)【Mirza M, Osindero S. Conditional】。這項工作提出了一種帶條件約束的GAN,在生成模型(D)和判別模型(G)的建模中均引入條件變量y(conditional variable y),使用額外信息y對模型增加條件,可以指導數據生成過程。這些條件變量y可以基於多種信息,例如類別標簽,用於圖像修復的部分數據[2],來自不同模態(modality)的數據。如果條件變量y是類別標簽,可以看做CGAN 是把純無監督的 GAN 變成有監督的模型的一種改進。這個簡單直接的改進被證明非常有效,並廣泛用於后續的相關工作中[3,4]。Mehdi Mirza et al. 的工作是在MNIST數據集上以類別標簽為條件變量,生成指定類別的圖像。作者還探索了CGAN在用於圖像自動標注的多模態學習上的應用,在MIR Flickr25000數據集上,以圖像特征為條件變量,生成該圖像的tag的詞向量。
Conditional Adversarial Nets結構
條件生成式對抗網絡(CGAN)是對原始GAN的一個擴展,生成器和判別器都增加額外信息y為條件, y可以使任意信息,例如類別信息,或者其他模態的數據。如Figure 1所示,通過將額外信息y輸送給判別模型和生成模型,作為輸入層的一部分,從而實現條件GAN。在生成模型中,先驗輸入噪聲p(z)和條件信息y聯合組成了聯合隱層表征。對抗訓練框架在隱層表征的組成方式方面相當地靈活。類似地,條件GAN的目標函數是帶有條件概率的二人極小極大值博弈(two-player minimax game ):
條件生成式對抗網絡(CGAN)是對原始GAN的一個擴展,生成器和判別器都增加額外信息y為條件, y可以使任意信息,例如類別信息,或者其他模態的數據。如Figure 1所示,通過將額外信息y輸送給判別模型和生成模型,作為輸入層的一部分,從而實現條件GAN。在生成模型中,先驗輸入噪聲p(z)和條件信息y聯合組成了聯合隱層表征。對抗訓練框架在隱層表征的組成方式方面相當地靈活。類似地,條件GAN的目標函數是帶有條件概率的二人極小極大值博弈(two-player minimax game ):
3.DCGAN
【github】地址 :
https://github.com/Newmu/dcgan_code theano
;https://github.com/carpedm20/DCGAN-tensorflow tensorflow
https://github.com/jacobgil/keras-dcgan keras
https://github.com/soumith/dcgan.torch torch
;https://github.com/carpedm20/DCGAN-tensorflow tensorflow
https://github.com/jacobgil/keras-dcgan keras
https://github.com/soumith/dcgan.torch torch
DCGAN是繼GAN之后比較好的改進,其主要的改進主要是在網絡結構上,到目前為止,DCGAN的網絡結構還是被廣泛的使用,DCGAN極大的提升了GAN訓練的穩定性以及生成結果質量。
論文的主要貢獻是:
◆ 為GAN的訓練提供了一個很好的網絡拓撲結構。
◆表明生成的特征具有向量的計算特性。
論文的主要貢獻是:
◆ 為GAN的訓練提供了一個很好的網絡拓撲結構。
◆表明生成的特征具有向量的計算特性。
DCGAN的生成器網絡結構如上圖所示,相較原始的GAN,DCGAN幾乎完全使用了卷積層代替全鏈接層,判別器幾乎是和生成器對稱的,從上圖中我們可以看到,整個網絡沒有pooling層和上采樣層的存在,實際上是使用了帶步長(fractional-strided)的卷積代替了上采樣,以增加訓練的穩定性。
DCGAN能改進GAN訓練穩定的原因主要有:
◆ 使用步長卷積代替上采樣層,卷積在提取圖像特征上具有很好的作用,並且使用卷積代替全連接層。
◆ 生成器G和判別器D中幾乎每一層都使用batchnorm層,將特征層的輸出歸一化到一起,加速了訓練,提升了訓練的穩定性。(生成器的最后一層和判別器的第一層不加batchnorm)
◆ 在判別器中使用leakrelu激活函數,而不是RELU,防止梯度稀疏,生成器中仍然采用relu,但是輸出層采用tanh。
DCGAN能改進GAN訓練穩定的原因主要有:
◆ 使用步長卷積代替上采樣層,卷積在提取圖像特征上具有很好的作用,並且使用卷積代替全連接層。
◆ 生成器G和判別器D中幾乎每一層都使用batchnorm層,將特征層的輸出歸一化到一起,加速了訓練,提升了訓練的穩定性。(生成器的最后一層和判別器的第一層不加batchnorm)
◆ 在判別器中使用leakrelu激活函數,而不是RELU,防止梯度稀疏,生成器中仍然采用relu,但是輸出層采用tanh。
◆ 使用adam優化器訓練,並且學習率最好是**`0.0002`**,(我也試過其他學習率,不得不說0.0002是表現最好的了)
DCGAN結果圖:
矢量計算:
矢量計算:
LSUN數據集上的結果:
DCGAN雖然有很好的架構,但是對GAN訓練穩定性來說是治標不治本,沒有從根本上解決問題,而且訓練的時候仍需要小心的平衡G,D的訓練進程,往往是訓練一個多次,訓練另一個一次。
4.WGAN
【GitHub】:
https://github.com/hwalsuklee/tensorflow-generative-model-collections
https://github.com/Zardinality/WGAN-tensorflow
https://github.com/Zardinality/WGAN-tensorflow
與DCGAN不同,WGAN主要從損失函數的角度對GAN做了改進,損失函數改進之后的WGAN即使在全鏈接層上也能得到很好的表現結果,WGAN對GAN的改進主要有:
◆ 判別器最后一層去掉sigmoid
◆ 生成器和判別器的loss不取log
◆ 對更新后的權重強制截斷到一定范圍內,比如[-0.01,0.01],以滿足論文中提到的lipschitz連續性條件。
◆ 論文中也推薦使用SGD, RMSprop等優化器,不要基於使用動量的優化算法,比如adam,但是就我目前來說,訓練GAN時,我還是adam用的多一些。
◆ 判別器最后一層去掉sigmoid
◆ 生成器和判別器的loss不取log
◆ 對更新后的權重強制截斷到一定范圍內,比如[-0.01,0.01],以滿足論文中提到的lipschitz連續性條件。
◆ 論文中也推薦使用SGD, RMSprop等優化器,不要基於使用動量的優化算法,比如adam,但是就我目前來說,訓練GAN時,我還是adam用的多一些。
從上面看來,WGAN好像在代碼上很好實現,基本上在原始GAN的代碼上不用更改什么,但是它的作用是巨大的。
◆ WGAN理論上給出了GAN訓練不穩定的原因,即交叉熵(JS散度)不適合衡量具有不相交部分的分布之間的距離,轉而使用wassertein距離去衡量生成數據分布和真實數據分布之間的距離,理論上解決了訓練不穩定的問題。
◆ 解決了模式崩潰的(collapse mode)問題,生成結果多樣性更豐富。
◆ 對GAN的訓練提供了一個指標,此指標數值越小,表示GAN訓練的越差,反之越好。可以說之前訓練GAN完全就和買彩票一樣,訓練好了算你中獎,沒中獎也不要氣餒,多買幾注吧。
◆ WGAN理論上給出了GAN訓練不穩定的原因,即交叉熵(JS散度)不適合衡量具有不相交部分的分布之間的距離,轉而使用wassertein距離去衡量生成數據分布和真實數據分布之間的距離,理論上解決了訓練不穩定的問題。
◆ 解決了模式崩潰的(collapse mode)問題,生成結果多樣性更豐富。
◆ 對GAN的訓練提供了一個指標,此指標數值越小,表示GAN訓練的越差,反之越好。可以說之前訓練GAN完全就和買彩票一樣,訓練好了算你中獎,沒中獎也不要氣餒,多買幾注吧。
有關GAN和WGAN的解釋,可以參考鏈接:https://zhuanlan.zhihu.com/p/25071913
總的來說,GAN中交叉熵(JS散度)不適合衡量生成數據分布和真實數據分布的距離,如果通過優化JS散度訓練GAN會導致找不到正確的優化目標,所以,WGAN提出使用wassertein距離作為優化方式訓練GAN,但是數學上和真正代碼實現上還是有區別的,使用Wasserteion距離需要滿足很強的連續性條件—lipschitz連續性,為了滿足這個條件,作者使用了將權重限制到一個范圍的方式強制滿足lipschitz連續性,但是這也造成了隱患,接下來會詳細說。另外說實話,雖然理論證明很漂亮,但是實際上訓練起來,以及生成結果並沒有期待的那么好。
注:Lipschitz限制是在樣本空間中,要求判別器函數D(x)梯度值不大於一個有限的常數K,通過權重值限制的方式保證了權重參數的有界性,間接限制了其梯度信息。
5.WGAN-GP
(improved wgan)
【GitHub】:
https://link.zhihu.com/?target=https%3A//github.com/igul222/improved_wgan_training
https://github.com/caogang/wgan-gp
https://link.zhihu.com/?target=https%3A//github.com/igul222/improved_wgan_training
https://github.com/caogang/wgan-gp
WGAN-GP是WGAN之后的改進版,主要還是改進了連續性限制的條件,因為,作者也發現將權重剪切到一定范圍之后,比如剪切到[-0.01,+0.01]后,發生了這樣的情況,如下圖左邊表示。
發現大多數的權重都在-0.01 和0.01上,這就意味了網絡的大部分權重只有兩個可能數,對於深度神經網絡來說不能充分發揮深度神經網絡的擬合能力,簡直是極大的浪費。並且,也發現強制剪切權重容易導致梯度消失或者梯度爆炸,梯度消失很好理解,就是權重得不到更新信息,梯度爆炸就是更新過猛了,權重每次更新都變化很大,很容易導致訓練不穩定。梯度消失與梯度爆炸原因均在於剪切范圍的選擇,選擇過小的話會導致梯度消失,如果設得稍微大了一點,每經過一層網絡,梯度變大一點點,多層之后就會發生梯度爆炸 。為了解決這個問題,並且找一個合適的方式滿足lipschitz連續性條件,作者提出了使用梯度懲罰(gradient penalty)的方式以滿足此連續性條件,其結果如上圖右邊所示。
梯度懲罰就是既然Lipschitz限制是要求判別器的梯度不超過K,那么可以通過建立一個損失函數來滿足這個要求,即先求出判別器的梯度d(D(x)),然后建立與K之間的二范數就可以實現一個簡單的損失函數設計。但是注意到D的梯度的數值空間是整個樣本空間,對於圖片(既包含了真實數據集也包含了生成出的圖片集)這樣的數據集來說,維度及其高,顯然是及其不適合的計算的。作者提出沒必要對整個數據集(真的和生成的)做采樣,只要從每一批次的樣本中采樣就可以了,比如可以產生一個隨機數,在生成數據和真實數據上做一個插值
於是就算解決了在整個樣本空間上采樣的麻煩。
所以WGAN-GP的貢獻是:
◆ 提出了一種新的lipschitz連續性限制手法—梯度懲罰,解決了訓練梯度消失梯度爆炸的問題。
◆ 比標准WGAN擁有更快的收斂速度,並能生成更高質量的樣本
◆ 提供穩定的GAN訓練方式,幾乎不需要怎么調參,成功訓練多種針對圖片生成和語言模型的GAN架構
但是論文提出,由於是對每個batch中的每一個樣本都做了梯度懲罰(隨機數的維度是(batchsize,1)),因此判別器中不能使用batch norm,但是可以使用其他的normalization方法,比如Layer Normalization、Weight Normalization和Instance Normalization,論文中使用了Layer Normalization,weight normalization效果也是可以的。為了比較,還是祭出了下面這張圖,可以發現WGAN-GP完爆其他GAN:
6.LSGAN
最小二乘GAN
全稱是Least Squares Generative Adversarial Networks
全稱是Least Squares Generative Adversarial Networks
【github】
https://github.com/hwalsuklee/tensorflow-generative-model-collections
https://github.com/guojunq/lsgan
LSGAN原理:
https://github.com/guojunq/lsgan
LSGAN原理:
其實原理部分可以一句話概括,即使用了最小二乘損失函數代替了GAN的損失函數。
但是就這樣的改變,緩解了GAN訓練不穩定和生成圖像質量差多樣性不足的問題。事實上,作者認為使用JS散度並不能拉近真實分布和生成分布之間的距離,使用最小二乘可以將圖像的分布盡可能的接近決策邊界,其損失函數定義如下:
但是就這樣的改變,緩解了GAN訓練不穩定和生成圖像質量差多樣性不足的問題。事實上,作者認為使用JS散度並不能拉近真實分布和生成分布之間的距離,使用最小二乘可以將圖像的分布盡可能的接近決策邊界,其損失函數定義如下:
其中作者設置a=c=1,b=0論文里還是給了一些數學推導與證明,感興趣的可以去看看生成結果展示:
7.BEGAN
(不是EBGAN)
BEGAN全稱是Boundary Equilibrium GANs
【GitHub】:
https://github.com/carpedm20/BEGAN-tensorflow
https://github.com/Heumi/BEGAN-tensorflow
https://github.com/carpedm20/BEGAN-pytorch
https://github.com/Heumi/BEGAN-tensorflow
https://github.com/carpedm20/BEGAN-pytorch
BEGAN的主要貢獻:
◆ 提出了一種新的簡單強大GAN,使用標准的訓練方式,不加訓練trick也能很快且穩定的收斂
◆ 對於GAN中G,D的能力的平衡提出了一種均衡的概念(GAN的理論基礎就是goodfellow理論上證明了GAN均衡點的存在,但是一直沒有一個准確的衡量指標說明GAN的均衡程度)
◆ 提出了一種收斂程度的估計,這個機制只在WGAN中出現過。作者在論文中也提到,他們的靈感來自於WGAN,在此之前只有wgan做到了
◆ 提出了一種收斂程度的估計,這個機制只在WGAN中出現過。作者在論文中也提到,他們的靈感來自於WGAN
先說說BEGAN的主要原理,BEGAN和其他GAN不一樣,這里的D使用的是auto-encoder結構,就是下面這種,D的輸入是圖片,輸出是經過編碼解碼后的圖片,
往的GAN以及其變種都是希望生成器生成的數據分布盡可能的接近真實數據的分布,當生成數據分布等同於真實數據分布時,我們就確定生成器G經過訓練可以生成和真實數據分布相同的樣本,即獲得了生成足以以假亂真數據的能力,所以從這一點出發,研究者們設計了**各種損失函數去令G的生成數據分布盡可能接近真實數據分布。**BEGAN代替了這種估計概率分布方法,它不直接去估計生成分布Pg與真實分布Px的差距,進而設計合理的損失函數拉近他們之間的距離,而是估計分布的誤差之間的距離,作者認為只要分布的的誤差分布相近的話,也可以認為這些分布是相近的。即如果我們認為兩個人非常相似,又發現這兩人中的第二個人和第三個人很相似,那么我們就完全可以說第一個人和第三個人長的很像。
在BEGAN中,第一個人相當於訓練的數據x,第二個人相當於D對x編碼解碼后的圖像D(x),第三個人相當於D以G的生成為輸入的結果D(g(z)),所以,如果||D(x)-x|| - || D(x)- D(g(z)) || 不斷趨近於0,那么隨着訓練,D(x)會不斷接近x,那么D(g(z)) 接近於D(x),豈不是就意味着 g(z) 的數據分布和x分布幾乎一樣了,那么就說明G學到了生成數據的能力。於是乎,假設圖片足夠大,像素很多。但是問題來了,如果||D(x)-x|| - || D(x)- D(g(z)) ||剛好等於0,這時候,D(x)和x可能還差的很遠呢,那不就什么也學不到了D(x)-x是一個圖片,假設圖片上的每一個像素都滿足獨立同分布條件,根據中心極限定理,像素的誤差近似滿足正太分布,假設期望是m1,方差是μ1,同理D(x)- D(g(z)),還有m2, μ1這時候如果我們再用wassertein距離衡量m1與m2的距離,
在BEGAN中,第一個人相當於訓練的數據x,第二個人相當於D對x編碼解碼后的圖像D(x),第三個人相當於D以G的生成為輸入的結果D(g(z)),所以,如果||D(x)-x|| - || D(x)- D(g(z)) || 不斷趨近於0,那么隨着訓練,D(x)會不斷接近x,那么D(g(z)) 接近於D(x),豈不是就意味着 g(z) 的數據分布和x分布幾乎一樣了,那么就說明G學到了生成數據的能力。於是乎,假設圖片足夠大,像素很多。但是問題來了,如果||D(x)-x|| - || D(x)- D(g(z)) ||剛好等於0,這時候,D(x)和x可能還差的很遠呢,那不就什么也學不到了D(x)-x是一個圖片,假設圖片上的每一個像素都滿足獨立同分布條件,根據中心極限定理,像素的誤差近似滿足正太分布,假設期望是m1,方差是μ1,同理D(x)- D(g(z)),還有m2, μ1這時候如果我們再用wassertein距離衡量m1與m2的距離,
再滿足下面這個條件下,
即他們成正比,這時候連lipschitz連續性條件也不需要了,
但是有一個問題,當m1和m2很接近是,條件1是趨於無窮的,不可能再忽略,於是,boundary(限制)就來了,
設置一個位於[0~1]之間的數λ,強制將m1和m2划分開界限,具體的損失函數如下:
BEGAN的訓練結果:不同的γ可以在圖片的質量和生成多樣性之間做選擇。
所以說BEGAN效果還是很強的,當然先不考慮最新nvidia的漸進訓練GAN,這篇之后會介紹。
這里直介紹了一些對GAN在訓練和生成上改進的工作,具體還有很多很多很多很多沒有介紹到,這里只是挑選了一些典型的,用的比較多的來介紹一下。感興趣的可以去看看https://github.com/hindupuravinash/the-gan-zoo
GAN動物園,上百個GAN等着被翻牌。
8.GAN的基本代碼
###################################a.起始情況
#是一個卷積神經網絡,變量名是D,其中一層構造方式如下。
w = tf.get_variable('w', [4, 4, c_dim, num_filter],
initializer=tf.truncated_normal_initializer(stddev=stddev))
dconv = tf.nn.conv2d(ddata, w, strides=[1, 2, 2, 1], padding='SAME')
biases = tf.get_variable('biases', [num_filter],
initializer=tf.constant_initializer(0.0))
bias = tf.nn.bias_add(dconv, biases)
dconv1 = tf.maximum(bias, leak*bias)
...
#是一個逆卷積神經網絡,變量名是G,其中一層構造方式如下。
#是一個卷積神經網絡,變量名是D,其中一層構造方式如下。
w = tf.get_variable('w', [4, 4, c_dim, num_filter],
initializer=tf.truncated_normal_initializer(stddev=stddev))
dconv = tf.nn.conv2d(ddata, w, strides=[1, 2, 2, 1], padding='SAME')
biases = tf.get_variable('biases', [num_filter],
initializer=tf.constant_initializer(0.0))
bias = tf.nn.bias_add(dconv, biases)
dconv1 = tf.maximum(bias, leak*bias)
...
#是一個逆卷積神經網絡,變量名是G,其中一層構造方式如下。
w = tf.get_variable('w', [4, 4, num_filter, num_filter*2],
initializer=tf.random_normal_initializer(stddev=stddev))
deconv = tf.nn.conv2d_transpose(gconv2, w,
output_shape=[batch_size, s2, s2, num_filter],
strides=[1, 2, 2, 1])
biases = tf.get_variable('biases', [num_filter],
initializer=tf.constant_initializer(0.0))
bias = tf.nn.bias_add(deconv, biases)
deconv1 = tf.nn.relu(bias, name=scope.name)
...
#的網絡輸入為一個維服從-1~1均勻分布的隨機變量,這里取的是100.
initializer=tf.random_normal_initializer(stddev=stddev))
deconv = tf.nn.conv2d_transpose(gconv2, w,
output_shape=[batch_size, s2, s2, num_filter],
strides=[1, 2, 2, 1])
biases = tf.get_variable('biases', [num_filter],
initializer=tf.constant_initializer(0.0))
bias = tf.nn.bias_add(deconv, biases)
deconv1 = tf.nn.relu(bias, name=scope.name)
...
#的網絡輸入為一個維服從-1~1均勻分布的隨機變量,這里取的是100.
batch_z = np.random.uniform(-1, 1, [config.batch_size, self.z_dim])
.astype(np.float32)
#的網絡輸入是一個batch的64*64的圖片,
#既可以是手寫體數據也可以是的一個batch的輸出。
.astype(np.float32)
#的網絡輸入是一個batch的64*64的圖片,
#既可以是手寫體數據也可以是的一個batch的輸出。
#這個過程可以參考上圖的a狀態,判別曲線處於不夠穩定的狀態,
#兩個網絡都還沒訓練好。
#兩個網絡都還沒訓練好。
############################b.訓練判別網絡
#判別網絡的損失函數由兩部分組成,一部分是真實數據判別為1的損失,一部分是的輸出self.G#判別為0的損失,需要優化的損失函數定義如下。
self.G = self.generator(self.z)
self.D, self.D_logits = self.discriminator(self.images)
self.D_, self.D_logits_ = self.discriminator(self.G, reuse=True)
self.d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
self.D_logits, tf.ones_like(self.D)))
self.d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
self.D_logits_, tf.zeros_like(self.D_)))
self.d_loss = self.d_loss_real + self.d_loss_fake
#然后將一個batch的真實數據batch_images,和隨機變量batch_z當做輸入,執行session更新的參數。
self.D, self.D_logits = self.discriminator(self.images)
self.D_, self.D_logits_ = self.discriminator(self.G, reuse=True)
self.d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
self.D_logits, tf.ones_like(self.D)))
self.d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
self.D_logits_, tf.zeros_like(self.D_)))
self.d_loss = self.d_loss_real + self.d_loss_fake
#然后將一個batch的真實數據batch_images,和隨機變量batch_z當做輸入,執行session更新的參數。
##### update discriminator on real
d_optim = tf.train.AdamOptimizer(FLAGS.learning_rate,
beta1=FLAGS.beta1).minimize(d_loss, var_list=d_vars)
...
out1 = sess.run([d_optim], feed_dict={real_images: batch_images,
noise_images: batch_z})
#這一步可以對比圖b,判別曲線漸漸趨於平穩。
#####################c.訓練生成網絡
#生成網絡並沒有一個獨立的目標函數,它更新網絡的梯度來源是判別網絡對偽造圖片求的梯度,
#並且是在設定偽造圖片的label是1的情況下,保持判別網絡不變,
#那么判別網絡對偽造圖片的梯度就是向着真實圖片變化的方向。
#並且是在設定偽造圖片的label是1的情況下,保持判別網絡不變,
#那么判別網絡對偽造圖片的梯度就是向着真實圖片變化的方向。
self.g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
self.D_logits_, tf.ones_like(self.D_)))
#然后用同樣的隨機變量batch_z當做輸入更新
self.D_logits_, tf.ones_like(self.D_)))
#然后用同樣的隨機變量batch_z當做輸入更新
g_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1)
.minimize(self.g_loss, var_list=self.g_vars)
...
out2 = sess.run([g_optim], feed_dict={noise_images:batch_z})
.minimize(self.g_loss, var_list=self.g_vars)
...
out2 = sess.run([g_optim], feed_dict={noise_images:batch_z})
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
沒什么不同
哪么重點來了,那么多GAN改進版,到底哪一個效果更好呢,最新的Google一項研究表明,GAN、WGAN、WGAN GP、LS GAN、DRAGAN、BEGAN啥的,都差不多,差不多,不多,為什么都差不多呢?因為天黑得時候他們都仰望同一片星空,忽然想起來了曲婉婷的一首歌—《沒有什么不同》
哪么重點來了,那么多GAN改進版,到底哪一個效果更好呢,最新的Google一項研究表明,GAN、WGAN、WGAN GP、LS GAN、DRAGAN、BEGAN啥的,都差不多,差不多,不多,為什么都差不多呢?因為天黑得時候他們都仰望同一片星空,忽然想起來了曲婉婷的一首歌—《沒有什么不同》
Google研究原文請見:https://arxiv.org/abs/1711.10337
在此項研究中,Google此項研究中使用了minimax損失函數和用non-saturating損失函數的GAN,分別簡稱為MM GAN和NS GAN,對比了WGAN、WGAN GP、LS GAN、DRAGAN、BEGAN,除了DRAGAN上文都做了介紹,另外還對比的有VAE(變分自編碼器)。
對比細節:
為了很好的說明問題,研究者們兩個指標來對比了實驗結果,分別是FID和精度(precision、)、召回率(recall)以及兩者的平均數F1。
其中FID(Fréchet distance(弗雷歇距離) )是法國數學家Maurice René Fréchet在1906年提出的一種路徑空間相似形描述,直觀來說是狗繩距離:主人走路徑A,狗走路徑B,各自走完這兩條路徑過程中所需要的最短狗繩長度,如下圖所示,所以說,FID與生成圖像的質量呈負相關。
為了更容易說明對比的結果,研究者們自制了一個類似mnist的數據集,數據集中都是灰度圖,圖像中的目標是不同形狀的三角形。
具體比較細節就不詳細展開了,這里做一個結論總結
在圖像生成方面,發現了VAE生成結果最差,其他的GAN等等生成質量都差不多,也很好理解其實,個人認為VAE更適合於對數據進行重構,對數據降維或者生成要求不是很高的數據上很方便(填補缺失數據),但是生成數據上還是GAN更勝一籌。
最后,研究者們也在精度(precision、)、召回率(recall)以及兩者的平均數F1上做了測試,測試細節請看論文,也並沒有發現其他GAN比原始GAN更突出的地方。
參考文獻:
https://www.cnblogs.com/bonelee/p/9166122.html
https://blog.csdn.net/solomon1558/article/details/52555083
————————————————
版權聲明:本文為CSDN博主「sakura小櫻」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Sakura55/article/details/81514828
https://blog.csdn.net/solomon1558/article/details/52555083
————————————————
版權聲明:本文為CSDN博主「sakura小櫻」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Sakura55/article/details/81514828