做者:凌逆戰html
地址:https://www.cnblogs.com/LXP-Never/p/10763804.htmlpython
在看這兩個函數以前,咱們須要先了解一維卷積(conv1d)和二維卷積(conv2d),二維卷積是將一個特徵圖在width和height兩個方向進行滑動窗口操做,對應位置進行相乘求和;而一維卷積則只是在width或者height方向上進行滑動窗口並相乘求和。api
一維卷積:tf.layers.conv1d()
一維卷積經常使用於序列數據,如天然語言處理領域。數組
tf.layers.conv1d( inputs, filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, activation=None, use_bias=True, kernel_initializer=None, bias_initializer=tf.zeros_initializer(), kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, trainable=True, name=None, reuse=None )
參數:[1]網絡
- inputs:張量數據輸入,通常是[batch, width, length]
- filters:整數,輸出空間的維度,能夠理解爲卷積核(濾波器)的個數
kernel_size
:單個整數或元組/列表,指定1D(一維,一行或者一列)卷積窗口的長度。- strides:單個整數或元組/列表,指定卷積的步長,默認爲1
- padding:"SAME" or "VALID" (不區分大小寫)是否用0填充,
-
- SAME用0填充;
- VALID不使用0填充,捨去不匹配的多餘項。
-
- activation:激活函數
- ues_bias:該層是否使用誤差
- kernel_initializer:卷積核的初始化
- bias_initializer:偏置向量的初始化器
- kernel_regularizer:卷積核的正則化項
- bias_regularizer:偏置的正則化項
- activity_regularizer:輸出的正則化函數
- reuse:Boolean,是否使用相同名稱重用前一層的權重
- trainable:Boolean,若是True,將變量添加到圖collection中
- data_format:一個字符串,一個channels_last(默認)或channels_first。輸入中維度的排序。
-
- channels_last:對應於形狀的輸入(batch, length, channels)
- channels_first:對應於形狀輸入(batch, channels, length)
-
- name = 取一個名字
返回值:dom
一維卷積後的張量,ide
例子
import tensorflow as tf x = tf.get_variable(name="x", shape=[32, 512, 1024], initializer=tf.zeros_initializer) x = tf.layers.conv1d( x, filters=1, # 輸出的第三個通道是1 kernel_size=512, # 不用管它是多大,都不影響輸出的shape strides=1, padding='same', data_format='channels_last', dilation_rate=1, use_bias=True, bias_initializer=tf.zeros_initializer()) print(x) # Tensor("conv1d/BiasAdd:0", shape=(32, 512, 1), dtype=float32)
解析:函數
- 輸入數據的維度爲[batch, data_length, data_width]=[32, 512, 1024],通常輸入數據input第一維爲batch_size,此處爲32,意味着有32個樣本,第二維度和第三維度分別表示輸入的長和寬(512,1024)
- 一維卷積核是二維的,也有長和寬,長爲卷積核的數量kernel_size=512,由於卷積核的數量只有一個,因此寬爲輸入數據的寬度data_width=1024,因此一維卷積核的shape爲[512,1024]
- filteres是卷積核的個數,即輸出數據的第三維度。filteres=1,第三維度爲1
- 因此卷積後的輸出數據大小爲[32, 512, 1]
二維卷積:tf.layers.conv2d()
二維卷積經常使用於計算機視覺、圖像處理領域google
tf.layers.conv2d( inputs, filters, kernel_size, strides=(1, 1), padding='valid', data_format='channels_last', dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer=None, bias_initializer=tf.zeros_initializer(), kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, trainable=True, name=None, reuse=None )
參數:[4]
inputs
:張量輸入。通常是[batch, width, length,channel]filters
:整數,輸出空間的維度,能夠理解爲卷積核(濾波器)的個數kernel_size
:2個整數或元組/列表,指定2D卷積窗口的高度和寬度。能夠是單個整數,以指定全部空間維度的相同值。strides
:2個整數或元組/列表,指定卷積沿高度和寬度方向的步幅。能夠是單個整數,以指定全部空間維度的相同值。- padding:"SAME" or "VALID" (不區分大小寫)是否用0填充,
-
- SAME用0填充;
- VALID不使用0填充,捨去不匹配的多餘項。
-
data_format
:字符串,"channels_last"
(默認)或"channels_first"
。輸入中維度的排序。-
channels_last:
對應於具備形狀的輸入,(batch, height, width, channels)
channels_first:
對應於具備形狀的輸入(batch, channels, height, width)
-
activation
:激活函數use_bias
:Boolean, 該層是否使用誤差項kernel_initializer
:卷積核的初始化bias_initializer
: 偏置向量的初始化。若是爲None,將使用默認初始值設定項kernel_regularizer
:卷積核的正則化項bias_regularizer
: 偏置矢量的正則化項activity_regularizer
:輸出的正則化函數trainable
:Boolean,若是True,
將變量添加到圖collection中name
:圖層的namereuse
:Boolean,是否使用相同名稱重用前一層的權重
返回:
二維卷積後的張量spa
例子:
import tensorflow as tf x = tf.get_variable(name="x", shape=[1, 3, 3, 5], initializer=tf.zeros_initializer) x = tf.layers.conv2d( x, filters=1, # 結果的第三個通道是1 kernel_size=[1, 1], # 不用管它是多大,都不影響輸出的shape strides=[1, 1], padding='same', data_format='channels_last', use_bias=True, bias_initializer=tf.zeros_initializer()) print(x) # shape=(1, 3, 3, 1)
解析:
- input輸入是1張 3*3 大小的圖片,圖像通道數是5,輸入shape=(batch, data_length, data_width, data_channel)
- kernel_size卷積核shape是 1*1,數量filters是1strides步長是[1,1],第一維和第二維分別爲長度方向和寬度方向的步長 = 1。
- 最後輸出的shape爲[1,3,3,1] 的張量,即獲得一個3*3的feature map(batch,長,寬,輸出通道數)
- 長和寬只和strides有關,最後一個維度 = filters。
卷積層中的輸出大小計算
設輸入圖片大小W,Filter大小F*F,步長爲S,padding爲P,輸出圖片的大小爲N:
$$N=\frac{W-F+2P}{S}+1$$
向下取整後再加1。
在Tensoflow中,Padding有2個選型,'SAME'和'VALID' ,下面舉例說明差異:
若是 Padding='SAME',輸出尺寸爲: W / S(向上取整)
import tensorflow as tf input_image = tf.get_variable(shape=[64, 32, 32, 3], dtype=tf.float32, name="input", initializer=tf.zeros_initializer) conv0 = tf.layers.conv2d(input_image, 64, kernel_size=[3, 3], strides=[2, 2], padding='same') # 32/2=16 conv1 = tf.layers.conv2d(input_image, 64, kernel_size=[5, 5], strides=[2, 2], padding='same') # kernel_szie不影響輸出尺寸 print(conv0) # shape=(64, 16, 16, 64) print(conv1) # shape=(64, 16, 16, 64)
若是 Padding='VALID',輸出尺寸爲:(W - F + 1) / S
import tensorflow as tf input_image = tf.get_variable(shape=[64, 32, 32, 3], dtype=tf.float32, name="input", initializer=tf.zeros_initializer) conv0 = tf.layers.conv2d(input_image, 64, kernel_size=[3, 3], strides=[2, 2], padding='valid') # (32-3+1)/2=15 conv1 = tf.layers.conv2d(input_image, 64, kernel_size=[5, 5], strides=[2, 2], padding='valid') # (32-5+1)/2=14 print(conv0) # shape=(64, 15, 15, 64) print(conv1) # shape=(64, 14, 14, 64)
1x1卷積核的做用,加深一層網絡,提取更深特徵,數據變維,
有效卷積(valid)、同維卷積(same)、徹底卷積(full)
a = [1 2 3 4 5] 原數組
b = [8 7 6] 卷積核數組 kernel
使用b做爲卷積覈對a數組作一維卷積運算的過程以下:
原數組: 0 0 1 2 3 4 5 0 0 卷積數組: 6 7 8 6 7 8 6 7 8 6 7 8 6 7 8 6 7 8 6 7 8 ------------------------------------- 結果: 44 65 86 有效卷積 (valid) 23 44 65 86 59 同維卷積 (same) 8 23 44 65 86 59 30 徹底卷積 (full)
參考文獻:
[1] tensorflow官方API tf.layers.conv1d
[2] tf.layers.conv1d函數解析(一維卷積)
[3] tf.layer.conv1d、conv2d、conv3d
[4] tensorflow官方API tf.layers.conv2d
import tensorflow as tf # case 2 input = tf.Variable(tf.random_normal([1, 3, 3, 5])) filter = tf.Variable(tf.random_normal([1, 1, 5, 1])) op2 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID') # (1, 3, 3, 1) # case 3 input = tf.Variable(tf.random_normal([1, 3, 3, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 1])) op3 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID') # (1, 1, 1, 1) # case 4 input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 1])) op4 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID') # (1, 3, 3, 1) # case 5 input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 1])) op5 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME') # (1, 5, 5, 1) # case 6 input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 7])) op6 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME') # (1, 5, 5, 7) # case 7 input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 7])) op7 = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME') # (1, 3, 3, 7) # case 8 input = tf.Variable(tf.random_normal([10, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 7])) op8 = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME') # (10, 3, 3, 7) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) print("case 2") print(sess.run(op2).shape) # (1, 3, 3, 1) print("case 3") print(sess.run(op3).shape) # (1, 1, 1, 1) print("case 4") print(sess.run(op4).shape) # (1, 3, 3, 1) print("case 5") print(sess.run(op5).shape) # (1, 5, 5, 1) print("case 6") print(sess.run(op6).shape) # (1, 5, 5, 7) print("case 7") print(sess.run(op7).shape) # (1, 3, 3, 7) print("case 8") print(sess.run(op8).shape) # (10, 3, 3, 7)
原文出處:https://www.cnblogs.com/LXP-Never/p/10763804.html