O-GAN引入正交分解實現GAN自編碼

本文來給大家分享一下筆者最近的一個工作:通過簡單地修改原來的GAN模型,就可以讓判別器變成一個編碼器,從而讓GAN同時具備生成能力和編碼能力,並且幾乎不會增加訓練成本。這個新模型被稱爲O-GAN(正交GAN,即Orthogonal Generative Adversarial Network),因爲它是基於對判別器的正交分解操作來完成的,是對判別器自由度的最充分利用。

 

Arxiv鏈接:https://arxiv.org/abs/1903.01931

開源代碼:https://github.com/bojone/o-gan

 

背景 #

筆者掉進生成模型的大坑已經很久時間了,不僅在博客中寫了多篇有關生成模型的博文,而且還往arxiv上也提交了好幾篇跟生成模型相關的小paper。自掉坑以來,雖然說對生成模型尤其是GAN的理解漸深,有時也覺得自己做出了一點改進工作(所以才提交到arxiv上),但事實上那些東西都是無關痛癢的修修補補,意義實在不大。

而本文要介紹的這個模型,自認爲比以往我做的所有GAN相關工作的價值總和還要大:它提供了目前最簡單的方案,來訓練一個具有編碼能力的GAN模型。

現如今,GAN已經越來越成熟,越做越龐大,諸如BigGAN、StyleGAN等算是目前最先進的GAN模型也已被人熟知,甚至玩得不亦樂乎。不過,這幾個最先進的GAN模型,目前都只有生成器功能,沒有編碼器功能,也就是說可以源源不斷地生成新圖片,卻不能對已有的圖片提取特徵。

當然,帶有編碼器的GAN也有不少研究,甚至本博客中就曾做過(參考《BiGAN-QP:簡單清晰的編碼&生成模型》)。但不管有沒有編碼能力,大部分GAN都有一個特點:訓練完成後,判別器都是沒有用的。因爲理論上越訓練,判別器越退化(比如趨於一個常數)。

做過GAN的讀者都知道,GAN的判別器和生成器兩個網絡的複雜度是相當的(如果還有編碼器,那麼複雜度也跟它們相當),訓練完GAN後判別器就不要了,那實在是對判別器這個龐大網絡的嚴重浪費!一般來說,判別器的架構跟編碼器是很相似的,那麼一個很自然的想法是能不能讓判別器和編碼器共享大部分權重?據筆者所知,過去所有的GAN相關的模型中,只有IntroVAE做到了這一點。但相對而言IntroVAE的做法還是比較複雜的,而且目前網上還沒有成功復現IntroVAE的開源代碼(筆者也嘗試復現過,但也失敗了。)。

而本文的方案則極爲簡單——通過稍微修改原來的GAN模型,就可以讓判別器轉變爲一個編碼器,不管是複雜度還是計算量都幾乎沒有增加。

模型 #

事不宜遲,馬上來介紹這個模型。首先引入一般的GAN寫法

D=G=argminD𝔼x∼p(x),z∼q(z)[f(D(x))+g(D(G(z)))]argminG𝔼z∼q(z)[h(D(G(z)))](1)(1)D=arg⁡minD⁡Ex∼p(x),z∼q(z)[f(D(x))+g(D(G(z)))]G=arg⁡minG⁡Ez∼q(z)[h(D(G(z)))]


爲了不至於混淆,這裏還是不厭其煩地對符號做一些說明。其中x∈ℝnx,z∈ℝnzx∈Rnx,z∈Rnz p(x)p(x)是真實圖片集的“證據分佈”,q(z)q(z)是噪聲的分佈(在本文中,它是nznz元標準正態分佈);而G:ℝnz→ℝnxG:Rnz→RnxD:ℝnx→ℝD:Rnx→R自然就是生成器和判別器了,f,g,hf,g,h則是一些確定的函數,不同的GAN對應着不同的f,h,gf,h,g。有時候我們會加一些標準化或者正則化手段上去,比如譜歸一化或者梯度懲罰,簡單起見,這些手段就不明顯地寫出來了。

 

然後定義幾個向量算符:

avg(z)=1nz∑i=1nzzi,std(z)=1nz∑i=1nz(zi−avg(z))2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾⎷,(z)=z−avg(z)std(z)(2)(2)avg(z)=1nz∑i=1nzzi,std(z)=1nz∑i=1nz(zi−avg(z))2,N(z)=z−avg(z)std(z)


寫起來貌似挺高大上的,但其實就是向量各元素的均值、方差,以及標準化的向量。特別指出的是,當nz≥3nz≥3時(真正有價值的GAN都滿足這個條件),[avg(z),std(z),(z)][avg(z),std(z),N(z)]函數無關的,也就是說它相當於是原來向量zz的一個“正交分解”。

 

