生成對抗網路GAN入門

生成對抗網路GAN入門

來自專欄機器學習隨筆15 人贊了文章

什麼是對抗生成網路?

一般來說:

  • 對抗生成網路有一個生成器Generator與一個判別器Discriminator。
  • 生成器Generator負責從隨機雜訊生成圖片,由於這些圖片不是真的,所以是Fake image
  • 判別器Discriminator負責判別這些圖片是真的圖片Real image,還是由Generator生成的Fake image

那麼在訓練過程中,我們希望Generator生成的圖片足夠真實,能夠騙過Discriminator;同時希望Discriminator又足夠強大,能夠很好的分辨出真圖與生成圖。最後在訓練中Generator與Discriminator達到一種「對抗」中的平衡,訓練結束。

這時候我們抽取出訓練好的Generator網路,就能夠替我們「生成」製造想要的圖片了。文章題圖就是一個GAN生成數字的典型應用示意圖。

生成圖片的數學原理

生成圖片其實並不是個新東西,但是為啥偏偏GAN這麼火?分析一下數學原理你就明白了。

還是建議讀者了解下。當然看如果只是看熱鬧,可以跳過這段。

首先引入2個概念:

1. 信息熵(Entropy)

根據香農(Shannon)信息熵公式,對於任意一個隨機變數 x,那麼信息熵 H(x) 定義如下,單位bit。由於 0<P(x)<1 , H(x)>0

H(x)=-sum_{x}^{}{P(x)log_2P(x)}

H(x) 表示隨機變數 x 的無序混亂程度,當 H(x) 越大 x 越混亂,隨機性越強。

舉例說明。不妨假設 xin{0,1} ,即只有兩種可能取值,那麼:

H=-plog_2p-(1-p)log_2(1-p)

利用求導法計算最大值:

frac{partial H}{partial p}=-(log_2p+pfrac{1}{p})-(-log_2(1-p)-(p-1)frac{1}{p-1})=0

p=1-pRightarrow p=0.5

即當每種可能發生概率相等時, x 的無序混亂度最大,也最無法預測哪種情況發生。

2. KL散度(Kullback-Leibler Divergence)

已知P(x)Q(x) 是隨機變數 x 的兩種不同分布,則 PQ 的KL散度為:

KL(P||Q)=sum_{x}^{}{P(x_i)left[ log_2P(x_i)-log_2Q(x_i)
ight]}=sum_{x}^{}{P(x_i)log_2frac{P(x_i)}{Q(x_i)}}

那麼:

KL(P||Q)=E_{xsim P(x)}left[ log_2P(x)-log_2Q(x) 
ight]

可以看出,KL散度其實是數據的分布 P 和分布 Q 之間的對數差值的期望,同時也表示PQ間信息損失的二進位位數。

那麼接下來分析生圖片的原理:

  • 假設給定一組數據 x 服從概率分布 P_{data}(x) ,記為 x sim P_{data}(x)
  • 對於以 x 為輸入的分布P_G(x;	heta) , 通過學習參數 	heta ,使得 P_G(x;	heta) 接近 P_{data}(x) ,那麼這樣就能找到一個Generator。

如何學習參數 	heta ?顯然最常用的辦法就是最大似然估計了。又是數學補考過的節奏~

那麼從 x sim P_{data}(x) 中採集一組樣本 {x^1,x^2,...,x^m} ,建立極大似然估計 L(	heta)

使得 L(	heta) 取得最大值時的 	heta^* 即為我們想要的值:

注意到樣本 {x^1,x^2,...,x^m} 來源自 x sim P_{data}(x) ,所以:

需要說明,公式中綠色橫線項是一個 	heta 無關的常數項,所以減去後不會影響 	heta^* 的結果。

看到這裡,一切很自然。我們要找的 	heta^* 就是使得 KL(P_{data}(x)||P_G(x;	heta)) 取得最小值的 	heta 參數。當得出 	heta^* 就會獲得一個想要的 Generator=P_G(x;	heta^*) ,就搞定了唄。

但是仔細想想好像不是那麼回事啊?

