# [GAN] CycleGAN之D與G架構(U-Net & Resnet)
###### tags: `GAN`
# Discriminator
## Patch GAN / Pixel GAN
CycleGAN繼承此架構
| 圖片 | 說明 |
| -------- | -------- |
|  | **一般GAN**</br>圖片尺寸大時,**整張圖片**丟進 D 做檢查很易導致訓練時間過長、Overfitting 、 performance 不好等狀況<br> * 最後一層為 Dense layer,輸出只有一個值 [0, 1],用該值判斷"這整張圖"是否真假 |
|   | **Patch GAN** </br>採取整張 **圖片一小部分 (patch)** 做檢查,而output的tensor包含多個Patch的機率,再取平均得到分類結果</br> 損失函數:</br>據風格判斷(因只取圖片的局部內容,無法用內容判斷loss)  |
---
為了能更好得對圖像的局部風格做判斷,使用 PatchGAN 做為 D
* D 層設計:PatchGAN 由 4 層 conv 堆疊而成,輸出層也是 conv,因此輸出是 8x8x1 的 patch(feature map),而非單一數值
* PatchGAN 將整張圖片拆成多個 patch 丟進 D 做檢查,去預測每個 patch 真假機率
* output 的 feature map 包含多個 Patch 的機率,對圖片中每一個 patch 分別判斷是否是 real,考慮到圖像的不同部分,再取平均得到分類結果
* feature map 中每個元素 Xij 代表每個 patch ij 為真樣本的機率,8x8x1 的 patch 則會有 8x8 個 Patch 的機率
* 我們在整個圖片上執行 PatchGAN,D 輸出的 feature map 大小 8x8x1,這 8x8x1 的 feature map 代表原始輸入影像中的某一個 70x70 的區域

# Generator
## 評估G
1. Validity 有效性
> g_BA fool d_A, g_AB fool d_B
2. Reconstruction 重構性
> g_BA + g_AB:經過雙向G,是否可復原影像B
4. Identity 一致性
> A圖放入g_BA, A圖是否可保持不變
## U-Net

以下過程重複4次
Convolution 運算後再加上激活函數(activation function),進行非線性轉換,之後得到的圖片會稱為特徵圖(feature map)
1. 3x3 Conv+Relu:兩次 (3x3是一個tensor) **特徵提取**
2. 2x2 Maxpooling2D **降低維度**
3. up-convolution
### 過程

### 為何選用U-Net
輸入和輸出圖像的
* 表面(surface appearance)不同
* 潛在的結構(underlying structure)相似
對於image translation的任務來說,輸入和輸出共享一些訊息(spatial information:黑白彩色照的結構邊緣不變),因此使用Unet這種跳層連接(skip connection)的方法
### Downsample
:::warning
**Why "Downsample"**
* 淺層結構:可以抓取圖像的一些簡單的特徵,比如邊界,顏色
* 深層結構:經過的卷積操作多了,能抓取到圖像的抽象特徵
作用:進行空間壓縮
向下過程逐漸理解:上下文(what:contextual understanding), ex: 影像風格
向下過程逐漸消失:圖像位置(where:spatial information ), ex: 影像內容
:::
* Channel 數量x2:
* Feature map 大小減半x(1/2)x(1/2)
* conv(stride=1) + **Max-pooling2D(降低維度2x2)**
耗時,無需學習參數,只保留局部區域最“重要的” feature
* Conv(stride=2):速度更快,但是某些位置的feature 就永遠丟掉
### Upsample
* Channel 數量/2:
* Feature map 大小加倍(x2x2)
* **Up-conv2D** + conv(stride=1) **(增加維度2x2)**
直接複製行列的值來擴充,可看作是 Pooling 反向操作
* Conv2DTranspose:與 CNN 相同具有參數可學習,可視為 CNN 卷積的反向操作
### Concatenate
* 建立skip connections:
* 將上游與下游中,尺寸相同的層彼此拼接,因此channel數量x2倍
32x32x64→32x32x128
* 作用:把在Downsample過程中遺失的spatial information送回各層
### InstanceNormalization