接着,我們已經說了判別器的結構其實和編碼器有點類似,只不過編碼器輸出一個向量而判別器輸出一個標量罷了,那麼我可以把判別器寫成複合函數:

D(x)≜T(E(x))(3)(3)D(x)≜T(E(x))


這裏EEℝnx→ℝnzRnx→Rnz的映射,而TTℝnz→ℝRnz→R的映射。不難想象,EE的參數量會遠遠多於TT的參數量,我們希望E(x)E(x)具有編碼功能。

 

怎麼實現呢?只需要加一個loss:Pearson相關係數

T,E=G=argminT,E𝔼x∼p(x),z∼q(z)[f(T(E(x)))+g(T(E(G(z))))−λρ(z,E(G(z)))]argminG𝔼z∼q(z)[h(T(E(G(z))))−λρ(z,E(G(z)))](4)(4)T,E=arg⁡minT,E⁡Ex∼p(x),z∼q(z)[f(T(E(x)))+g(T(E(G(z))))−λρ(z,E(G(z)))]G=arg⁡minG⁡Ez∼q(z)[h(T(E(G(z))))−λρ(z,E(G(z)))]


其中

ρ(z,ẑ)=∑i=1nz(zi−avg(z))(ẑi−avg(ẑ))/nzstd(z)×std(ẑ)=cos((z),(E(G(z))))(5)(5)ρ(z,z^)=∑i=1nz(zi−avg(z))(z^i−avg(z^))/nzstd(z)×std(z^)=cos⁡(N(z),N(E(G(z))))

如果λ=0λ=0,那麼就是普通的GAN而已(只不過判別器被分解爲兩部分EETT兩部分)。加上了這個相關係數,直觀上來看,就是希望zzE(G(z))E(G(z))越線性相關越好。爲什麼要這樣加?我們留到最後討論。

顯然這個相關係數可以嵌入到任意現成的GAN中,改動量顯然也很小(拆分一下判別器、加一個loss),筆者也做了多種GAN的實驗,發現都能成功訓練。

這樣一來,GAN的判別器DD分爲了EETT兩部分,EE變成了編碼器,也就是說,判別器的大部分參數已經被利用上了。但是還剩下TT,訓練完成後TT也是沒用的,雖然TT的參數量比較少,這個浪費量是很少的,但對於有“潔癖”的人(比如筆者)來說還是很難受的。

能不能把TT也省掉?經過筆者多次試驗,結論是:還真能!因爲我們可以直接用avg(E(x))avg(E(x))做判別器

E=G=argminE𝔼x∼p(x),z∼q(z)[f(avg(E(x)))+g(avg(E(G(z))))−λρ(z,E(G(z)))]argminG𝔼z∼q(z)[h(avg(E(G(z))))−λρ(z,E(G(z)))](6)(6)E=arg⁡minE⁡Ex∼p(x),z∼q(z)[f(avg(E(x)))+g(avg(E(G(z))))−λρ(z,E(G(z)))]G=arg⁡minG⁡Ez∼q(z)[h(avg(E(G(z))))−λρ(z,E(G(z)))]


這樣一來整個模型中已經沒有TT了,只有純粹的生成器GG和編碼器EE,整個模型沒有絲毫冗餘的地方~(潔癖患者可以不糾結了)

 

實驗 #

這樣做爲什麼可以?我們放到最後再說。先看看實驗效果,畢竟實驗不好的話,原理說得再漂亮也沒有意義。

注意,理論上來講,本文引入的相關係數項並不能提高生成模型的質量,所以實驗的目標主要有兩個:1、這個額外的loss會不會有損原來生成模型的質量;2、這個額外的loss是不是真的可以讓EE變成一個有效的編碼器?

剛纔也說,這個方法可以嵌入到任意GAN中,這次實驗用的是GAN是我之前的GAN-QP的變種:

E=G=argminE𝔼x∼p(x),z∼q(z)[avg(E(x))−avg(E(G(z)))+λ1Rx,z−λ2ρ(z,E(G(z)))]argminG𝔼z∼q(z)[avg(E(G(z)))−λ2ρ(z,E(G(z)))](7)(7)E=arg⁡minE⁡Ex∼p(x),z∼q(z)[avg(E(x))−avg(E(G(z)))+λ1Rx,z−λ2ρ(z,E(G(z)))]G=arg⁡minG⁡Ez∼q(z)[avg(E(G(z)))−λ2ρ(z,E(G(z)))]


其中

Rx,z=[avg(E(x))−avg(E(G(z)))]2‖x−G(z)‖2(8)(8)Rx,z=[avg(E(x))−avg(E(G(z)))]2‖x−G(z)‖2

數據集上,這次的實驗做得比較完整,在CelebA HQ、FFHQ、LSUN-churchoutdoor、LSUN-bedroom四個數據集上都做了實驗,分辨率都是128×128128×128(其實還做了一點256×256256×256的實驗,結果也不錯,但是沒放到論文上)。模型架構跟以往一樣都是DCGAN,其餘細節直接看論文或者代碼吧。

