# [GAN] CycleGAN之D與G架構(U-Net & Resnet) ###### tags: `GAN` # Discriminator ## Patch GAN / Pixel GAN CycleGAN繼承此架構 | 圖片 | 說明 | | -------- | -------- | | ![](https://i.imgur.com/n4dwhiv.png) | **一般GAN**</br>圖片尺寸大時,**整張圖片**丟進 D 做檢查很易導致訓練時間過長、Overfitting 、 performance 不好等狀況<br> * 最後一層為 Dense layer,輸出只有一個值 [0, 1],用該值判斷"這整張圖"是否真假 | | ![](https://i.imgur.com/6EK00T4.png) ![](https://i.imgur.com/ZrZXHar.png) | **Patch GAN** </br>採取整張 **圖片一小部分 (patch)** 做檢查,而output的tensor包含多個Patch的機率,再取平均得到分類結果</br> 損失函數:</br>據風格判斷(因只取圖片的局部內容,無法用內容判斷loss) ![](https://i.imgur.com/SWEc95y.png =330x) | --- 為了能更好得對圖像的局部風格做判斷,使用 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 的區域 ![](https://i.imgur.com/pyvvU0W.png) # 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 ![](https://i.imgur.com/00yizK8.png) 以下過程重複4次 Convolution 運算後再加上激活函數(activation function),進行非線性轉換,之後得到的圖片會稱為特徵圖(feature map) 1. 3x3 Conv+Relu:兩次 (3x3是一個tensor) **特徵提取** 2. 2x2 Maxpooling2D **降低維度** 3. up-convolution ### 過程 ![](https://i.imgur.com/F6qnepK.png =500x) ### 為何選用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 ![](https://i.imgur.com/vuecq1J.png =450x) 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 ) ### 深層網絡→梯度消失 ![](https://i.imgur.com/kXYVU1l.png) * 過往因為深層網路訓練不起來,易造成 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相同! ![](https://i.imgur.com/hzeVK5V.png =350x) ### Degradation(退化) ![](https://i.imgur.com/NLPYXry.png =500x) * 深度增加時,準確度出現飽和,甚至下降 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$== 的相關性 * 點對點乘積之值:代表一個特徵的強度 ![](https://i.imgur.com/JTRHw6m.png =500x) * 舉例 ![](https://i.imgur.com/53lsODM.png =340x) ![](https://i.imgur.com/N7S1pul.png =340x) * 概念: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相似度 ![](https://i.imgur.com/qV7HDKV.png =550x) * 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(生成圖) * 公式: ![](https://i.imgur.com/4RMWNA7.png =400x)(單層的style loss) ![](https://i.imgur.com/j3ecOFm.png =230x)(全部層的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) ``` ## 反向傳播 ![](https://i.imgur.com/MwmMRqF.png =350x)  $\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 ![](https://i.imgur.com/HUdJJ0l.png =350x) $\partial z/\partial w_1=x_1$ $\partial z/\partial w_2=x_2$ forward pass的規律:input是什麼,微分之後就是什麼,即上層的output為下層的 ### Backward ![](https://i.imgur.com/oCzlclc.png) $\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。 ![](https://i.imgur.com/7XYzQ5q.png) 總結來說,反向傳播就是將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 :::