N(樣本數=6張圖片), C(channel=6個feature map)
* InstanceNormalization
* ex. 單張圖片的單個channel單獨進行Noramlization。
* 根據每個輸入的Instance標準化
* 適用:想提取的是每張圖片的==特色、風格==
* 優點:加速模型收斂
**Why InstanceNormalization ?**
Style Transfer中,每個樣本的每個pixel的訊息都非常重要,圖片生成的結果主賴於圖像樣本(Instance)
對整個Batch做Normalization不適合圖像Style Transfer,因為會造成每個樣本獨特細節的丟失
* Batch Normalization
* ex. 對所有圖片(6張圖片中的每一張圖片)的同一個channel一起進行Normalization
* 根據整個 Batch 標準化:
* (mu, sigma) :需計算Batch的 mean & variance
* (gamma, beta) :要被 gradient 訓練的權重值
* (running_mean, running_var) 訓練時,由觀察 batch data 得到的平均和標準差。
```python=1
# 訓練時:輸入資料會先減去 mu 再除上 sigma ,normalize 到一個範圍 (-1~1 附近)
x = (x - mu) / sigma
# 接著再乘上 gamma 並加上 beta 後輸出。
out = gamma * x + beta
# 此時會把 mu 和 sigma 的值更新到 running_mean 和 running_var。
running_mean = momentum * running_mean + (1 - momentum) * sample_mean
running_var = momentum * running_var + (1 - momentum) * sample_var
# 照上述公式可以知道 batch size 越大,得到的 running_mean 和 running_var 越有說服力。
# 因為進來的資料不是以 batch 為單位,一次可能只推斷一筆資料,所以你沒有辦法用 mu 和 sigma 來執行 normalization,這時就會拿上述訓練時算出來的 running_mean 和 running_var 來用,就是說running_mean 和 running_var 是根據訓練時的經驗法則得出的結果。
x = (x - running_mean) / running_var
out = gamma * x + beta
```
* 適用:圖片分類
* 缺點:考慮了一個Batch中圖片的所有內容,造成丟失獨特細節
---
## ResNet (Residual )
### 深層網絡→梯度消失

* 過往因為深層網路訓練不起來,易造成 Gradient Vanishing(梯度消失)
* 出現情況:梯度下降法、反向傳播
* 修正:往回走
樓梯太長時,一路修正路徑回起點(梯度消失),每一次的修正都是基於偏微分,但當連續進行偏微分時,很容易讓==變化率歸零==。也就是無法繼續修正。
1. 近輸入層的hidden layer1的權值更新會變慢(學習效率很慢),導致靠近==權值幾乎不變==,近於初始值
2. 導致hidden layer 1 相當於mapping層,只有後幾層的隱藏層網絡在學習
3. 造成:
近 input 層的Gradient 值十分小,近 output 層的 Gradient會很大
當設定相同的 learning rate 時,近 input layer 的參數 updata 會很慢,近 output layer 的參數 update 會很快。
當前幾層都還沒有更動參數的時候(還是隨機的時候),隨後幾層的參數就已經收斂了。
* 解法:ResNet之shortcut
* 跳過幾個台階不需要走,搭建溜滑梯
* F(X)=Y, X+Y=Y'
* 將後方輸值入(X)往前送,與前層的輸出(Y)相加在送入下一層。
* 相加時,確保兩者的Shape、Channel相同!

### Degradation(退化)