上圖:

 

CelebA HQ隨機生成

CelebA HQ隨機生成

CelebA HQ重構效果

CelebA HQ重構效果

CelebA HQ線性插值

CelebA HQ線性插值

 

 

FFHQ隨機生成

FFHQ隨機生成

FFHQ重構效果

FFHQ重構效果

FFHQ線性插值

FFHQ線性插值

 

 

LSUN-church隨機生成

LSUN-church隨機生成

LSUN-church重構效果

LSUN-church重構效果

LSUN-church線性插值

LSUN-church線性插值

 

 

LSUN-bedroom隨機生成

LSUN-bedroom隨機生成

LSUN-bedroom重構效果

LSUN-bedroom重構效果

LSUN-bedroom線性插值

LSUN-bedroom線性插值

 

不管你們覺得好不好,反正我是覺得還好了~

1、隨機生成效果還不錯,說明新引入的相關係數項沒有降低生成質量;

2、重構效果還不錯,說明E(x)E(x)確實提取到了xx的主要特徵;

3、線性插值效果還不錯,說明E(x)E(x)確實學習到了接近線性可分的特徵。

原理 #

好,確認過眼神,哦不對,是效果,就可以來討論一下原理了。

很明顯,這個額外的重構項的作用就是讓zz儘可能與E(G(z))E(G(z))“相關”,對於它,相信大多數讀者的第一想法應該是mse損失‖z−E(G(z))‖2‖z−E(G(z))‖2而非本文用的ρ(z,E(G(z)))ρ(z,E(G(z)))。但事實上,如果加入‖z−E(G(z))‖2‖z−E(G(z))‖2那麼訓練基本上都會失敗。那爲什麼ρ(z,E(G(z)))ρ(z,E(G(z)))又會成功呢?

根據前面的定義,E(x)E(x)輸出一個nznz維的向量,但是T(E(x))T(E(x))只輸出一個標量,也就是說,E(x)E(x)輸出了nznz個自由度,而作爲判別器,T(E(x))T(E(x))至少要佔用一個自由度(當然,理論上它也只需要佔用一個自由度)。如果最小化‖z−E(G(z))‖2‖z−E(G(z))‖2,那麼訓練過程會強迫E(G(z))E(G(z))完全等於zz,也就是說nznz個自由度全部被它佔用了,沒有多餘的自由度給判別器來判別真假了,所以加入‖z−E(G(z))‖2‖z−E(G(z))‖2大概率都會失敗。但是ρ(z,E(G(z)))ρ(z,E(G(z)))不一樣,ρ(z,E(G(z)))ρ(z,E(G(z)))avg(E(G(z)))avg(E(G(z)))std(E(G(z)))std(E(G(z)))都沒關係(只改變向量E(G(z))E(G(z))avgavgstdstd,不會改變ρ(z,E(G(z)))ρ(z,E(G(z)))的值,因爲ρρ本身就先減均值除標準差了),這意味着就算我們最大化ρ(z,E(G(z)))ρ(z,E(G(z))),我們也留了至少兩個自由度給判別器。

這也是爲什麼在(6)(6)中我們甚至可以直接用avg(E(x))avg(E(x))做判別器,因爲它不會被ρ(z,E(G(z)))ρ(z,E(G(z)))的影響的。

一個相似的例子是InfoGAN。InfoGAN也包含了一個重構輸入信息的模塊,這個模塊也和判別器共享大部分權重(編碼器),而因爲InfoGAN事實上只重構部分輸入信息,因此重構項也沒佔滿編碼器的所有自由度,所以InfoGAN那樣做是合理的——只要給判別器留下至少一個自由度。

另外還有一個事實也能幫助我們理解。因爲我們在對抗訓練的時候,噪聲是z∼(0,Inz)z∼N(0,Inz)的,當生成器訓練好之後,那麼理論上對所有的z∼(0,Inz)z∼N(0,Inz)G(z)G(z)都會是一張逼真的圖片,事實上,反過來也是成立的,如果G(z)G(z)是一張逼真的圖片,那麼應該有z∼(0,Inz)z∼N(0,Inz)(即位於(0,Inz)N(0,Inz)的高概率區域)。進一步推論下去,對於z∼(0,Inz)z∼N(0,Inz),我們有avg(z)≈0avg(z)≈0以及std(z)≈1std(z)≈1。那麼,如果G(z)G(z)是一張逼真的圖片,那麼必要的條件是avg(z)≈0avg(z)≈0以及std(z)≈1std(z)≈1

