卷積、反捲積、轉置卷積和微步幅卷積
阿新 • • 發佈:2019-01-10
卷積
首先定義本文要用到的符號
- 輸入圖片的大小:
i1=i2=i 。 - 卷積核的大小:
k1=k2=k 。 - 卷積步長:
s1=s2=s 。 - 填充
padding=p 。
下圖表示引數為
下圖是引數為
在tensorflow中,卷積函式的填充方式有兩種,
如果填充方式為
如果填充方式為 AME
高度上需要填充的畫素值:
也可以自己設定填充的0的圈數:
輸出與輸入引數之間的關係為
反捲積又稱為轉置卷積
*反捲積又被稱為Transposed(轉置) Convolution,我們可以看出其實卷積層的前向傳播過程就是反捲積層的反向傳播過程,卷積層的反向傳播過程就是反捲積層的前向傳播過程。因為卷積層的前向反向計算分別為乘
定義反捲積的引數如下:
- 圖片大小:
i′ . - 卷積核大小
k′ 。 - 步長
s′ 。 - 填充0
p′ 。
下圖分別是卷積操作和他對應的反捲積操作:
當步長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。如下圖所示,是一個引數為