---
# System prepended metadata

title: '[GAN] Image to Image：Supervise CGAN vs. Unsupervised CGAN'
tags: [GAN]

---

# [GAN] Image to Image：Supervise CGAN vs. Unsupervised CGAN
###### tags: `GAN`


# Supervise CGAN
==D的輸入為paired data==
## Text to Image
> 輸入條件$c$：**文字**
> 回顧上篇：https://hackmd.io/J2aJeum6SIif3MJPbxTfNA?both
![](https://i.imgur.com/nJTCVGK.png　=500x)


---

## Image to Image
> 輸入條件$c$：**圖像**
> 以下為三種方法之輸出結果比較
> * ==L1 loss(close)==：恢復圖像的低頻部分
>重建的圖像很模糊，L1和L2並不能很好的恢復圖像的高頻部分(邊緣)，但能較好地恢復圖像的低頻部分(色塊)
> * GAN loss(之鑑別器)：恢復圖像的高頻部分
![](https://i.imgur.com/WgtXDwL.png)

### 1. 傳統 Supervise Learning → ==方法：L1 loss(close)==
需要準備幾萬張的 paired data ![](https://i.imgur.com/f2ncGo4.png =100x)
(1)幾何圖形：先取正常照片來生成 (2)真實圖片 


* 原理： 最小化利用 **NN 輸出的假圖$x$** 與 **真實圖片** 的 loss
![](https://i.imgur.com/IoKSSoe.png)
:::warning
輸入：幾何圖形$c$
輸出：同一個幾何圖會對應到許多答案，採各種可能的**平均值** (假圖$x$通常很模糊)

---------
:question: 為什麼 L1, L2 loss 的圖很模糊
**L1損失** = 平均絕對誤差(Mean Absolute Error，MAE)
* 各測量值其**絕對誤差**的**平均值**（取絕對值後再求平均值）
* $MAE = \frac{1}{n}\sum_{i=1}^{n}{| 預測值 - 實際值 |} = \frac{1}{n}\sum_{i=1}^{n}{|絕對誤差|}$

**L2損失** = 平均平方誤差：均方差(Mean Squared Error，MSE)
* 各測量值其**平方誤差**的**平均值**
  經過平方，與真實值**偏離較多的預測值**會比偏離較少的預測值受到**更為嚴重的懲罰**
* $MSE = \frac{1}{n}\sum_{i=1}^{n}{( 預測值 - 實際值 )^2 = \frac{1}{n}\sum_{i=1}^{n}{(絕對誤差)^2}}$
:::

###  2. CGAN Supervise Learning →  ==方法：GAN==

* 原理：利用 CGAN 來做會得到更清晰的圖片，但仍然可能會有一些奇怪的輸出，例如圖中左上角類似煙囪的奇怪圖形。
![](https://i.imgur.com/0heZLp8.png)
:::warning
**G：生成器**
* 輸入：==幾何圖形$c$==與==Prior distribution-z==，經過Generator之後得到照片x
    * 幾何圖形$c$
    * $z$（Noise 噪聲向量－from常態分佈值）
* 輸出：$x=G(c,z)$

**D：鑑別器**
* 輸入：==幾何圖形$c$==,==假圖$x$== 的對應關係，所以是supervised
* 輸出：score 
:::
###  3. CGAN Supervise Learning →  ==方法：L1 loss(close)+GAN==

* 原理：G的訓練再加入close概念(與原始照片愈接近愈好)，生成的照片可更近現實
最小化 ==假圖$x$== 與 **真實圖片** 的 loss。
![](https://i.imgur.com/GOYw1NB.png)

## pix2pix 
* Pix2pix為CGAN Supervise Learning之延伸
* 差別：輸入與CGAN一樣是pair data，但**不用噪音z**
    * 原因：此篇論文發現，加入噪聲z沒有太大作用（z被忽視），產生的隨機性很小，因此論文中也有提到在GAN要產生高隨機的Output是現今很重要的問題。
    * 在pix2pix，噪音z的輸入是通過在G中加入dropout策略來實現的 
    * 目的：增加隨機性，以便生成的圖像更具多樣性。
    > **Dropout**
    > * 問題：Overfit的時候才會去使用
    >   1. 情況：若模型的參數太多，訓練樣本又太少，訓練出來的模型易產生之問題
    >   2. 原因：training data 表現好，testing data 上表現不好
    >   注意：當training data 結果就不好的時候用 dropout 往往會越訓練越差
    > * 解法：每次batch都依據設定的drop rate，在層跟層之間丟棄一定比例的神經元（一部分的輸出過濾成0），因此權重(W)不更新，除了造成多個結果，也減少Overfit，使每一次都好像在訓練不同的神經網路，不會太依賴某些局部的特徵
    > * [註] 因此dropout也可以被用作一種添加 noise 的方法 (產生高隨機性)
    > 
::: info
Without z, the net could still learn a mapping from x to y, but would produce deterministic outputs, and therefore fail to match any distribution other than a delta function. Past conditional GANs have acknowledged this and provided Gaussian noise z as an input to the generator, in addition to x (e.g., [55]). 

In initial experiments, we did not find this strategy effective – the generator simply learned to ignore the noise – which is consistent with Mathieu et al. [40]. Instead, for our final models, we provide noise only in the form of dropout, applied on several layers of our generator at both training and test time. Despite the dropout noise, we observe only minor stochasticity in the output of our nets. 
我們以 dropout 的形式來給模型提供z，並且 dropout 在訓練和測試時都需要用到（如果在訓練時使用了dropout，確保在測試時也要使用dropout），不過作者依然發現dropout策略只會產生為小隨機性
[註] dropout 是應用在 u-net 模型中 generator 中 decoder 部分的前三層

Designing conditional GANs that produce highly stochastic output, and thereby capture the full entropy of the conditional distributions they model, is an important question left open by the present work.
:::

* D的分數由2組paired data而來
    * Real pair：(==條件：幾何圖$x$==, ==真圖 $y$== )
    * Fake pair：(==條件：幾何圖$x$==, ==生成圖 $G(x, z)$== )
* 公式：
    1. $\mathcal{L}_{cGAN}\left(G, D\right) =\mathbb{E}_{x,y}\left[\log D\left(x, y\right)\right]+
    \mathbb{E}_{x,z}\left[log(1 − D\left(x, G\left(x, z\right)\right)\right]$
        * 事先準備：
            * $x$= 輸入的 **條件$c$=幾何圖形** (事先取真實照片來生成)　
            * $y$= 真圖 (從database抓出的)　   →　$(x,y)=1$
        * 過程中生成：
            * $G(x,z)$ = 假圖　　　　　　　   →　$D(x,𝑥G(x,z))=1$
    2. $\mathcal{L}_{L1}\left(G\right) = \mathbb{E}_{x,y,z}\left[||y - G\left(x, z\right)||_{1}\right]$
    希望 ($G(x,z)$=假圖,$y$=真圖) 之間的差異減少
    3. $G^{*} = \arg\min_{G}\max_{D}\mathcal{L}_{cGAN}\left(G, D\right) + \lambda\mathcal{L}_{L1}\left(G\right)$



![](https://i.imgur.com/Ib0xqtD.png)

![](https://i.imgur.com/NC77CCQ.png)
 

---

# Unsupervise CGAN


| pix2pix | CycleGAN | 
| -------- | -------- |
| Supervise CGAN：有正確結果做對應<br/> ex. 文字train有對應的火車圖<br/>$(c1$：文字/幾何圖$x$：label=真圖$)$ | Unsupervise CGAN：沒有正確結果     | 
| ==D的輸入為paired data==，必須同時存在source與target    | ==D的輸入為unpaired data==，無法同時取得在source與target     | 
|單向運作(source→target)|雙向循環(source ⇄ target)|
|U-Net|ResNet|


![](https://i.imgur.com/UUI7JUL.jpg)

**在Supervise CGAN中**：可知道input對應的output該長什麼樣子(有label對應)
> Text to Image：有真實火車圖$x$來讓我知道，當我輸入文字$c$=train時，輸出要長得像$x$
> Image to Image：有真實房子圖$y$，當我輸入幾何圖$x$時，輸出要長得像$y$

**在Unsupervise CGAN中**：無法知道input對應的output該長什麼樣子(沒label對應)
> * 無source, 有traget
> 我們可以取得莫內的睡蓮畫(有traget)，但無法取得其畫原本真實的水塘照片(無source)
> → 我沒有 paried data (沒有input真實水塘照, 有output睡蓮畫)
> * 有source, 無traget
> 有source：在做風格轉換時，我們可以蒐集一堆**風景照&梵谷畫作**
> 無traget：但卻沒辦法取得我這張風景照要轉成梵谷畫風的 **生成圖(label)** 做對應
> → 我沒有 paried data (有input我的照片, 沒有output畫風版我的照片)
>* [註] 有些風格轉換有paired data, ex. Google Map 地圖轉衛星, 黑白彩色照

## CycleGAN
* **真實圖片**
$Domain X$：真實照片
$Domain Y$：梵谷畫的畫作
* **生成的假圖**：確保轉換後的圖像不會生成出與 input 完全無關的圖像
$G_{Y\rightarrow X}$：把$Domain Y$影像轉到$Domain X$
$G_{X\rightarrow Y}$：把$Domain X$影像轉到$Domain Y$
* 鑑別器
$D_Y$, $D_ｘ$：確保生成出來的圖像會是我們想要的目標 ( 風格 )。
### **Step1**：G生成的圖像，正常應該不會跟 input 相差太多(成果不錯)
![](https://i.imgur.com/niLoVwz.png =280x)

![](https://i.imgur.com/V43lwJA.png =600x)
* $D_Y$
用$Domain Y$訓練$D_Y$，為屬於$Domain Y$的圖片打分數
用來鑑別真圖：$Domain Y$ 及假圖：$G_{X\rightarrow Y}$
* $G_{X\rightarrow Y}$
用$Domain X$訓練$G_{X\rightarrow Y}$，學習騙過$D_Y$ (讓$D_Y$以為假圖是$Domain Y$的圖)

**[問題]**：G很快就發現D只看G的output，只在意畫風忽略input的內容
只產生單一梵谷風格圖片而無視輸入，不再轉換其他照片為梵谷風格圖片了=>再加$G_{Y\rightarrow X}$

### **Step2**： Cycle Consistency  避免G生成出與輸入照片無關
![](https://i.imgur.com/EAweQpj.png =280x)
![](https://i.imgur.com/WOwaOQW.png)
* $G_{Y\rightarrow X}$
將第一個G的輸出$Y$($G_{X\rightarrow Y}$)還原為原本的照片$X$($G_{Y\rightarrow X}$)
即將梵谷畫再轉回真實圖片，而我們希望輸入的照片與最終轉回的照片愈接近愈好
原理：==**最小化Loss**(input圖,還原的圖像)，以限制中間的生成圖像要跟 input 相似==
* $D_X$
需要一個Descriminator判斷生成的照片像不像真實照片


---


## 損失函數
* Loss(5) = Adversarial Loss(Gx2+Dx2) + Cycle Consistency Loss(cycx1)

### 1. Adversarial 
- [x] 理論：G和D的loss函數和GAN是一樣的
    * **1-1**. 生成器：$G_{X\rightarrow Y}$和其鑑別器：$D_{Y}$，定義loss：
        * $$\begin{aligned} \mathcal{L}_{\mathrm{GAN}}\left(G, D_{Y}, X, Y\right) &=\mathbb{E}_{y \sim p_{\text {data }}(y)}\left[\log D_{Y}(y)\right] +\mathbb{E}_{x \sim p_{\text {data }}(x)}\left[\log \left(1-D_{Y}(G(x))\right]\right. \end{aligned} $$
        * 優化效果公式 ：![](https://i.imgur.com/R3l31xe.png =250x)

    * **1-2**. 生成器：$G_{Y\rightarrow X}$和其鑑別器：$D_ｘ$，定義loss：($F$跟$G$都是生成器)
    $$\begin{aligned} \mathcal{L}_{\mathrm{GAN}}\left(F, D_{X}, Y, X\right) &=\mathbb{E}_{x \sim p_{\text {data }}(x)}\left[\log D_{X}(x)\right] +\mathbb{E}_{y \sim p_{\text {data }}(y)}\left[\log \left(1-D_{x}(F(y))\right]\right. \end{aligned} $$

- [x] Code
* D(鑑別器)的loss：
    loss_1是對於真圖的判定，越接近1越好，loss_2是對於假圖的判定，越接近0越好，loss是兩個loss相加
    ```python=1
    D_A_loss_1 = tf.reduce_mean(tf.squared_difference(dec_A,1))
    D_B_loss_1 = tf.reduce_mean(tf.squared_difference(dec_B,1))

    D_A_loss_2 = tf.reduce_mean(tf.square(dec_gen_A))
    D_B_loss_2 = tf.reduce_mean(tf.square(dec_gen_B))


    D_A_loss = (D_A_loss_1 + D_A_loss_2)/2
    D_B_loss = (D_B_loss_1 + D_B_loss_2)/2
    ```
* G(生成器)的loss:
    ```ython=1
    g_loss_B_1 = tf.reduce_mean(tf.squared_difference(dec_gen_A,1))
    g_loss_A_1 = tf.reduce_mean(tf.squared_difference(dec_gen_A,1))
    ```
### 2. Cycle Consistency Loss

- [x] 重構誤差(Reconstructed loss)：![](https://i.imgur.com/pwWY7Gy.png =150x)
![](https://i.imgur.com/4AoJdgC.png =400x)
    * 2-1. ($G_{X\rightarrow Y}$ + $G_{Y\rightarrow X}$) vs. ($x$)：真圖x經由G生成假圖y，再經由F**還原回圖x ⇆ 真圖x**
    * 2-2. ($G_{Y\rightarrow X}$ + $G_{X\rightarrow Y}$) vs. ($y$)：真圖y經由F生成假圖x，再經由G**還原回圖y ⇆ 真圖x**
![](https://i.imgur.com/GxOaynY.png =600x)

- [x] Code
保證loss盡量小：**原圖**&**還原圖**
注意：10*cyc_loss是賦予Cycle Consistency loss更大的權值，作者沒討論為何設10
    ```python=1
    cyc_loss = tf.reduce_mean(tf.abs(input_A-cyc_A)) + tf.reduce_mean(tf.abs(input_B-cyc_B))
    g_loss_A = g_loss_A_1 + 10*cyc_loss
    g_loss_B = g_loss_B_1 + 10*cyc_loss
    ```
### 3. 最終loss如下
![](https://i.imgur.com/WNaDowz.png =350x)
優化目標也仿照原始GAN：![](https://i.imgur.com/YRgD59O.png =300x)

### Metrics 指標
![](https://i.imgur.com/5u2hwTk.png =450x)
> 平均值受異常值影響較大，而中位數則相對穩定

| MAE(L1) | MSE(L2) | 
| -------- | -------- | 
|  * 概念：中位數（最小化MAE） <br/>* 適用圖片：產生較為尖銳的輸出 <br/>  * 對於異常值較穩定，讓大多數的資料都被預測正確| * 概念：平均值（最小化MSE） <br/>* 適用數值：輸出的東西較平滑(使圖像模糊)<br/>  * 對於異常值較敏感| 
MSE 對誤差取了平方（令 e=真實值-預測值）
* 因此若 e>1，則 MSE 會進一步增大誤差
* 如果資料中存在異常點：MSE > MAE（e 值就會很大， e²更大）
* 優點：會賦予異常點更大的權重
* 缺點：降低模型的整體性能
　 犧牲了其他樣本的誤差為代價，朝著減小異常點誤差的方向更新

[1] [機器學習大神最常用的 5 個回歸損失函數，你知道幾個？](https://buzzorange.com/techorange/2018/06/22/computer-learning-5-tips/)
[2] [均值的損失函數_為什麼MSE損失的收斂目標是均值，而MAE的是中位數？](https://blog.csdn.net/weixin_34481252/article/details/112669717)

![](https://i.imgur.com/Z7ulraF.png)
#### Generator 的 Metric 
* Validity 有效性 - ==數值(MSE-L2)==
`g_BA fool d_A, g_AB fool d_B`
將橘子轉成蘋果，是否可以騙過蘋果D
* Reconstruction 重構性 - ==影像(MAE-L1)==
`g_BA + g_AB`：經過雙向G，是否可復原影像B
將橘子轉成蘋果，在將蘋果轉成橘子，是否可以復原橘子的影像
* Identity 一致性 – ==影像(MAE-L1)==
A圖放入g_BA, A圖是否可保持不變
ex. 將橘子放入橘子G，看橘子圖是否可保持不變，若改變（例如背景的天空由藍轉黑），我們就可以知道這個模型還有問題

**Dicrimminator 的 Metric**
Cycle Consistency Loss：==數值(MSE-L2)==









## 參考資料
:::success

### CGAN：Image to Image原理
1. 李宏毅_ATDL_Lecture_15
https://hackmd.io/@shaoeChen/HJ3JycWeB
2. 生成對抗網絡GAN系列（五）：pix2pix&CGAN 差別
https://cloud.tencent.com/developer/article/1433790

### Cycle GAN
1. 對抗生成網路 GAN介紹 李宏毅深度學習：原理
https://hackmd.io/@abliu/H1kCeMHmr?type=view#GAN%E7%9A%84%E5%88%86%E9%A1%9E
3. 李宏毅_ATDL_Lecture_15：原理
https://hackmd.io/@shaoeChen/HJ3JycWeB
3. Generative Adversarial Network (3) --- Unsupervised Conditional GAN：原理
https://allen108108.github.io/blog/2019/10/29/Generative%20Adversarial%20Network%20(3)%20%E2%80%94%20Unsupervised%20Conditional%20GAN/
4. CycleGAN原理及實驗（TensorFlow）：原理
https://www.jianshu.com/p/64bf39804c80
5. 機器學習與深度學習系列連載： 第四部分對抗網絡GAN (四) 對抗網絡Cycle GAN：原理
https://blog.csdn.net/dukuku5038/article/details/85059899

### Loss
1. Cycle GAN 論文解析
https://blog.csdn.net/stezio/article/details/83627607?biz_id=102&utm_term=CycleGAN&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-83627607&spm=1018.2118.3001.4187
2. CycleGAN原理以及代碼全解析
https://zhuanlan.zhihu.com/p/37198143
3. CycleGAN原理及實驗（TensorFlow）
https://www.jianshu.com/p/64bf39804c80
4. CycleGAN論文的閱讀與翻譯，無監督風格遷移
https://zhuanlan.zhihu.com/p/45394148
:::