首先 P_{data}(x) 的數學表達式就很難寫出。比如我們要生成數字圖片,那麼數字圖片的 P_{data}(x) 表達式是什麼,你能寫出來么?更複雜的人臉圖片呢?那更別說找個具有足夠一般性和替代性的 P_G(x;	heta) 去接近 P_{data}(x) 。當然後續的求解徹底涼涼。

所以生成對抗網路GAN的最大貢獻,就是用神經網路黑盒代替了上述過程:

用Gernerator代替 P_G(x;	heta) ,用Discriminator代替 P_{data}(x) 去約束Gernerator。

使我們不再需要去琢磨 P_{data}(x) P_G(x;	heta) 這些東西的表達式,用玄學戰勝了困難。

生成對抗網路GAN(Generative Adversarial Nets)

千萬不要問哪裡去看GAN的代碼,Tensorflow早已經為大家造好了輪子:

wiseodd/generative-models

來看看GAN的網路結構:

  • Generator(G)

所謂的生成器,就是將 n	imes n 大小的隨機雜訊 z 上採樣到 28	imes28 大小的圖片(mnist圖片大小)。

設隨機雜訊 z 服從 P_{z}(z) 分布,即zsim P_{z}(z) 。那麼生成器的輸出可以表示為 G(z)

  • Discriminator(D)

圖2

所謂判別器,其實就是一個分類網路,輸入為 28	imes28 大小的圖片,記為x 。輸出 D(x) 是一個 (0,1) 之間的常數,代表輸入 x 為數字圖片的概率。

定義GAN的Cost value如下:

V(D,G)=E_{xsim P_{data}(x)}left[ log D(x) 
ight]+E_{zsim P_z(z)}left[log (1-D(G(z))) 
ight]

那麼希望找到的Generator是:

G^*=min_Gmax_DV(D,G)

如何理解?首先來感性的認識下 V(D,G)

判別器是一個二分類模型,判斷輸入的圖片是Real image or Fake image。

假定判別器輸入 x ,輸出 y ,則信息熵為:

H(D)=-ylog D(x) -(1-y)log(1-D(x))

