1. 程式人生 > >Tensorflow 反捲積(DeConv)實現原理+ 手寫python程式碼實現反捲積(DeConv)

Tensorflow 反捲積(DeConv)實現原理+ 手寫python程式碼實現反捲積(DeConv)

1、反捲積原理

反捲積原理不太好用文字描述,這裡直接以一個簡單例子描述反捲積。

假設輸入如下:

[[1,0,1],
 [0,2,1],
 [1,1,0]]

 反捲積卷積核如下:

[[ 1, 0, 1],
 [-1, 1, 0],
 [ 0,-1, 0]]

 現在通過strides=2來進行反捲積,使得尺寸由原來的3*3變為6*6.那麼在Tensorflow框架中,反捲積的過程如下(不同框架在裁剪這步可能不一樣):

 

其實通過繪製的這張圖,就已經把原理講的很清楚,大致步驟就是,先填充0,然後進行卷積,卷積過程和上一篇講述的一致。最後一步還要進行裁剪。

2、程式碼實現

上一篇文章我們只針對輸出通道數為1進行程式碼實現,在這篇文章中,反捲積我們將輸出通道設定為多個,這樣更符合實際場景。

先定義輸入和卷積核:


input_data=[[[1,0,1],
            [0,2,1],
            [1,1,0]],

            [[2,0,2],
            [0,1,0],
            [1,0,0]],

            [[1,1,1],
            [2,2,0],
            [1,1,1]],
            [[1,1,2],
            [1,0,1],
            [0,2,2]]] 
weights_data=[
            [[[ 1, 0, 1],
              [-1, 1, 0],
              [ 0,-1, 0]],

              [[-1, 0, 1],    
               [ 0, 0, 1],
               [ 1, 1, 1]],

              [[ 0, 1, 1],
               [ 2, 0, 1],
               [ 1, 2, 1]],

              [[ 1, 1, 1],
               [ 0, 2, 1],
               [ 1, 0, 1]]],

              [[[ 1, 0, 2],
                [-2, 1, 1],
                [ 1,-1, 0]],

               [[-1, 0, 1],    
                [-1, 2, 1],
                [ 1, 1, 1]],

               [[ 0, 0, 0],
                [ 2, 2, 1],
                [ 1,-1, 1]],
    
              [[ 2, 1, 1],
               [ 0,-1, 1],
               [ 1, 1, 1]]]
] 

上面定義的輸入核卷積核,在接下的運算過程如下圖所示:

可以看到實際上,反捲積和卷積基本一致,差別在於,反捲積需要填充過程,並在最後一步需要裁剪。

有幾點需要注意:

1、每個卷積核需要旋轉180°後,再傳入tf.nn.conv2d_transpose函式中,因為tf.nn.conv2d_transpose內部會旋轉180°,所以提前旋轉,再經內部旋轉後,能包傳卷積核和我們使用的卷積核的資料排列一致。

2、我們定義的輸入的shape為[c, h, w]需要轉為tensorflow所使用的[n, h, w, c]。

3、我們定義的卷積核shape為[out_c, in_c, h, w]需要轉為tensorflow反捲積中所使用的[h, w, out_c, in_c]

 

感謝作者:https://www.jianshu.com/p/f0674e48894c