---
# System prepended metadata

title: Free-Form Image Inpainting with Gated Convolution 論文讀後整理
tags: [Image Inpainting, Deep Learning]

---

---
title: Free-Form Image Inpainting with Gated Convolution 論文讀後整理
tags: Deep Learning,Image Inpainting
description: 論文讀後整理
---

# Free-Form Image Inpainting with Gated Convolution 論文讀後整理

最剛開始找到這篇是在Paper with Code上的 [Image Inpainting](https://paperswithcode.com/task/image-inpainting) 這欄

因為最多實作中 
第一名的Paper Nvidia使用的是PyTorch，所以選了第二名的這篇來看(使用TensorFlow)

## 概述
這篇是在2019年的ICCV(國際計算機視覺大會)發表
做的也如標題所述 透過 **Gated Convolution** **修補**任何形式的**影像**(浮水印、雜物...)
![](https://i.imgur.com/t8RxRsi.jpg)

## 環境
* Python 3.7.9
* cuda 9.2.148
* tensorflow 1.15.4
* keras 2.8.0
* 作者的toolkit
tensorflow toolkit neuralgym (run pip install git+https://github.com/JiahuiYu/neuralgym).

## 先決條件
partial conv 有幾項先決條件限制:

* 一、模型的架構
    1. valid pixels in input image 輸入圖像 有 圖像中的有效像素
    2. masked pixels in input image 輸入圖像 有 圖像中的無效像素(mask)
    3. neurons with receptive field covering no valid pixel of input image 神經元傳遞後 仍能感知到無效像素
    4. neurons with receptive field covering different number of valid pixels of input image 神經元傳遞後 仍能知道各神經元有多少有效像素/特徵
    5. synthesized pixels in deep layers. 合成深層的像素

* 二、分離有效與無效像素
    * Q :  如何能夠從使用者傳入的圖像中，分離出有效與無效像素，單純以白色來區分會導致許多問題產生
    * A : 透過另一個檔案另外寫入MASK
* 三、無效像素感知不到
    * Q : 在深層模型中，無效像素因為模型的深度 而導致感知越來越薄弱，深層的神經元也需要知道MASK外的像素來合成
    * A : 自動學習MASK的值->gated convolution

## Gated convolution
這個卷積 他對每個channel(RGB 或 自定義通道)及 空間位置(mask內外) 學習了動態門控機制
### 門控機制
1. 輸入特徵先計算gating values
![](https://i.imgur.com/DGVgkyQ.png)

2. output
![](https://i.imgur.com/yQDaOEd.png)

這個門控實作簡單 且 在下面的幾種情況下表現更好
1. mask有複雜形狀
2. the inputs are no longer simply RGB channels with a mask but also have conditional inputs like sparse sketch(不太懂這個意思)

### 網路架構
1. 堆疊Gated convolution 形成一個 encoder-decoder network
2. 透過 contextual attention module within same refinement network 更容易捕捉依賴關係

## vanilla convolution
一般的conv在圖片分類、物件偵測上獲得很好的運用
但是在圖像修復上卻有一些缺點
不管有沒有缺漏 都會經過相同的filter(沒有辦法分出其中是有效/無效的pixel)

這樣會導致輸出上產生 視覺偽影(顏色差異、模糊、邊緣效應)
:::warning
補圖片說明
:::

## Partial convolution
這是由 Nvidia團隊於 ECCV 2018 提出,
透過masking 與 e-normalization(mask-update)的方法來逐步修復整張圖片
![](https://i.imgur.com/oKUm9qk.png)
![](https://i.imgur.com/9q6yj5m.png)
![](https://i.imgur.com/ayj1egk.png)
* 紅框
    此時 Kernal 內的 Mask value 都為 1(都為正確的pixel不需填補)，
    那他會執行 eq1 的 if sum(M) > 0 的式子。
    概念為 : 此處並非空洞，可使用一般的 Convolution 正常處理。

* 綠框
    雖然 Kernal 右下角的 Mask value 右下角為 0(代表空洞)，
    但是我們可以透過附近的 1 即爲正常的 pixel 學到點東西，
    可能是顏色、紋理。

* 藍框
    此時 Kernal 內的 Mask value 全為 0(都為空缺需填補的pixel)，
    那我們就先不處理，
    等傳遞到後面的 Layer 有較多的資訊時再做修補。

持續這樣修補到整張圖片的mask都是1那就修補完成了

### Partial convolution　的缺點
1. 因為mask-update的方式會導致 不管只有 1個有效pixel 或 9個有效pixel 下一層的mask都被更新成1
![](https://i.imgur.com/9q6yj5m.png)
2. 沒有辦法額外支援使用者的輸入
![](https://i.imgur.com/mJSUWs7.png)
![](https://i.imgur.com/SlFSJOF.png)
3. mask到深層網路會逐漸消失，後面會提到此篇提出的gated conv
4. 每層網路都共用相同的channel 限制的網路的彈性，也是跟gated conv有關係
![](https://i.imgur.com/23Q1YG4.png)

### Gated Convolution
就是從前面的Hard Mask改成Soft Mask(by DeepLearning)
具體的公式如下
![](https://i.imgur.com/HNHmVEC.png)
跟Pconv不同的是他的mask是動態生成的，
相比於Pconv 它不僅學習了特徵擷取，也做到了Semantic Segmentation
在深層網路也能突出mask和sketch的訊息(highlight the masked regions and sketch information)，達到更好的修復成果
具體Code的實現如下 [JiahuiYu/generative_inpainting/inpaint_ops.py@Github](https://github.dev/JiahuiYu/generative_inpainting)
![](https://i.imgur.com/dGZWQZ3.png)



特徵擷取的激活函數可以是ReLU, ELU and LeakyReLU(作者提供的Model預設是ELU)
![](https://i.imgur.com/RuT7pBf.png)


## SN-PatchGAN
在辨別圖像生成是否正確上，使用了SN-PatchGAN，他是基於Spectral Normalization for Generative Adversarial Networks所修改的GAN網路。
SN-GAN 簡單來說就是Lipschitz constant 對每層的輸出做限縮，讓GAN的穩定度提升。
但此篇論文有26頁的篇幅，所以沒有深入研究。
![](https://i.imgur.com/DA042Ke.png)

Dsn : 代表 spectral-normalized discriminator
x : 前面網路生成的圖片
z : 代表不完整的圖片

最後的loss 是 pixel-wise l1 reconstruction 和 SN-PatchGAN loss 比例1:1組成
![](https://i.imgur.com/eTPeue7.png)

## mask 與 sketch生成
### mask
用了一個演算法來生成像是人畫的樣子
![](https://i.imgur.com/EqOuHlj.png)
![](https://i.imgur.com/7AbcjzL.png)
### sketch
![](https://i.imgur.com/pgVOYl9.png)
引用了 "Holistically-Nested Edge Detection"這邊論文的HED model來生成邊緣

## 整體網路架構
![](https://i.imgur.com/vLhQdUV.png)

整體的網路架構是借鑑自"Generative Image Inpainting with Contextual Attention"這篇論文

## Coarse Network
stage 1的部分是Coarse Network 粗網路 
其中關鍵使用了 **dilated convolution** 擴張卷積 **增加 Receptive Field，**
其主要原因為 **Receptive Field的大小會大程度的影響修復的品質**。
在恢復圖片大小的部分，
作者有提到原本的Pconv所使用的UNet架構在**skip connections的輸入幾乎為0**，無法傳播顏色和紋理訊息
使用了簡單的鄰近插值法。
```python=
x = resize(x, func=tf.image.resize_nearest_neighbor)
```
這張圖有點醜 但是蠻容易理解鄰近插值法做的事情
![](https://i.imgur.com/7cYo5H9.png)


## Two Branch Refinement Network with Contextual Attention
這邊主要是借鑑自別人的想法，我覺得這邊的修復反而是較關鍵的一環
![](https://i.imgur.com/QanCVNd.png)
作者想解決的問題是：在背景區中匹配MASK的特徵。
1. 在背景區提取3*3的特徵 -> kernel
2. 使用標準化內積(餘弦相似度)
3. 透過softmax計算權值
4. 選出最好的方塊 填入mask 再反卷積出Mask的缺失的部分

如果內存爆掉 有兩種解法
1. 增加Conv的stride
2. 降解析度

而下面的是透過 擴張卷積來"想像" 缺失內容
完成後把兩個連接 
```python=
x = tf.concat([x_hallu, pm], axis=3)
```

反卷積出結果後 丟到SN-PatchGan裡面去對抗並修正模型。


[论文解析Generative Image Inpainting with Contextual Attention](https://blog.csdn.net/weixin_42360095/article/details/92699064)

## 比較
![](https://i.imgur.com/xjeQHIt.jpg)

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


{%hackmd theme-dark %}