1. 程式人生 > >卷積、反捲積、轉置卷積和微步幅卷積

卷積、反捲積、轉置卷積和微步幅卷積

卷積
首先定義本文要用到的符號

  • 輸入圖片的大小: i1=i2=i
  • 卷積核的大小: k1=k2=k
  • 卷積步長:s1=s2=s
  • 填充padding=p

下圖表示引數為(i=5,k=3,s=2,p=1)的卷積計算過程,可以看出輸出的圖片大小是(33)
二維卷積
下圖是引數為(i=6,k=3,s=2,p=1)的卷積計算過程,輸出大小為(33)
這裡寫圖片描述

在tensorflow中,卷積函式的填充方式有兩種,VALIDSAME,其中SAME表示全0填充,VALID表示不新增。
如果填充方式為VALID輸出與輸入引數之間的關係為:
NewImage=(ik+1)/s
如果填充方式為S

AME輸出與輸入引數之間的關係為:
NewImage=(i/s)
高度上需要填充的畫素值:h=(NewImage1)s+ki,上面新增的0的行數h/2。下面為hh/2
也可以自己設定填充的0的圈數:
輸出與輸入引數之間的關係為
NewImage=i+2pks+1
反捲積又稱為轉置卷積
*反捲積又被稱為Transposed(轉置) Convolution,我們可以看出其實卷積層的前向傳播過程就是反捲積層的反向傳播過程,卷積層的反向傳播過程就是反捲積層的前向傳播過程。因為卷積層的前向反向計算分別為乘 CCT,而反捲積層的前向反向計算分別為乘 CTC和,所以它們的前向傳播和反向傳播剛好交換過來。
定義反捲積的引數如下:

  • 圖片大小:i.
  • 卷積核大小k
  • 步長s
  • 填充0p
    下圖分別是卷積操作和他對應的反捲積操作:
    這裡寫圖片描述
    這裡寫圖片描述
    當步長s=1時,可按照卷積過程逆向計算大小。
# -*- coding: utf-8 -*-
# @Time     : 2017/11/16 20:18
# @File     : Deconv2d.py
# @Author   : Zhiwei Zhong
# @Function : 反捲積轉置卷積
import tensorflow as tf
import numpy as np
x1 = tf.Variable(np.random.normal(0, 1, 3*3).reshape(1
, 3, 3, 1), dtype=tf.float32) # x2 shape=(1, 6, 6, 3)數字代表的含義分別是(batch, 行數, 列數,通道數) x2 = tf.Variable(np.random.normal(0, 1, 6*6*3).reshape(1, 6, 6, 3), dtype=tf.float32) x3 = tf.Variable(np.random.normal(0, 1, 5*5*3).reshape(1, 5, 5, 3), dtype=tf.float32) # 卷積核的 shape 含義為(濾波器的行, 濾波器的列, 當前層的深度, 濾波器的深度)濾波器的深度也是輸出層的深度 kernel = tf.Variable(np.random.normal(0, 1, 3*3*3).reshape(3, 3, 3, 1), dtype=tf.float32) # 6*6*3 -> 3*3*1 y2 = tf.layers.conv2d(x3, 1, 3, strides=2, padding='SAME') # 5*5*3 -> 3*3*1 y3 = tf.layers.conv2d(x2, 1, 3, strides=2, padding="SAME") # 相同的卷積引數下,6*6*3和5*5*3都能得到 3*3*1的結果,如果用下面這個函式他計算出的結果是不需要取整的那一個,如果 # 要規定輸出的大小,可以用nn.conv2d_transpose()函式。 z2 = tf.layers.conv2d_transpose(y3, 1, 3, strides=2, padding="SAME") # strides 第一維和最後一維必須是1, 中間兩個代表橫著和豎向每次卷積跨過的幅度。 z3 = tf.nn.conv2d_transpose(y2, filter=kernel, strides=[1, 2, 2, 1], output_shape=[1, 5, 5, 3], padding="SAME") with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print(sess.run(y2).shape) print(sess.run(y3).shape) print(sess.run(z2).shape) print(sess.run(z3).shape) """ (1, 3, 3, 1) (1, 3, 3, 1) (1, 6, 6, 1) (1, 5, 5, 3) """

微步幅卷積,即步幅為分數,對於步長大於1的卷積操作,我們可能會想到其對應的反捲積的步長小於1。如下圖所示,是一個引數為i=5,k=3,s=2,p=1的卷積操作對應的反捲積操作,對於卷積的小步長可以理解為在其輸入特徵單元之間插入s1個0,然後看成新的特徵輸入,此時步長為1,對應的卷積步長也為1。
這裡寫圖片描述