CV_basic idea of GAN

在GAN出現之前…

假設真實的data服從P_data,並且現在擁有屬於這個分佈的一些樣本,但是這個P_data我們是無從得知的,但是我們希望可以得到一個嶄新的同樣屬於這個分佈的data。所以我們就對這個分佈建立模型,其對應着分佈P_G,希望這個P_G能夠儘可能地逼近P_data,由於這個P_G是我們自己建立的,所以這個模型或者說P_G對我們而言必然是可知的。那麼此時只要P_G能夠儘可能地逼近P_data,那麼任務就能由從未知的分佈P_data中sample出數據data轉換爲從建立的模型對應的P_G中sample出data從而簡單地被完成。關於這個模型的建立,是需要先驗知識的,從而簡化問題。首先去假設其滿足某一個分佈,那麼任務進一步地被簡化成只需要對這個分佈中的參數進行估計即可。而對於這個模型的參數的估計,可以採用的方法是:利用已存在的樣本,去估計這個假設的分佈的參數,從而使得假設的分佈P_G能夠儘可能地逼近真實的分佈P_data。常見的方法有MLL。這個方法的思路也就是很直觀地,被採樣到的樣本屬於P_data的樣本必然是出現概率最高的樣本,根據此去估計模型的參數。

這種方式的侷限就在於,嚴重依賴模型的先驗知識。P_data的分佈往往是不那麼簡單的,即假設其所屬於的分佈往往是不準確的。這就嚴重導致了P_G的準確性,即時找到了最優的P_G,也可能喝P_data相距甚遠。

這裏的data可能是任何的data,這涉及到在計算機中數據的表示。例如image—>matrix或者vector。這樣實際上就不會覺得關於image的分佈這件事情很抽象了,本質上都是在某一個空間中的一些數據點,每個數據點都可以理解爲一個vector,其維數等於這個空間的維數。

上述也提到了MLL的侷限。那麼如果希望能夠使P_G能夠儘可能地擬合P_data,就需要藉助更爲複雜的model—>NN

在MLL的公式中


可以近似爲積分的形式,即將E的求解轉換爲積分的形式。由於是

運算,所以可以加入一個參數項

從而使式子整體變成KL散度。

用於衡量P_data和P_G的相似性。

所以GAN對應的是這樣一個過程:給一個training dataset,表示sampled from P_data,一個P_prior表示隨機噪聲的分佈,一個G和一個D。輸入z sampled from P_prior,由G輸出data_G,交給D讓其判別data_G是realistic or fake;而在其他的迭代中,也加入data sampled from P_data,讓D判別data_G是realistic or fake。若不將P_data中的data也參與訓練,那麼D只需要每次都輸出0就可以獲得很好的性能了…這樣無法真正學到強勢的D。所以這是一個D和G交替更新的過程。最終,收斂後,輸入一個z sampled from P_prior就可以經過G生成一個G_data,並且這個G_data足夠逼真…

所以這和AE是一樣的過程,只不過Loss變了,AE的loss是由原始image和AE輸出的data的相似性計算得到的,而GAN的loss是由D得到的。

解析GAN的Loss Function

其中,

如何理解這個Loss Function? 前述MLL方法實際上可以理解爲在計算P_data和P_G的KL divergence,這裏GAN的Loss Function也可以用同樣的方法去分析。

本質上就是在找到D*。

<這裏有一點需要注意,雖然是關於G和D的表達式,但是還隱含着隨機變量x>

所以,很自然地,對D*進行求解,通過一次導求的極值點即可。這裏除了給定x以外,還給定了G。

這裏的P_data和P_G均爲常數。

通過計算可得,

此時V(G, D*)取得最大值。

將D*代入V(G, D)

可得

將E根據定義進行表示,可得

可知,在給定G,x下,當D=D*時,V(G, D*)爲P_data和P_G的JS divergence。<注意,是在D*=argmax_D V(G, D)時,V(G, D*)才表示JSD>

所以對於

相當於在求解能使得P_data和P_G的JS Divergence最小的G=G*,即當G*對應的P_G=P_data時,JSD(P_data, P_G*)最小。也就是說,Loss Function在引導着G向着P_data和P_G的JSD最小的方向逼近。

<這也就是爲什麼說original GAN和VAE沒有本質區別,只是在Loss Function上,GAN是藉助了D來構成Loss Function,或者說是藉助了D來引導G的學習方向。這裏的D實際上是在做一個JS divergence的度量,所以對D進行學習,就是在衡量P_data和P_G之間的距離,即JSD>

但在訓練過程中,需要注意的是,這裏的Loss Funtion中實際上是隱含着隨機變量x的。以D的訓練爲例說明,通過argmax_D V(G, D)得到的D*,實際上應該是D*(x)。也就是說,對於D來說,他是一個constant—>dD/dD=1,但是對於x來說,他是一個function—>dD/dx=D’。而在訓練時,是對x進行偏導從而進行gradient descent來更新D的參數。對於D的訓練的Loss Function是max_D V(G, D),因爲在給定的不同的x下,max_D V(G, D)是不同的值,所以對於x來說,這個Loss Function是一個max函數。

對GAN進行訓練:

實際操作中,使用的是用樣本來計算E。即用樣本均值來替代E的定義計算。所以從P_data和P_G中分別sample出相同數目m的數據,分別用於計算

<注意,V(G, D)是由上述兩部分共同構成的,所以既需要G生成的數據,同時也需要真實的數據用於GAN的訓練,否則D只需要每次判別爲fake就能達到收斂條件>

在D的訓練中,是通過計算Loss對input x的偏導來進行gradient descent以更新模型參數的。這裏的input x來源於兩部分1.真實的數據 2.G生成的數據

在G的訓練中,是通過計算Loss對input z的偏導來進行gradient descent以更新模型參數的。這裏的input z是從P_prior中採樣得到的,也就是隨機噪聲

一般情況下對D進行多次的更新後纔對G進行一次的更新。原因在於,只有當D到達最優處,對應的max_D V(G, D)纔是表示P_data和P_G之間的JSD(此時固定G,隱含着也固定x,將V(G, D)視爲D的函數)。同時,對於G的更新,不能一次更新太多。

這是由於max_D V(G0, D0)在更新G0之後(固定D),V(G1, D0)的函數可能已經發生了變化,雖然在原先的D0下,V(G1, D0)的值會比V(G0, D0)更小,但是這會導致JSD的峯值(可能在D=Di處取到)反而變得更大了,從而在下一次固定G對D進行更新時,D達到此時V的最優處,使得V的值即JSD的值反而變得更大。而我們所希望的是G的更新能朝着令JSD整體更小的方向進行的。這就與目標相違背。

最後貼上關於GAN訓練的實際算法(double loop)

Reference

臺大深度學習_李宏毅

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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