* 深度增加時,準確度出現飽和,甚至下降
ex. :20層的神經網路表現得會比與56層還好
* X:非Overtitting所導致
`訓練資料:損失函數較小,預測準確率較高;但在測試資料:損失函數比較大,預測準確率較低。`
* O:因為56層神經網路的訓練損失(training error)一樣很高(比20層還高)
* 注意:如何辨別是否為 Overfitting
> 理論上,56層的 Network 擁有(或超過)跟20層相同模型 performance ,可能是 **模型參數的調校問題**、**Overfitting** 導致未能有此結果。
> 1. 在testing data 上看到 20-layer 的 error 較小,就說是overfitting 是錯的。首先要先檢查在 training data 上的結果。
> 2. training data 上 56-layer 的 performance 本來就比 20-layer 變現差很多,在做neural network時,有很多的問題使 train 不好,比如 local mininmize 等等。
56-layer 可能卡在一個 local minimize 上,得到一個不好的結果,這樣看來,56-layer 並不是 overfitting,只是沒有 train 的好。
* 解法:Identity mapping(最差情況)
* 什麼都沒學到,Y=0,但至少有shorcut傳來的X值
* 確保一致性(Identity):沒學到新的特徵,也不會讓模型退化
---
## Neural Style Transfer
作法: 透過 Gradient descent ,將 Loss Function最小化
> GAN&VAE:透過 Backpropagation ,將 Loss Function最小化
* Content loss(內容損失):same content
* 希望新的圖像 包含基礎圖像的**基本內容**;
* Style loss(風格損失):same general style
* 希望新圖像 包含風格圖像的**基本風格**信息;
* Total variance loss(總方差損失):smooth
* 希望生成的圖像 看起來**平滑**而不是像素顆粒。
### Content loss 內容損失
* 概念
用已經訓練好的 Deep neural network (VGG19) 辨識 content,即可取得輸入影像的 高階特徵.
> 希望抓取圖片中的 高階特徵(higher-level features),而非individual pixels值.
> ex. buildings, sky, or river
* 公式:使用指標 MSE
$\mathcal{L}_{content}(\vec{p}, \vec{x}, l)=\frac{1}{2}\sum_{i,j} (F^l_{ij}-P^l_{ij})^2$
原圖$p$(base image)與生成圖$x$(combined image)的特徵差距,似『預測值與實際值的差距』
* P :原圖(base image)的特徵向量
* F :生成圖(combined image)的特徵向量
* $F^l_{ij}$:第$l$層的feature map,第$i$個filter產生的feature map的第$j$個元素
* Code
```python=1
def content_loss(content, gen):
return K.sum(K.square(gen - content))
content_loss = content_weight * content_loss(base_image_features, combination_features)
```
#### 風格特徵計算 Gram
* 公式:$G^l_{ij}=\sum_k F^l_{ik}F^l_{jk}$
* 理論
* 單層中,有多個feature map,觀察feature map兩兩之間的相關性
> feature1(尖尖)和feature2(綠色)總是一起出現的,代表它們的相關性較高
* 在$l$層,$[i,j,k]$=第$i$個特徵($feature_i$)和第$j$個特徵($feature_j$)在 ==位置$k$== 的相關性
* 點對點乘積之值:代表一個特徵的強度

* 舉例
 
* 概念:CNN某層中,不同的filter其點對點乘積之結果
* 假設:照片大小64x64, 有128個filter, 不同filter抓取不同特徵
* 若兩張filter差異很大,做點對點乘積之結果會很小
* 作法:把3維(64x64x128) →壓成→ 2維(64x64)x(128)
* $A$=(64x64)x(128)
* $A$與$A^t$相乘:相同位置(某層)上,filter之間的相似度,也就是風格相似度
* 風格(Style reference)的filter與生成圖(combined image)的filter,計算兩者filter相似度

* Code
```python=1
def gram_matrix(x):
features = K.batch_flatten(K.permute_dimensions(x, (2, 0, 1)))
gram = K.dot(features, K.transpose(features))
return gram
```
### Style loss(風格損失)
* 概念
* 風格圖 與生成圖 的特徵差距,反應畫風的差距
* 風格特徵loss:Gram(風格圖)-Gram(生成圖)
* 公式:
(單層的style loss)
(全部層的style loss合起來加權的)
風格圖$S$(Style reference)與 生成圖$G$(Combined image) 的特徵差距
* $S$:風格圖(Style reference),通過Gram矩陣,其風格的特徵向量
* $G$:生成圖(Combined image),通過Gram矩陣,其風格的的特徵向量
* $N_1$:Channel數量
* $M_1$:影像大小(高x寬)
* $l$:第l層
* Code
```python=1
def style_loss(style, combination):
S = gram_matrix(style)
C = gram_matrix(combination)
channels = 3
size = img_nrows * img_ncols
return K.sum(K.square(S - C)) / (4.0 * (channels ** 2) * (size ** 2))
```
### Total Variance Loss
總損失函數 = 原圖的損失函數 + 風格圖的損失函數
* 公式:
$\mathcal{L}_{total}=\alpha \mathcal{L}_{content} + \beta \mathcal{L}_{style}$
總和(a=影像下移平方誤差&b=右移的平方誤差)x權重
```python=1
def total_variation_loss(x):
a = backend.square(x[:, :height-1, :width-1, :] - x[:, 1:, :width-1, :])
b = backend.square(x[:, :height-1, :width-1, :] - x[:, :height-1, 1:, :])
return backend.sum(backend.pow(a + b, 1.25))
loss += total_variation_weight * total_variation_loss(combination_image)
```
## 反向傳播

