作者丨蘇劍林
單位丨廣州火焰資訊科技有限公司
研究方向丨NLP,神經網路
個人主頁丨kexue.fm
事實上,O-GAN 的發現,已經達到了我對 GAN 的理想追求,使得我可以很愜意地跳出 GAN 的大坑了。所以現在我會試圖探索更多更廣的研究方向,比如 NLP 中還沒做過的任務,又比如圖神經網路,又或者其他有趣的東西。
不過,在此之前,我想把之前的 GAN 的學習結果都記錄下來。
這篇文章中,我們來梳理一下 GAN 的架構發展情況,當然主要的是生成器的發展,判別器一直以來的變動都不大。還有,本文介紹的是 GAN 在影象方面的模型架構發展,跟 NLP 的 SeqGAN 沒什麼關係。
此外,關於 GAN 的基本科普,本文就不再贅述了。
話在前面
當然,從廣義上來講,影象領域的分類模型的任何進展,也算是判別器的進展(因為都是分類器,相關的技術都可能用到判別器中),而影象分類模型本質上從 ResNet 之後就沒有質的變化,這也說明 ResNet 結構對判別器基本上是最優選擇了。
但是生成器不一樣,雖然從 DCGAN 之後 GAN 的生成器也形成了一些相對標準的架構設計,但遠說不上定型,也說不上最優。直到最近也有不少工作在做生成器的新設計,比如 SAGAN 就是將 Self Attention 引入到了生成器(以及判別器)中,而大名鼎鼎的 StyleGAN 就是在 PGGAN 的基礎上引入了一個風格遷移形式的生成器。
因此,很多工作都表明,GAN 的生成器的結果還有一定的探索空間,好的生成器架構能加速 GAN 的收斂,或者提升 GAN 的效果。
DCGAN
要談到 GAN 架構發展史,肯定不得不說到 DCGAN 的,它在 GAN 史上稱得上是一個標誌性事件。
基本背景
眾所周知,GAN 起源於 Ian Goodfellow 的文章 Generative Adversarial Networks [1],但早期的 GAN 僅僅侷限在 MNIST 這樣的簡單資料集中。這是因為 GAN 剛出來,雖然引起了一波人的興趣,但依然還處於試錯階段,包括模型架構、穩定性、收斂性等問題都依然在探索中。而 DCGAN 的出現,為解決這一系列問題奠定了堅實的基礎。
DCGAN 出自文章 Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks [2]。要說它做了什麼事情,其實也簡單:它提出了一種生成器和判別器的架構,這個架構能極大地穩定 GAN 的訓練,以至於它在相當長的一段時間內都成為了 GAN 的標準架構。
說起來簡單,但事實上能做到這個事情很不容易,因為直觀上“合理”的架構有很多,從各種組閤中篩選出近乎最優的一種,顯然是需要經過相當多的實驗的。
而正因為 DCGAN 幾乎奠定了 GAN 的標準架構,所以有了 DCGAN 之後,GAN 的研究者們可以把更多的精力放到更多樣的任務之上,不再過多糾結於模型架構和穩定性上面,從而迎來了 GAN 的蓬勃發展。
架構描述
好了,說了這麼多,我們回到架構本身的討論之上。DCGAN 所提出的模型架構大致如下:
1. 生成器和判別器均不採用池化層,而採用(帶步長的)的摺積層;其中判別器採用普通摺積(Conv2D),而生成器採用反摺積(DeConv2D);
2. 在生成器和判別器上均使用 Batch Normalization;
3. 在生成器除輸出層外的所有層上使用 RelU 啟用函式,而輸出層使用 Tanh 啟用函式;
4. 在判別器的所有層上使用 LeakyReLU 啟用函式;
5. 摺積層之後不使用全連線層;
6. 判別器的最後一個摺積層之後也不用 Global Pooling,而是直接 Flatten。
其實現在看來,這還是一種比較簡單的結構,體現了大道至簡的美感,進一步證明瞭好的必然是簡潔的。
DCGAN 的結構示意圖如下:
▲ DCGAN的判別器架構(左)和生成器架構(右)
個人總結
幾個要點:
1. 摺積和反摺積的摺積核大小為 4*4 或者 5*5;
2. 摺積和反摺積的 stride 一般都取為 2;
3. 對於判別器來說,第一層摺積後一般不用 BN,而後面都是“Conv2D+BN+LeakReLU”的組合樣式,直到 feature map 的大小為 4*4;
4. 對於生成器來說,第一層是全連線,然後 reshape 為 4*4 大小,然後是“Conv2D+BN+ReLU”的組合樣式,最後一層摺積則不用 BN,改用 tanh 啟用;相應地,輸入圖片都要透過除以 255 然後乘以 2 減去 1,來縮放到 -1~1 之間。
雖然從引數量看可能很大,但事實上 DCGAN 很快,而且佔視訊記憶體不算多,所以很受大家歡迎。因此雖然看起來很老,但至今仍然很多工都在用它。至少在快速實驗上,它是一種優秀的架構。
ResNet
隨著 GAN 研究的日益深入,人們逐漸發現了 DCGAN 架構的一些不足之處。
DCGAN的問題
公認的說法是,由於 DCGAN 的生成器中使用了反摺積,而反摺積固有地存在“棋盤效應(Checkerboard Artifacts)”,這個棋盤效應約束了DCGAN的生成能力上限。關於棋盤效應,詳細可以參考 Deconvolution and Checkerboard Artifacts [3](強烈推薦,超多效果圖示)。
▲ 棋盤效應圖示,體現為放大之後出現如國際象棋棋盤一樣的交錯效應。圖片來自文章 Deconvolution and Checkerboard Artifacts
準確來說,棋盤效應不是反摺積的問題,而是 stride > 1 的固有毛病,這導致了摺積無法“各項同性”地改寫整張圖片,而出現了交錯效應,如同國際象棋的棋盤一般。而反摺積通常都要搭配 stride > 1 使用,因此通常認為是反摺積的問題。
事實上,除了反摺積,膨脹摺積也會有棋盤效應,因為我們可以證明膨脹摺積在某種轉化下,其實等價於 stride > 1 的普通摺積。
另一方面,筆者估計還有一個原因:DCGAN 的非線效能力也許不足。分析過 DCGAN 結果的讀者會留意到,如果輸入的圖片大小固定後,整個 DCGAN 的架構基本都固定的,包括模型的層數。
唯一可以變化的似乎就只有摺積核大小(通道數也可以稍微調整,但其實調整空間不大),改變摺積核大小可以在一定程度上改變模型的非線效能力,但改變摺積核大小僅僅改變了模型的寬度,而對於深度學習來說深度可能比寬度更重要。問題就是對於 DCGAN 來說,沒有一種自然而直接的方法來增加深度。
ResNet模型
由於以上原因,並且隨著 ResNet 在分類問題的日益深入,自然也就會考慮到 ResNet 結構在 GAN 的應用。事實上,目前 GAN 上主流的生成器和判別器架構確實已經變成了 ResNet,基本結果圖示如下:
▲ 基於ResNet的判別器架構(左)和生成器架構(右),中間是單個ResBlock的結構
可以看到,其實基於 ResNet 的 GAN 在整體結構上與 DCGAN 並沒有太大差別(這進一步肯定了 DCGAN 的奠基作用),主要的特點在於:
1. 不管在判別器還是生成器,均去除了反摺積,只保留了普通摺積層;
2. 摺積核的大小通常統一使用 3*3 的,摺積之間構成殘差塊;
3. 透過 AvgPooling2D 和 UpSampling2D 來實現上/下取樣,而 DCGAN 中則是透過 stride > 1 的摺積/反摺積實現的;其中 UpSampling2D 相當於將影象的長/寬放大若干倍;
4. 由於已經有殘差,所以啟用函式可以統一使用 ReLU,當然,也有一些模型依然使用 LeakyReLU,其實區別不大;
5. 透過增加 ResBlock 的摺積層數,可以同時增加網路的非線效能力和深度,這也是 ResNet 的靈活性所在;
6. 一般情況下殘差的形式是 x+f(x),其中 f 代表摺積層的組合;不過在 GAN 中,模型的初始化一般要比常規分類模型的初始化更小,因此穩定起見,有些模型乾脆將其改為 x+α×f(x),其中 α 是一個小於 1 的數,比如 0.1,這樣能獲得更好的穩定性;
7. 有些作者認為 BN 不適合 GAN,有時候會直接移除掉,或者用 LayerNorm 等代替。
個人總結
我沒有認真考究過首先把 ResNet 用在 GAN 中是哪篇文章,只知道 PGGAN、SNGAN、SAGAN 等知名 GAN 都已經用上了 ResNet。ResNet 的 stride 都等於 1,因此足夠均勻,不會產生棋盤效應。
然而,ResNet 並非沒有缺點。雖然從引數量上看,相比 DCGAN,ResNet 並沒有增加引數量,有些情況下甚至比 DCGAN 引數量更少,但 ResNet 比 DCGAN 要慢得多,所需要的視訊記憶體要多得多。
這是因為 ResNet 層數更多、層之間的連線更多,所以導致梯度更複雜,並且並行性更弱了(同一層摺積可以並行,不同層摺積是串聯的,無法直接並行),結果就是更慢了,更佔視訊記憶體了。
還有,棋盤效應實際上是一種非常細微的效應,也許僅僅是在高畫質圖生成時才能感受到它的差異。
事實上在我的實驗中,做 128*128 甚至 256*256 的人臉或 LSUN 生成,並沒有明顯目測到 DCGAN 和 ResNet 在效果上的差異,但是 DCGAN 的速度比 ResNet 快 50% 以上,在視訊記憶體上,DCGAN 可以直接跑到 512*512 的生成(單個 1080ti),而 ResNet 的話,跑 256*256 都有些勉強。
因此,如果不是要 PK 目前的最優 FID 等指標,我都不會選擇 ResNet 架構。
SELF-MOD
正常來說,介紹完 ResNet 後,應該要介紹一下 PGGAN、SAGAN 等模型的,畢竟從解析度或者 IS、FID 等指標上來看,它們也算是一個標誌性事件。
不過我並不打算介紹它們,因為嚴格來講,PGGAN 並不是一種新的模型架構,它只是提供了一個漸進式的訓練策略,這種訓練策略可以用到 DCGAN 或 ResNet 架構上;而 SAGAN 其實改動並不大,標準的 SAGAN 只不過在普通的 DCGAN 或 ResNet 架構中間,插入了一層 Self Attention,不能算生成器架構上的大變動。
接下來介紹一個比較新的改進:Self Modulated Generator,來自文章 On Self Modulation for Generative Adversarial Networks [4],我這裡直接簡稱為“SELF-MOD”好了。
條件BN
要介紹 SELF-MOD 之前,還需要介紹一個東西:Conditional Batch Normalization(條件 BN)。
眾所周知,BN 是深度學習尤其是影象領域常見的一種操作。說實話我不大喜歡 BN,但不得不說的是它在不少 GAN 模型中發揮了重要作用。常規的 BN 是無條件的:對於輸入張量,其中 i,j,k,l 分別表示影象的 batch、長、寬、通道維度,那麼在訓練階段有:
其中:
是輸入批資料的均值方差,其中 N=batch_size×長×寬,而 β,γ 是可訓練引數,ϵ 則是小的正常數,用來防止除零錯誤。除此之外,維護一組滑動平均變數,在測試階段的使用滑動平均的均值方差。
之所以說這樣的 BN 是無條件的,是因為引數 β,γ 純粹由梯度下降得到,不依賴於輸入。相應地,如果 β,γ 依賴於某個輸入 y,那麼就稱為條件 BN:
這時候 βl(y),γ(y) 是某個模型的輸出。先來說說怎麼實現。其實在 Keras 中,實現條件 BN 非常容易,參考程式碼如下:
def ConditionalBatchNormalization(x, beta, gamma):
"""為了實現條件BN,只需要將Keras自帶的BatchNormalization的
beta,gamma去掉,然後傳入外部的beta,gamma即可;為了訓練上的穩定,
beta最好能做到全0初始化,gamma最好能做到全1初始化。
"""
x = BatchNormalization(center=False, scale=False)(x)
def cbn(x):
x, beta, gamma = x
for i in range(K.ndim(x)-2):
# 調整beta的ndim,這個根據具體情況改動即可
beta = K.expand_dims(beta, 1)
gamma = K.expand_dims(gamma, 1)
return x * gamma + beta
return Lambda(cbn)([x, beta, gamma])
SELF-MOD GAN
條件BN首先出現在文章 Modulating early visual processing by language 中,後來又先後被用在 cGANs With Projection Discriminator 中,目前已經成為了做條件 GAN(cGAN)的標準方案,包括 SAGAN、BigGAN 都用到了它。
簡單來說,它就是把條件 c 作為 β,γ 的條件,然後構成條件 BN,替換掉生成器的無條件 BN。也就是說,生成器的主要輸入還是隨機噪聲 z,然後條件 c 則傳入到生成器的每一個 BN 中。
說那麼多條件 BN,它跟 SELF-MOD 有什麼關係呢?
情況是這樣的:SELF-MOD 考慮到 cGAN 訓練的穩定性更好,但是一般情況下 GAN 並沒有標簽 c 可用,那怎麼辦呢?乾脆以噪聲 z 自身為標簽好了!這就是 Self Modulated 的含義了,自己調節自己,不借助於外部標簽,但能實現類似的效果。用公式來描述就是:
在原論文中,β(z) 是兩層全連線網路:
γ(z) 也是一樣的,而且看了下官方原始碼,發現中間層的維度可以取得更小一些,比如 32,這樣不會明顯增加引數量了。
這就是無條件 GAN 的 SELF-MOD 結構的生成器。
個人總結
我結合了自己的 O-GAN 實驗了一下 SELF-MOD 結構,發現收斂速度幾乎提升了 50%,而且最終的 FID 和重構效果都更優一些,SELF-MOD 的優秀可見一斑,而且隱隱有種感覺,似乎 O-GAN 與 SELF-MOD 更配(哈哈,不知道是不是自戀的錯覺)。
▲ SELF-MOD形式的DCGAN生成器。基於ResNet的也類似,都只是將BN替換成SELF-MOD版本的
Keras 參考程式碼如下:
https://github.com/bojone/o-gan/blob/master/o_gan_celeba_sm_4x4.py
另外,哪怕在 cGAN 中,也可以用 SELF-MOD 結構。標準的 cGAN 是將條件 c 作為 BN 的輸入條件,SELF-MOD 則是將 z 和 c 同時作為 BN 的輸入條件,參考用法如下:
其中 E,E′ 是兩個 Embedding 層,類別數比較少的情況下,直接理解為全連線層就行了,γ 同理。
其他架構
讀者可能很奇怪,怎麼還沒談到著名的 BigGAN [5] 和 StyleGAN [6]?
事實上,BigGAN 並沒有做模型架構做出特別的改進,而且作者本身也承認這隻不過是“暴力出奇跡”罷了;而對於 StyleGAN,它確實改進了模型架構,但是理解了前面的 SELF-MOD 之後,其實也就不難理解 StyleGAN 了,甚至可以將 StyleGAN 看成是 SELF-MOD 的一個變種。
AdaIN
StyleGAN 的核心,是一個叫做AdaIN(Adaptive Instance Normalization)的玩意,來源於風格遷移的文章 Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization [7]。它其實跟條件 BN 差不多,甚至比條件 BN 還簡單:
跟條件 BN 的差別是:條件 BN 是 μl 和 σl,而 AdaIN 則是 μi,l 和 σi,l,也就是說 AdaIN 僅僅是在單個樣本內部算統計特徵,不需要用一批樣本算,因此 AdaIN 也不用維護滑動平均的均值和方差,所以其實它比條件 BN 還簡單。
StyleGAN
▲ StyleGAN形式的DCGAN生成器。基於ResNet的也類似,大體的改動就是將條件BN換成AdaIN
有了 SELF-MOD 和 AdaIN 後,其實就可以把 StyleGAN 說清楚了,StyleGAN 的主要改動也就是生成器,相比於 SELF-MOD,它的不同之處在於:
1. 取消頂部的噪聲輸入,換成一個可訓練的常數向量;
2. 將所有條件 BN 換成 AdaIN;
3. AdaIN 的輸入條件是將噪聲用多層 MLP 變換後,再用不同的變換矩陣投影為不同 AdaIN 的 β 和 γ。
就這麼簡單~
個人總結
我自己也實驗過一個簡化的 StyleGAN 形式的 DCGAN,發現能收斂,效果也還行,但有輕微的 Mode Collapse。
由於官方的 StyleGAN 是用了 PGGAN 的樣式進行訓練的,而我沒有,所以我猜測是不是 StyleGAN 要配合 PGGAN 才能訓練好呢?目前還沒有答案。只是在我的實驗裡,SELF-MOD 要比 StyleGAN 好訓練得多,效果也更好。
文章彙總
本文簡單地梳理了一下 GAN 的模型架構變化情況,主要是從 DCGAN、ResNet 到 SELF-MOD 等變動,都是一些比較明顯的改變,可能有些細微的改進就被忽略了。
一直以來,大刀闊斧地改動 GAN 模型架構的工作比較少,而 SELF-MOD 和 StyleGAN 則再次燃起了一部分人對模型架構改動的興趣。Deep Image Prior [8] 這篇文章也表明瞭一個事實:模型架構本身所蘊含的先驗知識,是影象生成模型可以成功的重要原因。提出更好的模型架構,意味著提出更好的先驗知識,自然也就有利於影象生成了。
本文所提及的一些架構,都是經過自己實驗過的,所作出評價都是基於自己的實驗和審美觀,如有不到位之處,請各位讀者斧正。
參考文獻
[1] Ian J. Goodfellow, Jean Pouget-Abadie, Mehdi Mirza, Bing Xu, David Warde-Farley, Sherjil Ozair, Aaron Courville, and Yoshua Bengio. Generative Adversarial Networks. NIPS, 2014.
[2] Alec Radford, Luke Metz, Soumith Chintala. Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks. ICLR, 2016.
[3] Odena, et al., “Deconvolution and Checkerboard Artifacts”, Distill, 2016. http://doi.org/10.23915/distill.00003
[4] Ting Chen, Mario Lucic, Neil Houlsby, and Sylvain Gelly. On self Modulation for Generative Adversarial Networks. arXiv preprint arXiv:1810.01365, 2018.
[5] Andrew Brock, Jeff Donahue and Karen Simonyan. Large Scale GAN Training for High Fidelity Natural Image Synthesis. ICLR 2019.
[6] Tero Karras, Samuli Laine, and Timo Aila. A Style-Based Generator Architecture for Generative Adversarial Networks. Proc. IEEE Conference on Computer Vision and Pattern Recognition (CVPR) 2019.
[7] Huang, Xun and Belongie, Serge. Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization. ICCV 2017.
[8] Ulyanov, Dmitry and Vedaldi, Andrea and Lempitsky, Victor. Deep Image Prior. Proc. IEEE Conference on Computer Vision and Pattern Recognition (CVPR) 2018.
朋友會在“發現-看一看”看到你“在看”的內容