應用這個結論,如果我們希望重構效果好,也就是希望G(E(x))G(E(x))是一張逼真的圖片,那麼必要的條件是avg(E(x))≈0avg(E(x))≈0以及std(E(x))≈1std(E(x))≈1。這就說明,對於一個好的E(x)E(x),我們可以認爲avg(E(x))avg(E(x))std(E(x))std(E(x))都是已知的(分別等於0和1),既然它們是已知的,我們就沒有必要擬合它們,換言之,在重構項中可以把它們排除掉。而事實上:

−ρ(z,E(G(z)))∼‖‖(z)−(E(G(z)))‖‖2(9)(9)−ρ(z,E(G(z)))∼‖N(z)−N(E(G(z)))‖2


也就是說在mse損失中排除掉avg(E(x))avg(E(x))std(E(x))std(E(x))的話,然後省去常數,它其實就是−ρ(z,E(G(z)))−ρ(z,E(G(z))),這再次說明了ρ(z,E(G(z)))ρ(z,E(G(z)))的合理性。並且由這個推導,重構過程並不是G(E(x))G(E(x))而是

x̂=G((E(x)))(10)(10)x^=G(N(E(x)))

最後,這個額外的重構項理論上還能防止mode collapse的出現。其實很明顯,因爲重構質量都不錯了,生成質量再差也差不到哪裏去,自然就不會怎麼mode collapse了~非要說數學依據的話,我們可以將ρ(z,E(G(z)))ρ(z,E(G(z)))理解爲ZZG(Z)G(Z)的互信息下界,所以最小化−ρ(z,E(G(z)))−ρ(z,E(G(z)))事實上在最大化ZZG(Z)G(Z)的互信息,這又等價於最大化G(Z)G(Z)的熵。而G(Z)G(Z)的熵大了,表明它的多樣性增加了,也就遠離了mode collapse。類似的推導可以參考《能量視角下的GAN模型(二):GAN=“分析”+“採樣”》

結語 #

本文介紹了一個方案,只需要對原來的GAN進行簡單的修改,就可以將原來GAN的判別器轉化爲一個有效的編碼器。多個實驗表明這樣的方案是可行的,而對原理的進一步思考得出,這其實就是對原始判別器(編碼器)的一種正交分解,並且對正交分解後的自由度的充分利用,所以模型也被稱爲“正交GAN(O-GAN)”。

小改動就收穫一個編碼器,何樂而不爲呢?歡迎大家試用~

後記:

事後看,本文模型的思想其實本質上就是“直徑和方向”的分解,並不難理解,但做到這件事情不是那麼輕鬆的。

最開始我也一直陷入到‖z−E(G(z))‖2‖z−E(G(z))‖2的困境中,難以自拔,後來我想了很多技巧,終於在‖z−E(G(z))‖2‖z−E(G(z))‖2的重構損失下也穩定住了模型(耗了幾個月),但模型變得非常醜陋(引入了三重對抗GAN),於是我着手簡化模型。後來我嘗試用coscos值用重構損失,發現居然能夠簡單地收斂了,於是我思考背後的原理,這可能涉及到自由度的問題。

接着我嘗試將E(x)E(x)分解爲模長和方向向量,然後用模長‖E(x)‖‖E(x)‖做判別器,用coscos做重構損失,判別器的loss用hinge loss。這樣做其實幾何意義很明顯,說起來更漂亮些,部分數據集是work的,但是通用性不好(CelebA還行,LSUN不行),而且還有一個問題是‖E(x)‖‖E(x)‖非負,無法嵌入到一般的GAN,很多穩定GAN的技巧都不能用。

然後我想怎麼把模長變成可正可負,開始想着可以對模長取對數,這樣小於1的模長取對數後變成負數,大於1的模長取對數變成正數,思然達成了目的。但是很遺憾,效果還是不好。後來陸續實驗了諸多方案都不成功,最後終於想到可以放棄模長(對應於方差)做判別器的loss,直接用均值就行了~~所以後來轉換成avg(E(x))avg(E(x)),這個轉變經歷了相當長的時間。

還有,重構損失一般認爲要度量xxG(E(x))G(E(x))的差異,而我發現只需要度量zzE(G(z))E(G(z))的差異,這是最低成本的方案,因爲重構是需要額外的時間的。最後,我還做過很多實驗,很多想法哪怕在CelebA上都能成功,但LSUN上就不行。所以,最後看上去簡單的模型,實際上是艱難的沉澱。

整個模型源於我的一個執念:判別器既然具有編碼器的結構,那麼就不能被浪費掉。加上有IntroVAE的成功案例在先,我相信一定會有更簡單的方案實現這一點。前前後後實驗了好幾個月,跑了上百個模型,直到最近終於算是完整地解決了這個問題。

對了,除了IntroVAE,對我啓發特別大的還有Deep Infomax這篇論文,Deep Infomax最後的附錄裏邊提供了一種新的做GAN的思路,我開始也是從那裏的方法着手思考新模型的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章