$\dfrac{\partial C}{\partial w}=\dfrac{\partial z}{\partial w}\dfrac{\partial C}{\partial z}$
* $\dfrac{\partial z}{\partial w}:$ forward pass
* $\dfrac{\partial C}{\partial z}:$backward pass
### Forward

$\partial z/\partial w_1=x_1$
$\partial z/\partial w_2=x_2$
forward pass的規律:input是什麼,微分之後就是什麼,即上層的output為下層的
### Backward

$\dfrac{\partial C}{\partial z}=\dfrac{\partial a}{\partial z}\dfrac{\partial C}{\partial a}$
$\dfrac{\partial C}{\partial a}=\dfrac{\partial z'}{\partial a}\dfrac{\partial C}{\partial z'}+\dfrac{\partial z''}{\partial a}\dfrac{\partial C}{\partial z''}$
$a=\sigma(z)$:z通過activation function之後得到output,a再做為其它neuron的輸入計算得到下一層的z…最後才得到C。

總結來說,反向傳播就是將forward pass的偏微分跟backward pass的偏微分相乘即為解。
## 參考資料
:::success
### PatchGAN
1. [對PatchGAN的感知域(receptive_field)理解](https://www.cnblogs.com/ChenKe-cheng/p/11207998.html)
### U-Net
1. [深度學習]Semantic Segmentation語義分割之UNet(2)
https://www.itread01.com/content/1543926966.html
### ResNet
1. (文科友善)深度學習與梯度下降
https://medium.com/@bc165870081/%E6%96%87%E7%A7%91%E5%8F%8B%E5%96%84-%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92%E8%88%87%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D-c6826a79d45f
2. Residual Leaning:認識ResNet與他的冠名後繼者ResNeXt、ResNeSt
https://medium.com/%E8%BB%9F%E9%AB%94%E4%B9%8B%E5%BF%83/deep-learning-residual-leaning-%E8%AA%8D%E8%AD%98resnet%E8%88%87%E4%BB%96%E7%9A%84%E5%86%A0%E5%90%8D%E5%BE%8C%E7%B9%BC%E8%80%85resnext-resnest-6bedf9389ce
3. (深度學習)ResNet之殘差學習
https://medium.com/@hupinwei/%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-resnet%E4%B9%8B%E6%AE%98%E5%B7%AE%E5%AD%B8%E7%BF%92-f3ac36701b2f
4. 你必須要知道CNN模型:ResNet
https://zhuanlan.zhihu.com/p/31852747
### InstanceNormalization
1. 模型優化之Instance Normalization
https://zhuanlan.zhihu.com/p/56542480
2. Batch normalization和Instance normalization的對比?
https://www.zhihu.com/question/68730628
### Style Transfer
1. 談談圖像的Style Transfer(一)
https://blog.csdn.net/Hungryof/article/details/53981959
2. 圖像風格轉換Style Transfer
https://zhuanlan.zhihu.com/p/49433020
3. 【技術博客】風格遷移——藝術風格化的神經網絡算法
https://zhuanlan.zhihu.com/p/73480707
4. 风格迁移(Style Transfer)论文阅读整理(一)
https://zhuanlan.zhihu.com/p/37638591
5. Neural Style Transfer
http://fancyerii.github.io/books/neural-style-transfer/#%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D
6. Fast Style Transfer(快速風格轉移)
http://closure11.com/fast-style-transfer%E5%BF%AB%E9%80%9F%E9%A3%8E%E6%A0%BC%E8%BD%AC%E7%A7%BB/
7. Day 11:風格轉換(Style Transfer) -- 人人都可以是畢卡索
https://ithelp.ithome.com.tw/articles/10192738
8. [筆記]Tensorflow-Lesson8_影像風格轉換
https://ithelp.ithome.com.tw/articles/10210883
### CNN
1. 卷積神經網路(Convolutional neural network, CNN) — CNN運算流程
https://medium.com/@chih.sheng.huang821/%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF-convolutional-neural-network-cnn-cnn%E9%81%8B%E7%AE%97%E6%B5%81%E7%A8%8B-ecaec240a631
### 論文
1. Image-to-Image Translation with Conditional Adversarial Networks
https://arxiv.org/pdf/1611.07004.pdf
3. 2019 年臺灣國際科學展覽會優勝作品專輯
https://twsf.ntsec.gov.tw/activity/race-2/2019/pdf/TISF2019-190016.pdf
## Book
書籍《Generative-Deep-Learning》
https://zhuanlan.zhihu.com/p/81151322
:::