# 李宏毅_ATDL_Lecture_21
###### tags: `Hung-yi Lee` `NTU` `Advance Topics in Deep Learning`
[課程撥放清單](https://www.youtube.com/channel/UC2ggjtuuWvxrHHHiaDH1dlQ/playlists)
## Energy-based GAN
[課程連結](https://www.youtube.com/watch?v=gFaqKdcCdOE&list=PLJV_el3uVTsPMxPbjeX7PicgWbY7F8wW9&index=21)
### Original Idea

快速複習原始GAN,原始GAN中,Discriminator扮演著引導者的角色,其中資料集與Discriminator(紅色線)的關係就如上面圖示一般,會試著將藍色的分佈(生成資料)引導至綠色分佈(真實資料),幾次迭代之後,兩個分佈幾近重疊,那Discriminator就功成身退。
### Original GAN

這影片也在之前的課程有看過,[影片連結](https://www.youtube.com/watch?v=ebMei6bYeWw)(Beniamin Striner)
很清楚的,Discriminator是Linear,而distribution是中間的原點,但這種情況下Generator沒有辦法只是一個Linear的function,它會比較複雜。而Discriminator的工作就只是引導分佈的移動,它可以是簡單的。
### Evaluation Function

之前談Structure learning時提到,處理一個問題的時候可以定義一個Evaluation function,其輸入為object-x,輸出F(x)<sub>(可以是一個`nn`)</sub>為scalar,這個scalar評估這個輸入的x有『多好』。以影像為例,真實的影像經過function之後得到的輸出應該是高的。如果我們可以找到一個x讓F(x)產生很高的值,那就可以利用F(x)來生成影像。
找出F(x)的概念如下:
1. 在real data的地方其值愈大愈好
2. 看起來不real的data其值愈小愈好
但這麼做的一個問題是,real data就是你的實際資料,這可以窮舉,但其它的非real data太多了,根本無法窮舉。
### Evaluation Function - Structured Perceptron

Structured Perceptron課程提到,我們的輸入是$x,\hat{y}$的成對資料,然後找一個weight vector-w,意思是我們的function-$F(x,y)=w \cdot \phi(x,y)$,找weight vector-w就是找$F(x,y)$,其演算法如下:
* 初始化 w=0
* 對每一個$(x^r,\hat{y}^r)$的成對資料做計算
* 找一個$\widetilde{y}^r$來最大化$F(x^r,y)$
* $x^r$是給定的資料,找$\widetilde{y}^r$最大化function
* 這是解arg max的問題,窮舉所有可能的$\widetilde{y}^r$讓$F(x^r,y)$最大
* 如果找到的$\widetilde{y}^r$不是$\hat{y}^r$,更新參數w如下
* $w \rightarrow w + \phi(x^r, \hat{y}^r) - \phi(x^r, \widetilde{y}^r)$
* 我們希望增加$F(x^r, \hat{y}^r)$出現的機率,減少$F(x^r, \widetilde{y}^r)$出現的機率
* 直到w不再更新
這個task中,Evaluation Function就是$F(x,y)$,剛才提過,要找出這個function是困難的,如果$y$是有結構性的東西的話,那更為困難,因為你根本無法窮舉,這導致$F(x,y)$無法過於複雜。
### How about GAN?

回過頭來用GAN的角度來看,Generator只是用比較聰明的方法來找negative的example,直觀來看,簡報右上圖我們可以清楚看到,我們讓實際資料(綠色分佈)的F(x)值是大的,而生成資料(藍色分佈)的F(x)的值是小的,我們並不清楚這兩個分佈之外的情況會是怎麼樣,因此它也可能是像圖表(最上)呈現一般。
但我們會更新Generator讓F(x)最大,也許更新之後分佈移動至右邊(中圖),但更新的時候我們會壓低Generator的output,因此它會讓F(x)變小(下圖)。
最終,兩個分佈重疊,讓F(x)變大與變小的力道會相互抵消,最終停止更新,你找到F(x),也就是discriminator,這時候discriminator告訴我們real data的分佈是出現在什麼地方,density愈高,output值就愈大。
實作GAN過程中,有些人會將過去幾次迭代的資料也當做negative data,讓機器知道過去錯誤資料的分佈的存在,這種作法稱之為『experience replay』。
每次的迭代Discriminator都不是重頭訓練,而是繼承過去參數,原始GAN的想法中,Discriminator的作用在於評估兩個divergence之間的差異,這似乎不需要繼承過去的參數,但實際上它就是繼承,而且訓練好GAN之後的Discriminator也可以應用於其它專案上,並非丟棄。
Energy-based的想法上,Discriminator必需要是可以Model實際資料的分佈,而稍早的影片上所示,他的Discriminator就是一個Linear的function,這並沒有辦法Model資料分佈,因此Energy-based的話,Discriminator的capacity要夠大才有辦法Model資料分佈,而不只是引導Generator的行進方向。
### Energy-based GAN(EBGAN)

[論文連結_Energy-based Generative Adversarial Network](https://arxiv.org/abs/1609.03126)
* 在EBGAN中,它將Discriminator視為energy function,也就是將evaluation function取負號。(structure learning中evaluation function output愈大代表資料愈真實,而energy function output愈小則代表資料愈真實。)
* 論文中一個特別的點是使用Auto-encoder來做Discriminator,也就是energy function
* Loss fucntion中加入margin
* 可以合出256x256的圖片
### EBGAN

EBGAN中的Generator與其它相似,input-$z$,output-$x$,特別的在於Discriminator,裡面是一個Auto-encoder,input-$x$,output-$\widetilde{x}$,要注意到的是,Discriminator的output應該是一個scalar,但Auto-encoder的output是image,並不會是一個scalar,因此得到scalar的方式就是將input與output相減,即$\Vert x-\widetilde{x} \Vert$,也就是計算它的reconstruction error有多大,它是這個Discriminator的output或者是energy function的energy,其最小值為0,最大可至無窮大。
訓練EBGAN的方式:
1. sample real example x
2. sample code z from prior distribution
3. put z into generator then get image
4. updata discriminator D to minimize
* Discriminator的Loss fucntion如下:
* $L_D(x,z)=D(x)+max(0,m-D(G(z)))$
* D(x):要讓real data的D(x)愈小愈好
5. sample code z from prior distribution
6. update generator G to minimize
* Generator的Loss function如下:
* $LG(z)=D(G(z))$
* $G(z)$得到影像,做為input經過$D(x)$得到的值愈小愈好
一定要特別注意到,這跟之前講GAN的部份是反過來的,EBGAN是energy function,愈小愈好。
### EBGAN

這邊說明Discriminator loss function的意義。
直觀來看,Discriminator的loss function應該是$L_D(x,z)=D(x)-D(G(z))$,也就是希望在real的地方其輸出愈低愈好,在fake的地方其輸出愈高愈好<sub>(注意,energy function是希望output愈低愈好)</sub>,但實際上對於real的定義,最好也不過是output為0,而且reconstruct是困難的,但要train壞它是很簡單的,而且輸出還可以是無窮大,這種情況下會造成模型可能專注在放大fake而不收斂real。
因此,Discriminator的loss function才會是$L_D(x,z)=D(x)+max(0,m-D(G(z)))$:
* $m$:為一個定義好的margin
* $max(0,m-D(G(z)))$:當$m-D(G(z))>0$的時候才有loss,也就是當生成的影像帶到$D(x)$之後的output如果大過$m$就不存在penalty,這樣機器就會知道再大的output只要大過$m$就會被忽略,自然就會往壓低real的output。
Generator的loss function-$D(G(z))$比較直覺,就是單純的希望其output的energy是小的,也就自然而然的往real的地方靠近。
### EBGAN

當real data distribution與generator data distribution一模一樣的時候就意味著$D(x)$的值會與$D(G(z))$的值相同,假設其值為$\gamma$,當$\gamma$介於0與m之間的時候,其loss皆為m。
在訓練完之後,在real data distribution的部份,其$\gamma$會介於0與m之間,但其餘的部份並不會,因為我們使用Auto-encoder,其reconstruction error為低的區域在input空間上是有限的,只有少部份的input會在經過Bottleneck之後會被完整地正確的重建,也就是只有少量的區域會是低的energy(real data的區域),而其它的部份就會有高的energy,因此利用Auto-encoder不會有原始GAN會train壞掉的情況。
### More about EBGAN

Pulling-away term for training generator,這是希望generator的輸出可以多樣性:
1. 讓generator輸出batch data:$S=\left\{...x_i...x_j...\right\}$
2. 除了最小化energy function之外,加入此項$f_{PT}(S)=\sum_{i,j,i\neq j}cos(e_i,e_j)$
* 意思是,將生成的資料兩兩取出,丟到discriminator,取編碼的輸出$e$,我們希望這兩個愈不像愈好,也就是Cosine Similarity愈小愈好。
另外論文中也提到,可以將EBGAN視為一種訓練Auto-encoder的方法,原始Auto-encoder只是單純的讓reconstruction error變小,但在GAN的情境中還加入讓generator的假資料的reconstruction error變大。這樣做的好處在於,Auto-encoder不會有機會因為架構設計不良而單純的將real image背下來,因為它加入了generator的假資料,必須讓reconstruction error變大,也就避免這個Auto-encoder是一個Identity function(恆等函數)。
### Margin Adaptation GAN(MAGAN)

[論文連結_MAGAN: Margin Adaptation for Generative Adversarial Networks](https://arxiv.org/abs/1704.03817)
**EBGAN的進階版本為MAGAN**
簡報中右上圖為實際資料的energy,右下圖為生成資料的energy,較底的黑線為30取log,較高的黑線為70取log,在原始EBGAN訓練中,我們會希望生成的資料其energy會大過margin<sub>(即m的設置)</sub>,從生成資料的energy圖示來看,確實EBGNA有做到這件事。
比較兩圖可以發現,訓練初期機器並沒有花太多心思在壓下實際資料的energy,反而是在忙著讓生成資料的energy上升,一直到後期才開始讓實際資料的energy下降。而且也發現到,即使到訓練後期,生成資料的energy也沒有下降,如果後期的生成資料已經是夠真實了,那它的energy應該也是低的才對,但原始EBGAN的設計是要讓生成資料的energy放大,因此機器會花費心思在給生成資料至少大於m的energy。這從兩圖後段的energy可以看的出來。
Margin Adaptation GAN希望以一個動態的方式來調控,因此m是一個浮動的值,而且會愈來愈小,直觀來看,隨著訓練迭代次數的增多,生成的資料應該愈來愈真實,相對的應該就要有較小的energy,也就是調低margin讓生成資料有較小的energy。
可以看的到兩圖的藍線不管是在真實資料或是生成資料的energy都是在下降的,這也反應目前生成的資料是愈來愈好的。
### Loss-sensitive GAN(LSGAN)

[論文連結_Loss-Sensitive Generative Adversarial Networks on Lipschitz Densities](https://arxiv.org/abs/1701.06264)
LSGAN中雖然沒有提到energy的概念,但有提到adaptive margin的概念。
假設我們將LSGAN內的$D(x)$視為energy function(再次的說明,LSGAN內並沒有提到energy的概念),其最佳化函式為:
$D(x)+max(0, \Delta(x, G(z)+D(x)-D(G(z))))$
前段$D(x)$為real的資料,後段為fake的資料處理。
### Loss-sensitive GAN(LSGAN)

以圖形來說明,縱軸為energy,愈低代表愈好。
我們希望real的資料($x$)所得energy愈低愈好,也就是discriminator的output愈低愈好,而fake的資料我們希望它的energy是大的,但只要超過margin-$m$就好。
假設現在有兩張照片,$G(z)$與$G(z')$,它們的energy是不同的,這個margin是由$\Delta(x,G(z))$來計算這兩張照片的相似度,因此如果它們跟real的資料差異很大的時候,它們的margin就會比較大,因此可以看的到,兩張成像品質不一的照片各自擁有它們的margin。
### Loss-sensitive GAN(LSGAN)

在說明Structural SVM也提過類似的概念。左邊在沒有加入margin概念的時候我們會希望所有正確的資料所得的evaluation是大過錯誤資料的,即$F(x^n,\hat{y}^n)\geq F(x^n,y^n)$。但引入margin概念之後,我們希望正確的資料與錯誤資料相比不只是大,而是大過一個margin,而且這個margin是adaptive。
### Boundary Equilibrium Generative Adversarial Networks(BEGAN)

[論文連結_BEGAN: Boundary Equilibrium Generative Adversarial Networks](https://arxiv.org/abs/1703.10717)
BEGAN內的discriminator也是一個Auto-encoder。論文中讓人驚豔的是,它所生成的人臉是非常真實的。
### BEGAN

基本上BEGAN的精神與EBGAN相似,不同的是它的discriminator的loss function為:
$L_D=D(x)-k_tD(G(z))$
* $k_t$為浮動值,初始化為0,這意味著在訓練初始我們希望real data的energy是低的。
* 每次迭代過程中更新$k_t$,即$k_{t+1}=k_t+\lambda(\gamma D(x)-D(G(z)))$
* $\lambda$是一個類似於learning rate的超參數,正值。
* $\gamma$是一個常數,自己設置的超參數。
* 在$\gamma D(x)-D(G(z))\space >\space 0$的時候增加
* 即$\gamma D(x) > D(G(z))$的時候增加
* 即$\dfrac{D(G(z))}{D(x)}<\gamma$的時候增加
* 意思即是,當$D(G(z))$(生成的資料)的reconstruction error已經比真實的資料還要小的時候,我們再讓生成資料的reconstruction error變大。(因為我們希望生成資料的reconstruction error是大的)
模型不會太專注在假資料(生成資料)上,只有在它們的reconstruction error太小的時候才會再來觀注它。
### BEGAN



上面圖示說明著不同的$\gamma$值產生不同的結果,放大就意味著不大管假資料,因此可以看的到設置為0.7的部份照片較不真實,但論文提到,過小的值會造成出來的資料多樣性較差。
課程上老師也補充,如果設置為0.0的時候,在Auto-coder設計夠好情況下可能最後generator所sample的資料就會很像單純真實資料內的照片而以。
最後論文還提到,他們發現到,似乎所sample的照片都沒有戴眼鏡的人,而且很單調。