tf卷积的实现

一、函数定义:

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

除去name参数用以指定该操作的name,与方法有关的一共五个参数:

input:
指需要做卷积的输入图像,它要求是一个Tensor,具有[batch, in_height, in_width, in_channels]这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一

filter:
相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意:第三维in_channels=input的第四维

strides:卷积时在input图像上每一维的步长,是长为4的向量[1,height_stride,width_stride,1],1代表移动一步

padding:
string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同的卷积方式(后面会介绍)。前者代表通过补0使,卷积提取的特征与原来的patch一致;VALID代表不填充

use_cudnn_on_gpu:
bool类型,是否使用cudnn加速,默认为true

结果返回一个Tensor,这个输出,就是我们常说的feature map

二、计算流程

情况a,现在有一张 3×3 单通道的图像(对应的shape:[1,3,3,1]),用一个1×1的卷积核(对应的shape:[1,1,1,1],形如[[[[2.5]]]])去做卷积,最后会得到一张3×3的feature map(图像上从左到右,从上到下每次取一个元素,与卷积核计算乘积)。

import tensorflow as tf
sess=tf.Session()

i = tf.constant([[1,2,3,],
                 [4,5,6],
                 [7,8,9]],dtype="float")
k = tf.constant([2.0])   
input = tf.reshape(i,[1,3,3,1])   #输入是一张3*3单通道图片
filter = tf.reshape(k,[1,1,1,1])  #卷积核是size=1*1,输入单通道(由input决定),输出单通道
op1 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')
print(sess.run(op1))
#--op1输出
  
[图片个数,卷积高决定,卷积宽决定,输出通道]

[[[[  2.]
   [  4.]
   [  6.]]

  [[  8.]
   [ 10.]
   [ 12.]]

  [[ 14.]
   [ 16.]
   [ 18.]]]]

i = tf.constant([
    [4, 3, 1, 0],
    [2, 1, 0, 1],
    [1, 2, 4, 1],
    [3, 1, 0, 2]], dtype=tf.float32)
    
k = tf.constant([
    [1, 0, 1],
    [2, 1, 0],
    [0, 0, 1]], dtype=tf.float32)

input  = tf.reshape(i, [1, 4, 4, 1], name='image')
filter = tf.reshape(k, [3, 3, 1, 1], name='kernel')
op2 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')
print(sess.run(op2))

2.增加图片的通道数,使用一张3×3 五通道的图像(对应的shape:[1,3,3,5]),用一个1×1的卷积核(对应的shape:[1,1,1,1])去做卷积,仍然是一张3×3的feature map,这就相当于每一个像素点,卷积核都与该像素点的每一个通道做点积

你可能感兴趣的:(tf卷积的实现)