當前位置:
首頁 > 知識 > LSGAN:最小二乘生成對抗網路

LSGAN:最小二乘生成對抗網路

來源:PaperWeekly

本文約2500字,建議閱讀10分鐘。

本文介紹了經典AI論文——LSGAN,它比常規GAN更穩定,比WGAN收斂更迅速。

筆者這次選擇復現的是 Least Squares Generative Adversarial Networks,也就是LSGANs。

近幾年來 GAN 是十分火熱的,由 Goodfellow 在 14 年發表論文 Generative Adversarial Nets [1] 開山之作以來,生成式對抗網路一直都備受機器學習領域的關注,這種兩人零和博弈的思想十分有趣,充分體現了數學的美感。從 GAN 到 WGAN [2] 的優化,再到本文介紹的 LSGANs,再到最近很火的 BigGAN [3],可以說生成式對抗網路的魅力無窮,而且它的用處也是非常奇妙,如今還被用在例如無負樣本的情況下如何訓練分類器,例如AnoGAN [4]。

LSGANs 這篇經典的論文主要工作是把交叉熵損失函數換做了最小二乘損失函數,這樣做作者認為改善了傳統 GAN 的兩個問題,即傳統 GAN 生成的圖片質量不高,而且訓練過程十分不穩定。

LSGANs 試圖使用不同的距離度量來構建一個更加穩定而且收斂更快的,生成質量高的對抗網路。但是我看過 WGAN 的論文之後分析這一損失函數,其實並不符合 WGAN 作者的分析。在下面我會詳細分析一下為什麼 LSGANs 其實並沒有那麼好用。

論文復現代碼:

http://aistudio.baidu.com/aistudio/#/projectdetail/25767


LSGANs的優點

我們知道傳統 GAN 生成的圖片質量不高,傳統的 GANs 使用的是交叉熵損失(sigmoid cross entropy)作為判別器的損失函數。

在這裡說一下我對交叉熵的理解,有兩個分布,分別是真實分布 p 和非真實分布 q。

信息熵是,就是按照真實分布 p 這樣的樣本空間表達能力強度的相反值,信息熵越大,不確定性越大,表達能力越弱,我們記作 H(p)。 交叉熵就是,可以理解為按照不真實分布 q 這樣的樣本空間表達能力強度的相反值,記作 H(p,q)。

KL 散度就是 D(p||q) = H(p,q) - H(p),它表示的是兩個分布的差異,因為真實分布 p 的信息熵固定,所以一般由交叉熵來決定,所以這就是為什麼傳統 GAN 會採用交叉熵的緣故,論文也證明了 GAN 損失函數與 KL 散度的關係。

我們知道交叉熵一般都是拿來做邏輯分類的,而像最小二乘這種一般會用在線性回歸中,這裡為什麼會用最小二乘作為損失函數的評判呢?

使用交叉熵雖然會讓我們分類正確,但是這樣會導致那些在決策邊界被分類為真的、但是仍然遠離真實數據的假樣本(即生成器生成的樣本)不會繼續迭代,因為它已經成功欺騙了判別器,更新生成器的時候就會發生梯度彌散的問題。

論文指出最小二乘損失函數會對處於判別成真的那些遠離決策邊界的樣本進行懲罰,把遠離決策邊界的假樣本拖進決策邊界,從而提高生成圖片的質量。作者用下圖詳細表達了這一說法:

我們知道傳統 GAN 的訓練過程十分不穩定,這很大程度上是因為它的目標函數,尤其是在最小化目標函數時可能發生梯度彌散,使其很難再去更新生成器。而論文指出 LSGANs 可以解決這個問題,因為 LSGANs 會懲罰那些遠離決策邊界的樣本,這些樣本的梯度是梯度下降的決定方向。

