---
# System prepended metadata

title: '生成式對抗網路 (Generative Adversarial Network, GAN)'
tags: [架構設計, 李宏毅, 深度學習]

---

## 介紹生成式對抗網路（Generative Adversarial Network, GAN）
之前介紹的神經網絡例如 RNN、CNN 等，輸入通常為一組向量，但在 GAN 中輸入有兩個，分別是 x 以及 z（簡單的分布），丟入 network 後輸出一個複雜的分布，將此類模型稱之為 Generator。

這時可能會有些好奇，為什麼需要生成一個複雜的分布呢？這是因為輸出結果有兩種以上的可能性，例如在一段影片中，每當主角走到了十字路口，可以選擇向前、向右或向左三種可能，如果沒有輸出一個分布決定方向，在經過相同地方後，主角可能會分裂成三個往不同的方向前進。

因此 GAN 模型適合應用在輸出有多種可能的情境下，尤其是需要有創造力的任務上，例如畫畫、聊天機器人等，若要求模型畫出紅色眼睛的動漫人物，模型就有可能輸出像是庫拉皮卡或者是輝夜姬大小姐等圖片。

![image](https://hackmd.io/_uploads/S1x_lxoSA.png)

### 從 Unconditional generaiton 開始介紹 Generator
在 Unconditional generaiton 中，不需要考慮 x，只需要輸入一個簡單的分布，也就是低維的向量，這裡是從 normal distribution 中 sample 出一個簡單的分布作為輸入，接著丟到 Generator 輸出一個複雜的分布，也就是高維的向量，即獲得動漫人物的圖片，在「[卷積神經網路(Convolutional Neural Networks, CNN)](https://hackmd.io/@lcaMuWOwR1Ox5o5yeTEupA/r1JC1wgrR)」文章中，有提到圖片其實就是一個非常長的向量，詳細內容可以參見該文章。

![image](https://hackmd.io/_uploads/H1RAVloBC.png)

### 什麼是 Discriminator
在 GAN 中，除了需要訓練 Generator 外，還需要額外訓練 Discriminator，其實就是另一個 Neural network，將 Generator 輸出的圖片（y）作為輸入，丟入 Discriminator 後會輸出一個 Scalar，評斷圖片是否為真實或是生成的圖片，若愈接近真實的二次元圖片則 scalar 數值愈高，愈不接近則 scalar 數值愈低。

![image](https://hackmd.io/_uploads/SkWhLliHA.png)

### Generative "Adversarial" Network
在看完上述介紹後，是否有感受到 Generator 與 Discriminator 間的微妙關係呢？Generator 的任務就是要能夠輸出一張圖片，足以騙過 Discriminator 拿到高分，就好比是蝴蝶與鳥類間的對抗關係，為了保護自己的生命，蝴蝶會演化出不同的外觀、顏色，試圖騙過鳥類的眼睛，但鳥類為了掠食也會隨之演化，兩者就不斷地進化發展，與 Generator 與 Discriminator 有異曲同工之妙，因此被稱為 "adversarial"。

![image](https://hackmd.io/_uploads/H1t-RgoSA.png)

## 如何訓練 Generator 與 Discriminator
在開始前需要初始化 Generator 以及 Discriminator 的參數，接著第一步固定 G 更新 D，還沒有更新過的 G 輸出圖片品質肯定很差，因此 D 必須辨別與真實二次元圖片的差別，對 G 產生的圖片輸出一個 scalar，可以使用 Classification 或者是 Regression 輸出 0 與 1 的數值；第二步固定 D 更新 G，輸入一個簡單向量至 G，試圖產生一個圖片並丟入 D 中，期望輸出 scalar 數值愈大愈好。

接著，不斷地反覆訓練 G 與 D 兩個 neural network。

![image](https://hackmd.io/_uploads/BJBwAeoBA.png =49%x) ![image](https://hackmd.io/_uploads/r1miRxiBR.png =50%x)

:::info
若對輸入向量做一個內插並丟入 G 中，能夠輸出連續變化的圖片。
![image](https://hackmd.io/_uploads/r1mVMWoS0.png)
:::

### 訓練 Generator 與 Discriminator 之目標
訓練 GAN 的方式與訓練其他模型相當類似，在之前的幾篇文章中提及，一個理想的模型需要挑選一組好的參數（w, b）使得 loss 數值越低越好，在 GAN 中，Generator 會輸出一個圖片，期望與真實的圖片愈接近愈好，也就是說需要找到一個 G 使得 P~G~ 和 P~Data~ 之 Divergence 越小越好，而 P~G~ 和 P~Data~ 兩者之分布可以從原先的資料中 sample 一些出來，但問題在於 Divergence 要如何計算呢？在後面的內容會說明如何解決此問題。

![image](https://hackmd.io/_uploads/SyxtDVTBA.png =70%x)![image](https://hackmd.io/_uploads/SyHsD4aBA.png =30%x)

而 Discriminator 的訓練，就是找到一個 D 使得 Objective function V(D, G) 的值愈大愈好，這裡的 V(D, G) 之形式完全可以寫成不同的樣貌，這裡之所以寫出這條式子是為了與二元分類器產生連結，該式的數值其實就是 Negative cross entropy，也可以想像成最大化 Negative cross entropy 等同於最小化 Cross entropy。

:::info
以下複製「如何訓練出好模型呢？」的文章內容，有介紹到交叉熵的基本概念，以便於複習。

在分類問題中，我們希望模型可以區隔不同類別的資料，交叉熵就是用來衡量模型預測的概率分佈與實際類別之間的差異。ŷᵢ 是實際類別（one-hot編碼），yᵢ' 是預測的類別概率。

![image](https://hackmd.io/_uploads/B18xlr6SR.png)
:::
![image](https://hackmd.io/_uploads/S18HuETrC.png =99%x)

Divergence 與 Objective function 彼此間也有些關聯，如果說 Divergence 很小，也就是說 P~G~ 和 P~Data~ 之分布相當接近，對 D 而言，很難分辨哪些是 G 產生的圖片以及哪些是真實的圖片，因此 Objective function 也會較小，相反地 P~G~ 和 P~Data~ 之分布很不接近，對 D 而言，就能夠較容易辨別出 G 產生的圖片與真實的圖片之差異，Objective function 也會較高。

因此，當 Divergence 大則 Objective function 大，而 Divergence 小則 Objective function 小，便能看出兩者之間存在關聯性，並用 Objective function 取代 Divergence 重新撰寫出下面的式子 G*。

![image](https://hackmd.io/_uploads/B118uN6S0.png)

:::info
這裡的 Divergence 有非常多種寫法，不一定只能使用這裡的 JS Divergence，在 GAN 中也必須維持 Generator 與 Discriminator 互相砥礪的關係，需考慮的因素相當繁多，因此訓練 GAN 此種模型是相當困難的，很喜歡李老師的一句話「No pain, no GAN」。
:::

### 訓練 GAN 之小技巧 - Wasserstein distance
#### JS Divergence 面臨的問題
在大多數的狀況下，P~G~ 和 P~Data~ 重疊部分相當少，少到幾乎可以忽略，這是因為圖片在高維空間中是 Low-dimensional manifold，在二維空間僅是一條線，P~G~ 和 P~Data~ 兩條線能夠相交的地方非常少；再者，即使 P~G~ 和 P~Data~ 有部分重疊，往往也因為 sample 的數量不夠多，對 Discriminator 而言也相當容易就能夠將兩者分開。

![image](https://hackmd.io/_uploads/SJFO5HarA.png =49%x)![image](https://hackmd.io/_uploads/rkemjSaSR.png =28%x)![image](https://hackmd.io/_uploads/rkU-hSarC.png =23%x)

另外，對於 JS Divergence 若發現 P~G~ 和 P~Data~ 沒有重疊，輸出的值都是 log2，而重疊時輸出值為 0，在沒有重疊的情況下，使得二元分類器都能夠達到 100% 的準確度，將兩者完美地分開，因此在 GAN 的訓練過程中使用 JS Divergence 其 loss (accuracy) 是毫無意義的。

對於上述 JS Divergence 面臨到的種種問題，因此提出了 Wasserstein distance 的技巧，運用此技巧的 GAN 被稱為 WGAN。


![image](https://hackmd.io/_uploads/ByiT2H6SA.png)

#### 什麼是 Wasserstein distance
Wasserstein distance 可以想像成是一台推土機，將土堆從 A 點推到 B 點，再從 C 點推至 D 點，推行的最短平均距離就叫做 Wasserstein distance。

那使用 Wasserstein distance 有什麼樣的好處呢？上述提到，JS Divergence 若發現 P~G~ 和 P~Data~ 沒有重疊，輸出的值都是 log2，而 Wasserstein distance 最大的好處在於就算 P~G~ 和 P~Data~ 沒有重疊在一起，也能夠藉由兩者間的距離長短，判斷彼此間的關係。

![image](https://hackmd.io/_uploads/r1EuI8Tr0.png)

那具體來說 Wasserstein distance 要如何計算呢？以下寫出了它的公式，需要特別注意的地方在於 D 需要受到 1-Lipschitz 的限制，也就是說 D 需要足夠 smooth，否則為了追求最大值，容易導致 D(y) 無法收斂變成無限大與無窮小，這不是我們想要的。

![image](https://hackmd.io/_uploads/BJRN8UprR.png)

:::info
D 須滿足 1-Lipschitz 的限制有相當多種作法，以下是相關的文獻。
![image](https://hackmd.io/_uploads/HJt_KUaBA.png)
:::

## 評估 GAN 的好或壞
### Quality of image
在評估生成影像的品質時，可以將一張由 G 輸出的圖片，丟入至影像分類系統(image classifier)中，假設現有類別一、類別二、類別三，則預期該張圖片能夠在某類別上有相當高的分布機率，例如類別二，而其他類別的分布機率相當低，代表 G 輸出的圖片具有較高的品質(quality)。

![image](https://hackmd.io/_uploads/Hy8kRhRBC.png)

### Diversity
具有能夠生成多樣性的圖片，代表將每張圖片丟入影像分類器後，能夠平均地分散在各個類別中，不會有其中一個類別有特別高的機率分布，這便是有良好的多樣性。

![image](https://hackmd.io/_uploads/SyGe4pCr0.png)

在圖片多樣性評估上，往往會出現兩種常見的問題，分別是 Mode Collapse 以及 Mode Dropping。
1. Mode Collapse
由於 G 的任務是為了在 D 上取得高分，因此若有一張圖片能夠騙過 D 且不斷地拿取高分，則 G 將會輸出多張相同或類似的圖片，導致圖片多樣性降低。
2. Mode Dropping
雖然 G 在第 t 次生成圖片看似沒有問題，有足夠的人臉的多樣性，但可能在第 t+1 次生成同一批的圖片，只是改變膚色罷了，往往看了多次後，人臉都是同樣那幾張。

    ![image](https://hackmd.io/_uploads/SJN_MpRHC.png)

:::info
有良好的圖片品質、高多樣性，可以用一個量化指標來做判別，分別是 Inception score（IS） 愈高愈好以及 Fréchet inception distance（FID） 愈低愈好。

由於目前生成的圖片都是人臉，圖片的多樣性並不高，因此會避免使用 IS，改而使用 FID，拿輸出前未經過 softmax 的向量，進行評斷，這麼做是因為輸出雖然都是人臉，但是男生女生、大眼睛小眼睛等特徵讓這些向量有所不同。
:::

## GAN 之應用
### GAN 使用在文字生成上（非常困難的任務）
利用之前學習過的 Transformer 的 Decoder 架構，生成 Vector sequence 並輸出對應最大數值的方塊字，接著丟到 Discrminator 輸出一個 scalar(score)，因此也可以將 Decoder 到生成文字的過程看做是一個 Generator 在做的事情，只不過現在是文字生成，而不是輸出圖片。

為什麼 GAN 難以應用在文字生成？這是因為當微小改變 Decoder 中的參數，生成的向量也會有微小改變，但輸出是找到對應最大數值的方塊字，即使受到微小改變也不會影響輸出具有最大數值的方塊字，因此 Generator 的輸出並沒有改變，代表文字生成的任務不能做微分，也就無法進行最佳化(optimization)處理，得到一組較好的參數。

遇到難訓練的模型，往往使用強化式學習(Reinforcement learning, RL)能夠解決該問題，但 RL 本身就是一個複雜的訓練過程，再加上 GAN 本身也難以訓練，兩個合在一起往往會使問題更加複雜化。

![image](https://hackmd.io/_uploads/ByaDc86H0.png)

### Conditional GenerationConditional GAN)
還記得前半部有介紹到 Unconditional generaiton，只看一個輸入 z（簡單分布）丟入至 Generator 中輸出複雜的向量，在 Conditional Generation 中，就是要同時看 x 和 z 兩個輸入。

#### 1. 文字生成圖片
在文字生成圖片的任務中，必須讓模型在訓練過程中從成對的資料（x, y）學習，也就是監督式學習（Supervised learning），其中 x 為文字、y 為對應之圖片，訓練好的模型，便可輸入 x（文字，例如紅眼睛）以及 z（簡單分布），期望 Generator 會輸出相關的圖片例如庫拉皮卡或者是輝夜姬大小姐等圖片。

接著丟入至 Discriminator 中，期望得到的 scalar 愈大愈好，但會發生一個問題，就是 G 可能根本不會理會 x 的指示，例如輸入想要一個紅眼睛的二次元人物，但 G 可能胡亂生成一張圖片，因為它的目標只需要在 D 上取得高分，不管生成哪一張圖片 G 都無所謂。

![image](https://hackmd.io/_uploads/rk9YzPaHA.png =95%x)

因此，給 D 的輸入除了有圖片還需要有 x，也就是說圖片不能隨便生成，必須要滿足 x 的指令，生成對應的圖片才能獲取高分，在 D 的訓練過程中必須先看過成對的資料包含高分以及低分，才能學會辨別 G 生成的圖片是否足夠接近真實的圖片以及是否滿足 x 的條件。

![image](https://hackmd.io/_uploads/Hk4cfwpBC.png)

#### 2. 圖片生成圖片
此時，輸入為 x（一張圖片）以及 z（簡單分布），丟入 G 後輸出另外一張圖片，例如輸入設計圖輸出建築物照片、輸入白天景色輸出黑夜景色、輸入黑白照片輸出彩色照片等，圖片生成圖片的方法稱為 Image Translation 或者是 pix2pix。

若單純使用 Supervised learning 訓練 G，會產生一個模糊影像，此概念跟一開始的例子十分相像，主角走到了十字路口，因為有多種可能的輸出，導致產生模糊的影像；若只用 GAN 的架構，由於創造力過於豐富，導致輸出圖片（y）出現輸入圖片（x）沒有的東西，因此最好的方式就是同時使用 Supervised 的技巧以及 GAN 的架構，輸出一個複雜的分布，並產生合理的圖片。

#### 3. 聲音生成圖片
#### 4. 圖片生成會說話的頭像(Talking Head Generation)

### Learning from unpaired data 使用到 Cycle GAN 技術
#### 1. 圖片風格轉換
在這裡，輸入為一張真人圖片，丟入 G 後輸出一張二次元圖片，此過程叫做圖片風格轉換，而 D 會辨別 G 產生的二次元圖片與真實的二次元圖片間的差異，並給予一個 scalar。

但這會發生一個問題，就是 G 會忽略輸入的真人圖片，胡亂生成一張二次元圖片，這個問題跟文字生成圖片的任務相同，G 只需要在 D 上獲取高分，不理會是否有滿足輸入（x）的要求，同時也沒有成對的資料給機器學習，因此接下來的 Cycle GAN 便能用來解決 Unsupervised 的問題。

![image](https://hackmd.io/_uploads/H1UGv6CSC.png)

Cycle GAN 的概念是，輸入一張真人圖片至 G 中得到一張二次元圖片，再將二次元圖片還原成真人圖片，觀察與一開始輸入的真人圖片向量是否接近，若足夠接近，代表機器有參考輸入的真人圖片，並根據其特徵輸出一張二次元圖片，而不是隨意生成，接著將二次元圖片丟入 D~y~ 輸出一個 scalar。

同樣的方式，能夠將二次元圖片輸入至 G 中得到一張真人圖片，再將真人圖片還原成二次元圖片，觀察與一開始輸入的二次元圖片向量是否接近，接著將真人圖片丟入 D~x~ 輸出一個 scalar。

:::info
就算使用 Cycle GAN 仍有非常小的機率，G 會學到奇怪的轉換，也導致真人圖片與二次元圖片根本不相匹配。
:::

![image](https://hackmd.io/_uploads/SyiE9TCrA.png)

#### 2. 文字風格轉換
在文字風格轉換的任務上，輸入是一串文字丟入 G 後產生另一串文字，這就是 Seq2Seq 的模型，雖然是可行的，但目前仍有許多困難待克服，例如前面有提到 GAN 使用在文字生成的任務上，最大的挑戰便是無法微分。

#### 3. Unsupervised abstractive summarization（文章轉摘要）
#### 4. Unsupervised translation（語言翻譯）
#### 5. Unsupervised ASR（語音轉文字）

## 總結，生成式對抗網路(Generative Adversarial Network, GAN)
在文章中，介紹了 Generator 以及 Discriminator，並了解兩者間的對抗關係，同樣也介紹了如何訓練這兩個 neural network 以及提供一些訓練小技巧-Wasserstein distance，甚至能夠從 quality 和 diversity 評估 GAN 的好壞，最後是 GAN 各式各樣的應用情境。

---
:::info 
以上就是這篇文章「生成式對抗網路 (Generative Adversarial Network, GAN)」的所有內容，第一次看的人會花比較多時間消化吸收，這是很正常的事情，若有任何問題，歡迎在下方與我聯繫、討論，接下來也會繼續分享相關文章，敬請期待。