4.1 Tensorflow:卷积函数
卷積
卷積神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)
其中,input為輸入,conv為卷積層,由卷積核構(gòu)成,pool為池層,由池化函數(shù)構(gòu)成最后是全連接層與輸出層,其負責(zé)對卷積層提取的特征進行處理以獲得我們需要的結(jié)果
###卷積函數(shù)
卷積函數(shù)是本篇文章要講解的內(nèi)容,在TensorFlow中卷積函數(shù)輸入的參數(shù)其輸入?yún)?shù)
主要有input, filter, strides, padding, use_cudnn_on_gpu=None,data_format=None, name=None)
其中
Input
Input的張量維度:[batch,in_height,in_width,in_channels],例如mnist中的輸入圖像為 28 * 28 的黑白圖像,其張量即為[batch,28,28,1],1代表黑白,RGB彩色圖像的通道則為3,而batch 則為輸入的圖像數(shù)量,一次輸入10張圖片時,其為10,20張時則為20
###filter 卷積核
filter 即為CNN中的卷積核,以我們最常用的tf.nn.conv2d為例 .它要求是一個Tensor,具有[filter_height, filter_width, in_channels, out_channels]這樣的shape,(其他的卷積函數(shù)其Tensor的具體內(nèi)容是不一樣的,在使用時請注意他們的不同)
tf.nn.conv2d中[filter_height, filter_width, in_channels, channel_multiplierl] 含義為[卷積核的高度,卷積核的寬度,圖像通道數(shù),卷積核個數(shù)],要求類型與參數(shù)input相同,有一個地方需要注意,第三維in_channels,就是參數(shù)input的第四維.
在使用中,因為一般不對Input的第一維和第四維進行卷積操作,所以strides 一般為[1,X,X,1]
strides
正如前面所述,strides 是另外一個極其重要的參數(shù),其為一個長度為4 的一維整數(shù)類型數(shù)組,每一位對應(yīng)input中每一位對應(yīng)的移動步長.
步長為一的卷積操作,不補零:
步長為二的卷積操作,不補零:
padding 與步長
padding=‘SAME’ 時,TensorFlow會自動對原圖像進行補零,從而使輸入輸出的圖像大小一致
效果如下:
padding=‘VALLLD’ 時,則會縮小原圖像的大小.
輸入輸出圖像大小的計算
此段內(nèi)容引自我翻譯的一篇文章
上面的內(nèi)容可能會使你混淆每一層的輸出尺寸。 所以我決定使用下面的內(nèi)容讓你能夠識別輸出尺寸。 在卷積層中,有三個關(guān)鍵控制著輸出尺寸的大小
我們可以應(yīng)用一個簡單的公式來計算輸出尺寸。 輸出圖像的空間大小可以計算**(W-F + 2 p / S)+ 1。 這里,W是輸入圖片大小,F是卷積核的大小,P是填充應(yīng)用的數(shù)量和S是步長的數(shù)量**。 假設(shè)我們有一個輸入圖像的大小32 * 32 * 3,我們應(yīng)用10過濾器的大小3 * 3 * 3,與單步和補零。
W = 32,F = 3,P = 0和S = 1。 輸出深度等于過濾器應(yīng)用的數(shù)量即10。
輸出音量的大小將(32-3 + 0)/ 1 + 1 = 30。 因此,輸出音量將30 * 30 * 10。
##TensorFlow中常用的卷積函數(shù)
tf.nn.conv2d
tf.nn.conv2d:對一個思維的輸入數(shù)據(jù) input 和四維的卷積核filter 進行操作,然后對輸入的數(shù)據(jù)進行二維的卷積操作,得到卷積之后的結(jié)果,也是我們最常用的卷積函數(shù)
示例代碼:
input_data = tf.Variable(np.random.rand(10, 9, 9, 3), dtype=np.float32) filter_data = tf.Variable(np.random.rand(2, 2, 3, 2), dtype=np.float32) y = tf.nn.conv2d(input_data, filter_data, strides=[1, 1, 1, 1], padding='SAME')print('tf.nn.conv2d : ', y) # tf.nn.conv2d : Tensor("Conv2D:0", shape=(10, 9, 9, 2), dtype=float32) # 在padding='SAME'時輸入輸出的圖像大小是一致的tf.nn.depthwise_conv2d
代碼如下
input_data = tf.Variable(np.random.rand(10, 9, 9, 3), dtype=np.float32) filter_data = tf.Variable(np.random.rand(2, 2, 3, 2), dtype=np.float32)y = tf.nn.depthwise_conv2d(input_data, filter_data, strides=[1, 1, 1, 1], padding='SAME') print('tf.nn.depthwise_conv2d : ', y)# tf.nn.depthwise_conv2d : Tensor("depthwise:0", shape=(10, 9, 9, 6), dtype=float32) # 輸出的通道數(shù)增加了其效果類似于多個卷積核運算都是張量的一個維度增加,不同之處在于通道數(shù)的增加是卷積核在不同通道上運算的結(jié)果,而多個卷積核運算是batch的數(shù)量增加
##完整的示例CODE
# - * - coding: utf - 8 -*- import tensorflow as tf import os import numpy as npos.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'# tf.nn.convolution # 計算N維卷積的和input_data = tf.Variable(np.random.rand(10, 9, 9, 3), dtype=np.float32) filter_data = tf.Variable(np.random.rand(2, 2, 3, 2), dtype=np.float32) y = tf.nn.convolution(input_data, filter_data, strides=[1, 1], padding='SAME')print('1. tf.nn.convolution : ', y) # 1. tf.nn.convolution : Tensor("convolution:0", shape=(10, 9, 9, 2), dtype=float32)# tf.nn.conv2d # 對一個思維的輸入數(shù)據(jù) input 和四維的卷積核filter 進行操作,然后對輸入的數(shù)據(jù)進行二維的卷積操作,得到卷積之后的結(jié)果 input_data = tf.Variable(np.random.rand(10, 9, 9, 3), dtype=np.float32) filter_data = tf.Variable(np.random.rand(2, 2, 3, 2), dtype=np.float32) y = tf.nn.conv2d(input_data, filter_data, strides=[1, 1, 1, 1], padding='SAME')print('2. tf.nn.conv2d : ', y) #2. tf.nn.conv2d : Tensor("Conv2D:0", shape=(10, 9, 9, 2), dtype=float32)# tf.nn.depthwise_conv2d # input 的數(shù)據(jù)維度 [batch ,in_height,in_wight,in_channels] # 卷積核的維度是 [filter_height,filter_heught,in_channel,channel_multiplierl] # 講不通的卷積和獨立的應(yīng)用在in_channels 的每一個通道上(從通道 1 到通道channel_multiplier) # 然后將所有結(jié)果進行匯總,輸出通道的總數(shù)是,in_channel * channel_multiplierinput_data = tf.Variable(np.random.rand(10, 9, 9, 3), dtype=np.float32) filter_data = tf.Variable(np.random.rand(2, 2, 3, 2), dtype=np.float32)y = tf.nn.depthwise_conv2d(input_data, filter_data, strides=[1, 1, 1, 1], padding='SAME') print('3. tf.nn.depthwise_conv2d : ', y)# tf.nn.separable_conv2d # 利用幾個分離的卷積核去做卷積,在該函數(shù)中,將應(yīng)用一個二維的卷積核,在每個通道上,以深度channel_multiplier進行卷積 input_data = tf.Variable(np.random.rand(10, 9, 9, 3), dtype=np.float32) depthwise_filter = tf.Variable(np.random.rand(2, 2, 3, 5), dtype=np.float32) poinwise_filter = tf.Variable(np.random.rand(1, 1, 15, 20), dtype=np.float32) # out_channels >= channel_multiplier * in_channels y = tf.nn.separable_conv2d(input_data, depthwise_filter=depthwise_filter, pointwise_filter=poinwise_filter,strides=[1, 1, 1, 1], padding='SAME') print('4. tf.nn.separable_conv2d : ', y)# 計算Atrous卷積,又稱孔卷積或者擴張卷積 input_data = tf.Variable(np.random.rand(1, 5, 5, 1), dtype=np.float32) filters = tf.Variable(np.random.rand(3, 3, 1, 1), dtype=np.float32) y = tf.nn.atrous_conv2d(input_data, filters, 2, padding='SAME') print('5. tf.nn.atrous_conv2d : ', y)# 在解卷積網(wǎng)絡(luò)(deconvolutional network) 中有時被稱為'反卷積',但實際上是conv2d的轉(zhuǎn)置,而不是實際的反卷積 x = tf.random_normal(shape=[1, 3, 3, 1]) kernal = tf.random_normal(shape=[2, 2, 3, 1]) y = tf.nn.conv2d_transpose(x, kernal, output_shape=[1, 5, 5, 3], strides=[1, 2, 2, 1], padding='SAME') print('6. tf.nn.conv2d_transpose : ', y)# 與二維卷積類似,用來計算給定三維輸入和過濾器的情況下的一維卷積. # 不同的是,它的輸入維度為 3,[batch,in_width,in_channels]. # 卷積核的維度也是三維,[filter_height,in_channel,channel_multiplierl] # stride 是一個正整數(shù),代表一定每一步的步長 input_data = tf.Variable(np.random.rand(1, 5, 1), dtype=np.float32) filters = tf.Variable(np.random.rand(3, 1, 3), dtype=np.float32) y = tf.nn.conv1d(input_data, filters, stride=2, padding='SAME') print('7. tf.nn.conv1d : ', y)# 與二維卷積類似,用來計算給定五維輸入和過濾器的情況下的三維卷積. # 不同的是,它的輸入維度為 5,[batch,in_depth,in_height,in_width,in_channels]. # 卷積核的維度也是三維,[filter_depth,filter_height,in_channel,channel_multiplierl] # stride 相較二維卷積多了一維,變?yōu)閇strides_batch,strides_depth,strides_height,strides_width,strides_channel],必須保證strides[0] = strides[4] =1 input_data = tf.Variable(np.random.rand(1, 2, 5, 5, 1), dtype=np.float32) filters = tf.Variable(np.random.rand(2, 3, 3, 1, 3), dtype=np.float32) y = tf.nn.conv3d(input_data, filters, strides=[1, 2, 2, 1, 1], padding='SAME') print('8. tf.nn.conv3d : ', y)# 與conv2d_transpose 二維反卷積類似 # 在解卷積網(wǎng)絡(luò)(deconvolutional network) 中有時被稱為'反卷積',但實際上是conv3d的轉(zhuǎn)置,而不是實際的反卷積 x = tf.random_normal(shape=[2, 1, 3, 3, 1]) kernal = tf.random_normal(shape=[2, 2, 2, 3, 1]) y = tf.nn.conv3d_transpose(x, kernal, output_shape=[2, 1, 5, 5, 3], strides=[1, 2, 2, 2, 1], padding='SAME') print('9. tf.nn.conv3d_transpose : ', y)RUN
1. tf.nn.convolution : Tensor("convolution:0", shape=(10, 9, 9, 2), dtype=float32) 2. tf.nn.conv2d : Tensor("Conv2D:0", shape=(10, 9, 9, 2), dtype=float32) 3. tf.nn.depthwise_conv2d : Tensor("depthwise:0", shape=(10, 9, 9, 6), dtype=float32) 4. tf.nn.separable_conv2d : Tensor("separable_conv2d:0", shape=(10, 9, 9, 20), dtype=float32) 5. tf.nn.atrous_conv2d : Tensor("convolution_1/BatchToSpaceND:0", shape=(1, 5, 5, 1), dtype=float32) 6. tf.nn.conv2d_transpose : Tensor("conv2d_transpose:0", shape=(1, 5, 5, 3), dtype=float32) 7. tf.nn.conv1d : Tensor("conv1d/Squeeze:0", shape=(1, 3, 3), dtype=float32) 8. tf.nn.conv3d : Tensor("Conv3D:0", shape=(1, 1, 3, 5, 3), dtype=float32) 9. tf.nn.conv3d_transpose : Tensor("conv3d_transpose:0", shape=(2, 1, 5, 5, 3), dtype=float32)總結(jié)
以上是生活随笔為你收集整理的4.1 Tensorflow:卷积函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.1 Tensorflow笔记(基础篇
- 下一篇: 4.2 Tensorflow笔记:池化函