論文指出因為傳統 GAN 辨別器 D 使用的是 sigmoid 函數,並且由於 sigmoid 函數飽和得十分迅速,所以即使是十分小的數據點 x,該函數也會迅速忽略樣本 x 到決策邊界 w 的距離。這就意味著 sigmoid 函數本質上不會懲罰遠離決策邊界的樣本,並且也說明我們滿足於將 x 標註正確,因此辨別器 D 的梯度就會很快地下降到 0。

我們可以認為,交叉熵並不關心距離,而是僅僅關注於是否正確分類。

正如論文作者在下圖中所指出的那樣:

(a)圖看到交叉熵損失很容易就達到飽和狀態

(b)圖最小二乘損失只在一點達到飽和,作者認為這樣訓練會更加穩定。


LSGANs的損失函數

傳統 GAN 的損失函數:

LSGANs 的損失函數:

其中 G 為生成器(Generator),D 為判別器(Discriminator),z 為噪音,它可以服從歸一化或者高斯分布,為真實數據 x 服從的概率分布,為 z 服從的概率分布。為期望值,同為期望值。

def generator(z, name="G"):

with fluid.unique_name.guard(name+"_"):

fc1 = fluid.layers.fc(input = z, size = 1024)

fc1 = fluid.layers.fc(fc1, size = 128 * 7 * 7)

fc1 = fluid.layers.batch_norm(fc1,act = "tanh")

fc1 = fluid.layers.reshape(fc1, shape=(-1, 128, 7, 7))

conv1 = fluid.layers.conv2d(fc1, num_filters = 4*64,

filter_size=5, stride=1,

padding=2, act="tanh")

conv1 = fluid.layers.reshape(conv1, shape=(-1,64,14,14))

conv2 = fluid.layers.conv2d(conv1, num_filters = 4*32,

filter_size=5, stride=1,

padding=2, act="tanh")

conv2 = fluid.layers.reshape(conv2, shape=(-1,32,28,28))

conv3 = fluid.layers.conv2d(conv2, num_filters = 1,

filter_size=5, stride=1,

padding=2,act="tanh")

# conv3 = fluid.layers.reshape(conv3, shape=(-1,1,28,28))

print("conv3",conv3)

return conv3

生成器代碼展示

def discriminator(image, name="D"):

with fluid.unique_name.guard(name+"_"):

conv1 = fluid.layers.conv2d(input=image, num_filters=32,

filter_size=6, stride=2,

padding=2)

conv1_act = fluid.layers.leaky_relu(conv1)

conv2 = fluid.layers.conv2d(conv1_act, num_filters=64,

filter_size=6, stride=2,

padding=2)

conv2 = fluid.layers.batch_norm(conv2)

conv2_act = fluid.layers.leaky_relu(conv2)

fc1 = fluid.layers.reshape(conv2_act, shape=(-1,64*7*7))

fc1 = fluid.layers.fc(fc1, size=512)

fc1_bn = fluid.layers.batch_norm(fc1)

fc1_act = fluid.layers.leaky_relu(fc1_bn)

fc2 = fluid.layers.fc(fc1_act, size=1)

print("fc2",fc2)

return fc2

判別器代碼展示

作者提出了兩種 abc 的取值方法:

1. 使 b - c = 1,b - a = 2,例如 a = -1,b = 1,c = 0:

2. 使 c = b,用 0-1 二元標籤,我們可以得到:

作者在文獻中有詳細推倒過程,詳細說明了 LSGAN 與 f 散度之間的關係,這裡簡述一下。

通過對下式求一階導可得到 D 的最優解:

代入:

其中另加項並不影響的值,因為它不包含參數 G。

最後我們設 b - c = 1,b - a =2 就可以得到:

其中就是皮爾森卡方散度。


LSGANs未能解決的地方

下面我會指出 LSGANs 給出的損失函數到底符不符合 WGAN 前作的理論。關於 WGAN 前作及 WGAN 論文的分析可以參考本文 [5]。

上面我們指出了 D 的最優解為公式(5),我們最常用的設 a=-1,b=1,c=0 可以得出:

把最優判別器帶入上面加附加項的生成器損失函數可以表示為:

也就是優化上面說的皮爾森卡方散度,其實皮爾森卡方散度和 KL 散度、JS 散度有一樣的問題,根據 WGAN 給出的理論,下面用 P1,P2 分別表示和。

當 P1 與 P2 的支撐集(support)是高維空間中的低維流形(manifold)時,P1 與 P2 重疊部分測度(measure)為 0 的概率為 1。也就是 P1 和 P2 不重疊或重疊部分可忽略的可能性非常大。

對於數據點 x,只可能發生如下四種情況:

1. P1(x)=0,P2(x)=0

2. P1(x)!=0,P2(x)!=0

3. P1(x)=0,P2(x)!=0

4. P1(x)!=0,P2(x)=0

可以想像成下面這幅圖,假設 P1(x) 分布就是 AB 線段,P2(x) 分布就是 CD 線段,數據點要麼在兩條線段的其中一條,要麼都不在,同時在兩條線段上的可能性忽略不計。

情況 1 是沒有意義的,而情況 2 由於重疊部分可忽略的可能性非常大所以對計算損失貢獻為 0,情況 3 可以算出 D*=-1,損失是個定值 1,情況 4 類似。

所以我們可以得出結論,當 P1 和 P2 不重疊或重疊部分可忽略的可能性非常大時,當判別器達到最優時,生成器仍然是不迭代的,因為此時損失是定值,提供的梯度仍然為 0。同時我們也可以從另一個角度出發,WGAN 的 Wasserstein 距離可以變換如下:

它要求函數 f 要符合 Lipschitz 連續,可是最小二乘損失函數是不符合的,他的導數是沒有上界的。所以結論就是 LSGANs 其實還是未能解決判別器足夠優秀的時候,生成器還是會發生梯度彌散的問題。


兩種模型架構和訓練

模型的結構

作者也提出了兩類架構:

第一種處理類別少的情況,例如 MNIST、LSUN。網路設計如下:

第二類處理類別特別多的情形,實際上是個條件版本的 LSGAN。針對手寫漢字數據集,有 3740 類,提出的網路結構如下:

訓練數據

論文中使用了很多場景的數據集,然後比較了傳統 GANs 和 LSGANs 的穩定性,最後還通過訓練 3740 個類別的手寫漢字數據集來評價 LSGANs。

本文使用的數據集列表

在 LSUN 和 HWDB1.0 的這兩個數據集上使用 LSGANs 的效果圖如下,其中 LSUN 使用了裡面的 bedroom, kitchen, church, dining room 和 conference room 五個場景,bedroom 場景還對比了 DCGANs 和 EBGANs 的效果在圖 5 中,可以觀察到 LSGANs 生成的效果要比那兩種的效果好。

圖 7 則體現了 LSGANs 和傳統 GANs 生成的圖片對比。

通過實驗觀察,作者發現 4 點技巧:

生成器 G 帶有 batch normalization 批處理標準化(以下簡稱 BN)並且使用 Adam 優化器的話,LSGANs 生成的圖片質量好,但是傳統 GANs 從來沒有成功學習到,會出現 mode collapse 現象;

生成器 G 和判別器 D 都帶有 BN 層,並且使用 RMSProp 優化器處理,LSGANs 會生成質量比 GANs 高的圖片,並且 GANs 會出現輕微的 mode collapse 現象;

生成器 G 帶有 BN 層並且使用 RMSProp 優化器,生成器 G 判別器 D 都帶有 BN 層並且使用 Adam 優化器時,LSGANs 與傳統 GANs 有著相似的表現;

RMSProp 的表現比 Adam 要穩定,因為傳統 GANs 在 G 帶有 BN 層時,使用 RMSProp 優化可以成功學習,但是使用 Adam 優化卻不行。