當有 N 個樣本 {(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}H(D) 的估計值為:

ar{H}(D)=-sum_{i=1}^{N}{y_ilog(D(x_i))-sum_{i=1}^{N}{(1-y_i)log(1-D(x_i))}}

由於 N 個樣本沒有辦法完整的表示判別器 D 的分布,所以 ar{H}(D) 只是一個估計。考慮這裡的樣本 x_i 來源:

  • 圖片 x_i 是Real image,即 x_isim P_{data}(x) ,概率 y_i
  • 圖片 x_i 是Fake image,即 x_i=G(z_i) ,其中 zsim P_z(z) ,對應概率 1-y_i

那麼:

ar{H}(D)=-sum_{i=1}^{N}{y_ilog(D(x_i))-sum_{i=1}^{N}{(1-y_i)log(1-D(x_i))}}

=-sum_{i=1}^{N}{y_ilog(D(x_i))-sum_{i=1}^{N}{P_z(z_i)log(1-D(G(z_i)))}}

(x_i,y_i) 採樣無窮多時,即 N
ightarrowinfty 時:

H(D)=lim_{N
ightarrowinfty}ar{H}(D)=-E_{xsim P_{data}(x)}left[ log D(x) 
ight]-E_{zsim P_z(z)}left[log (1-D(G(z))) 
ight]

即:

V(D,G)=-H(D)

G^*=min_Gmax_DV(D,G)=max_Gmin_DH(D)

  • 訓練 D ,使得 V(D,G)變大,即熵 H(D) 混亂度變小
  • 訓練 G ,使得 V(D,G)變小,即熵 H(D) 混亂度變大

最終在 minleftrightarrowmax 的博弈中整個GAN系統趨向於平衡。

關於 V(D,G) 原理的數學證明(數學公式預警)

首先考慮在給定 G 的情況下max_DV(D,G) 的含義。

V(D,G)=E_{xsim P_{data}(x)}left[ log D(x) 
ight]+E_{zsim P_z(z)}left[log (1-D(G(z))) 
ight]

=int_{x}^{}P_{data}(x)log D(x)dx+int_{z}^{}P_z(z)log(1-D(G(z)))dz

=int_{x}^{}P_{data}(x)log D(x)dx+int_{x}^{}P_G(x)log(1-D(x))dx

=int_{x}^{}left[ P_{data}(x)log D(x)+P_G(x)log(1-D(x)) 
ight]dx

當每一個 P_{data}(x)log D(x)+P_G(x)log(1-D(x)) 取得最大值時, V(D,G) 也取得最大值。

觀察函數 f(x) = a log x + blog(1 - x),在 x=frac{a}{a+b} 取得最大值(不信你自己算)。所以:

D^*(x) = frac{P_{data}(x)}{P_{data}(x) + P_G(x)}

在給定 G 時, D^* 使 V(D,G) 取得最大值。

然後將 D^* 帶入 max_DV(D,G)

max_DV(D,G)=E_{xsim P_{data}(x)}left[log D^*(x)
ight]+E_{zsim P_z(z)} left[ log(1-D^*(G(z))) 
ight]

=E_{xsim P_{data}(x)}left[log D^*(x)
ight]+E_{xsim P_G(x)} left[ log(1- D^*(x)) 
ight]

=E_{xsim P_{data}(x)}left[log frac{P_{data}(x)}{P_{data}(x) + P_G(x)}
ight]+E_{xsim P_G(x)} left[ log(frac{P_{G}(x)}{P_{data}(x) + P_G(x)}) 
ight]

=int_{x}^{}P_{data}(x)logfrac{frac{1}{2}P_{data}(x)}{frac{P_{data}(x) + P_G(x)}{2}}dx + int_{x}^{}P_G(x)logfrac{frac{1}{2}P_G(x)}{frac{P_{data}(x) + P_G(x)}{2}}dx

=-2log2+KL(P_{data}(x)||frac{P_{data}(x)+P_G(x)}{2})+KL(P_G(x)||frac{P_{data}(x)+P_G(x)}{2})

D 固定的情況下,當通過訓練 G 使得 P_G(x)approx P_{data}(x) ,即 G 生成的圖片與真實圖片非常接近的情況下獲得 G^*

看到這,GAN的訓練過程就是小菜一碟了。

圖3

條件生成對抗網路CGAN(Conditional Generative Adversarial Nets)

OK,了解了GAN的基本原理後,就可以生成數字了。但是有一個問題,GAN生成的數字是完全隨機的,即具體生成 0sim 9 中的哪一個數字依賴於隨機輸入 zsim P_z(x)

那麼如果只想固定生成某個具體數字怎麼辦?這時就要用到CGAN網路了。

定義CGAN:

Generator為 G(z|y) ,代表輸入雜訊z和標籤 y 的情況下生成的特定 y 類別圖片。

Discrimiator為D(x|y),代表輸入輸入圖片 x 經過判別後是 y 類別的概率。

同時 V(D,G) 如下:

V(D,G)=E_{xsim P_{data}(x)}left[ log D(x|y) 
ight]+E_{zsim P_z(z)}left[log (1-D(G(z|y))) 
ight]

要尋找的 G^* 如下:

G^*=min_Gmax_DV(D,G)

相比於原始GAN,其實就是多了個類別標籤 y ,並將原來的2分類變為多分類。

圖4

那麼這個 y 是什麼?也許是個矩陣,反正每個類別有自己特定的 y ,只需要將 xy 拼接或相加在一起就能形成 x|y 了(當然必須保證 x|y 的生成方式,訓練和使用時是一樣的)。

還沒有懂CGAN?看看下面這個代碼吧。

github.com/wiseodd/gene

參考文獻:

[1] Agustinus Kristiadis Blog (GitHub stars 3k+)

Generative Adversarial Nets in TensorFlow

Conditional Generative Adversarial Nets in TensorFlow

[2] 李宏毅深度學習課程

李宏毅深度學習(2017)

Machine Learning and having it deep and structured (2017,Spring)


推薦閱讀:

從下往上看--新皮層資料的讀後感 第三部分 MP神經元-70年前的逆向推演
[圖集] mnist
機器學習研究人員需要了解的8個神經網路架構(上)
Neural ODE:連續層的可變深度的神經網路,將殘差網路變為微分方程
DeepMind《Nature》子刊發文:AI「元強化學習」的關鍵因素同樣存在於人類大腦

TAG:神經網路 | 生成對抗網路GAN | 深度學習DeepLearning |