動手學gluon系列之--上採樣的實現方法:Conv2DTranspose,轉置卷積的實現與原理

說道上採樣,就不得不提一篇非常經典的論文FCN,其在使用卷積縮放尺度後,利用上採樣將特徵圖放大,實現圖像分割,並且論文中多次提到的利用雙線性插值實現上採樣,那麼在gluon中,如何實現呢?

這裏需要使用函數nn.Conv2DTranspose,本質就是下面這兩行(備註中包含參數介紹


### 利用反捲積實現上採樣,初始化方式採用Bilinear便實現了雙線性插值上採樣
upsample=nn.Conv2DTranspose(channels=1024, kernel_size=4, padding=1, strides=2, groups=1024, weight_initializer=init.Bilinear())

### 如果將上採樣的學習率設置爲0,則始終是雙線性插值,參數不會變化
upsample.collect_params()/setattr("lr_mult", 0.0)

## 函數參數介紹
## channels: 這個通卷積的channel
## kernel_size: 這個不用多說,就是卷積核
## padding: 這個要多說一些,這個padding並不是conv2Dtranspose時候在特徵圖兩側添加的padding的數目,而是與它互逆的conv2D對應的padding數目,conv2Dtranspose兩側添加的數據是 kernel_size -1 - padding
## strides: 這裏也對應的是與之對應的conv2D所對應的strides
## groups: 不多說,好理解
## weight_initializer: 不多說,好理解

## 輸出尺度的計算方法
## out_height = (height-1)*strides[0]-2*padding[0]+kernel_size[0]+output_padding[0]
## out_width = (width-1)*strides[1]-2*padding[1]+kernel_size[1]+output_padding[1]

如果想實現的放大倍數爲f(偶數)通常的設置爲:

  • kernel_size = 2f
  • strides = f
  • padding = f/2

-------- 介紹完了函數,就好好介紹一下轉置卷積是怎麼回事吧—

轉置卷積,顧名思義,肯定是把卷積轉置了,沒錯,在進行轉置卷積的時候,的確是將卷積轉置了,不過爲什麼將卷積轉置呢?實際是根據公式計算出來的,這就要從轉置卷積的目的說起了,其實轉置卷積的目的就是來進行卷積相反的計算,假如我們有特徵圖X,卷積核W,可以得到Y = WX,那麼我們已知Y和W如何得到X呢?利用公式就是WTY=XW^{T}Y=X,轉置就是這麼出來的,想要詳細瞭解的小夥伴可以參考鏈接https://zhuanlan.zhihu.com/p/48501100,以及一篇非常經典的paper:https://arxiv.org/pdf/1603.07285.pdf

那麼從實現層面具體是怎麼做的呢?

其實也比較簡單,主要就是先padding後conv。

這裏可以根據是不是存在strides,而分成兩種情況:

  • 情況一:沒有strides:
    這就比較好理解了,下圖的第一張就是最典型的轉置卷積,其輸入圖像爲2x2大小,兩邊增加padding後,然後利用3x3的卷積核進行卷積操作,最終得到的是4x4的結果。

兩側增加的padding怎麼計算呢?這裏注意一下,再次強調一下,這裏padding的多少並不是函數中padding參數的值,而是kernel_size-1-padding的值,爲什麼是這個意思呢?主要是因爲函數要保證conv與convtranspose的參數一樣的情況下,可以互逆

  • 情況二:strides不等於1:
    這就是下面第二行的圖了,首先會在輸入特徵圖中間插入0點,然後再進行反捲積操作。

在這裏插入圖片描述
其實上面的圖是動圖,動圖可以訪問鏈接:https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md

https://github.com/vdumoulin/conv_arithmetic#convolution-arithmetic

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章