下面是使用 LSGANs 和 GANs 學習混合高斯分布的數據集,下圖展現了生成數據分布的動態結果,可以看到傳統 GAN 在 Step 15k 時就會發生 mode collapse 現象,但 LSGANs 非常成功地學習到了混合高斯分布。


論文具體實現

筆者使用了 MNIST 數據集進行實驗,具體實現效果如下:

LSGANs:

GAN:

從本次用 MNIST 數據訓練的效果來看,LSGANs 生成的效果似乎是比 GAN 的要清晰高質量一些。


總結

LSGANs 是對 GAN 的一次優化,從實驗的情況中,筆者也發現了一些奇怪的現象。我本來是參考論文把判別器 D 的損失值,按真假兩種 loss 加起來一併放入 Adam 中優化,但是無論如何都學習不成功,梯度還是彌散了,最後把 D_fake_loss 和 D_real_loss 分為兩個 program,放入不同的 Adam 中優化判別器D 的參數才達到預期效果。

這篇論文中的思想是非常值得借鑒的,從最小二乘的距離的角度考量,並不是判別器分類之後就完事了,但是 LSGANs 其實還是未能解決判別器足夠優秀的時候,生成器梯度彌散的問題。


關於PaddlePaddle

筆者反饋:幫助文檔有點少,而且我本來就直接寫好了想改成使用 GPU 運算,沒找到怎麼改;

PaddlePaddle團隊:關於如何使用 GPU 運行,可以看下執行器 Executor(單 GPU 或單線程 CPU 執行器)或 ParallelExecutor(多 GPU 或多線程 CPU 執行器,也可以單 GPU/線程 CPU 執行)的文檔,前者指定 place 為 CUDAPlace,後者介面有個 use_cuda,具體請參考文檔。也可以看 models repo 例子,比如 image_classification 或 text_classification 的例子。

筆者反饋:Program 這個概念有點新穎,一個模型可以有多個 Program,但是我實現的 GAN 可以只用一個,也可以分別放進三個 Program,沒有太了解到 Program 這個概念的優越之處,我還是像計算圖那樣使用了,官方也沒給出與 TensorFlow 的對比。

PaddlePaddle團隊:關於 Program 設計可以參考官方文檔。這裡提一點,在用戶使用的直觀感受中和 TensorFlow graph 不同的是,凡是放在一個 Program 里 op,只要運行該 Program,這些 op 就都會執行;而 TensorFlow,指定一個 variable,只運行以該 variable 為葉子節點的 graph,其他多餘 node 不執行,這是最大的用戶感受到的區別。

至於一個 Program 還是多個 Program,看用戶使用需求而定,多個 Program 時要注意的東西就比較多,例如是否要參數共享等,當然運行多次的時間代價也稍多。 如果是 GAN 也可以參考 models repo 的例子。

小道消息:聽說全新版本的 PaddlePaddle 已於今日發布哦。


參考文獻

[1]. I. Goodfellow, J. Pouget-Abadie, M. Mirza, B. Xu, D. Warde-Farley, S. Ozair, A. Courville, and Y. Bengio, 「Generative adversarial nets,」 in Advances in Neural Information Processing Systems (NIPS), pp. 2672–2680, 2014.

[2]. M. Arjovsky, S. Chintala, and L. Bottou. Wasserstein GAN. arXiv preprint arXiv:1701.07875, 2017.

[3]. Andrew Brock, Jeff Donahue and Karen Simonyan. Large Scale GAN Training for High Fidelity Natural Image Synthesis. arXiv:1809.11096, 2018.

[4]. Schlegl, Thomas, et al. "Unsupervised Anomaly Detection with Generative Adversarial Networks to Guide Marker Discovery." arXiv preprint arXiv:1703.05921 (2017).

[5]. https://zhuanlan.zhihu.com/p/25071913?from_voters_page=true


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 數據派THU 的精彩文章:

Tableau小技巧之分離Box plot和Unit Histogram
清華園裡的AI公開課!第三講之神經網路

TAG:數據派THU |