TensorFlow学习---tf.nn.conv2d实现卷积操作
2017-06-21 15:09
656 查看
tf.nn.conv2d是TensorFlow里面实现卷积的函数。
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:卷积时在图像每一维的步长,这是一个一维的向量,长度4。对于图片,因为只有两维,通常strides取[1,stride,stride,1]
第四个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式。若是"SAME",表示卷积核可以停留在图像边缘,也就是输出与输入形状相同。若为"VALID",则输出形状为:(in_height-
filter_height+1)*(in_width- filter_width+1)
第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true
结果返回一个Tensor,这个输出,就是我们常说的featuremap
那么TensorFlow的卷积具体是怎样实现的呢,下面将举例说明。
详细的卷积过程可以看帖子:http://blog.csdn.net/huahuazhu/article/details/73469491
图像矩阵
卷积核矩阵
卷积过程:
2. 将1中的padding的值改为‘SAME’时,表示卷积核可以停留在图像边缘,也就是输出与输入形状相同,则输出5×5的feature map。
在计算时可以认为是图像的边缘补0,再进行滑动计算点积。
代码实现如下:
运行结果如下:
[[[[4.]
[ 3.]
[ 4.]]
[[ 2.]
[ 4.]
[ 3.]]
[[ 2.]
[ 3.]
[ 4.]]]]
###############
[[[[2.]
[ 2.]
[ 3.]
[ 1.]
[ 1.]]
[[ 1.]
[ 4.]
[ 3.]
[ 4.]
[ 1.]]
[[ 1.]
[ 2.]
[ 4.]
[ 3.]
[ 3.]]
[[ 1.]
[ 2.]
[ 3.]
[ 4.]
[ 1.]]
[[ 0.]
[ 2.]
[ 2.]
[ 1.]
[ 1.]]]]
下图中左侧为输入的三通道(R\G\B)的7*7图片,中间为两个核函数(即滤波器)Filter W0,Filter W1,右侧为输出Output Volume为两张3*3的feature map
代码实现如下:
运行结果如下:
[[[[0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 1.]
[ 1. 0. 0.]
[ 2. 1. 1.]
[ 0. 0. 2.]
[ 1. 0. 2.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 2. 0. 0.]
[ 0. 1. 1.]
[ 1. 1. 2.]
[ 0. 2. 0.]
[ 0. 1. 1.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 2. 1.]
[ 2. 1. 0.]
[ 2. 0. 2.]
[ 1. 0. 2.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 2. 2. 0.]
[ 2. 1. 1.]
[ 0. 2. 1.]
[ 1. 1. 2.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 1. 2. 2.]
[ 2. 1. 2.]
[ 0. 1. 2.]
[ 0. 1. 1.]
[ 0. 2. 1.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]]]
[[[[-1. 1.]
[ 0. 0.]
[ 0. 1.]]
[[ 0. 1.]
[-1. -1.]
[-1. 0.]]
[[ 1. 0.]
[-1. 0.]
[ 1. 0.]]]
[[[ 0. -1.]
[-1. -1.]
[ 0. -1.]]
[[ 1. -1.]
[ 1. 0.]
[ 0. -1.]]
[[ 0. 0.]
[-1. -1.]
[-1. 0.]]]
[[[ 0. 1.]
[ 0. -1.]
[ 0. 1.]]
[[-1. 1.]
[-1. -1.]
[ 1. -1.]]
[[-1. -1.]
[ 1. 1.]
[-1. -1.]]]]
[[[[-1. 1.]
[ 4. -4.]
[ 2. -9.]]
[[-8. -2.]
[-8. -7.]
[ 0. -6.]]
[[ 1. -4.]
[-4. -7.]
[ 1. 0.]]]]
对比一下,和理论分析的一致。
参考文档
【1】http://blog.csdn.net/mao_xiao_feng/article/details/53444333
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:卷积时在图像每一维的步长,这是一个一维的向量,长度4。对于图片,因为只有两维,通常strides取[1,stride,stride,1]
第四个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式。若是"SAME",表示卷积核可以停留在图像边缘,也就是输出与输入形状相同。若为"VALID",则输出形状为:(in_height-
filter_height+1)*(in_width- filter_width+1)
第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true
结果返回一个Tensor,这个输出,就是我们常说的featuremap
那么TensorFlow的卷积具体是怎样实现的呢,下面将举例说明。
详细的卷积过程可以看帖子:http://blog.csdn.net/huahuazhu/article/details/73469491
1单通道、一个卷积核
1.考虑一种简单的情况,现在有一张5×5单通道的图像(对应的shape:[1,5,5,1]),用一个3×3的卷积核(对应的shape:[3,3,1,1])去做卷积,最后会得到一张3×3的feature map。padding的值为‘VALID’图像矩阵
1 | 1 | 1 | 0 | 0 |
0 | 1 | 1 | 1 | 0 |
0 | 0 | 1 | 1 | 1 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 1 | 0 | 0 |
卷积核矩阵
1 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 1 |
卷积过程:
2. 将1中的padding的值改为‘SAME’时,表示卷积核可以停留在图像边缘,也就是输出与输入形状相同,则输出5×5的feature map。
在计算时可以认为是图像的边缘补0,再进行滑动计算点积。
0 | 0 | 0 | 0 | 0 | 0 | 0 | | 1 | 0 | 1 |
0 | 1 | 1 | 1 | 0 | 0 | 0 | | 0 | 1 | 0 |
0 | 0 | 1 | 1 | 1 | 0 | 0 | | 1 | 0 | 1 |
0 | 0 | 0 | 1 | 1 | 1 | 0 | | |||
0 | 0 | 0 | 1 | 1 | 0 | 0 | | |||
0 | 0 | 1 | 1 | 0 | 0 | 0 | | |||
0 | 0 | 0 | 0 | 0 | 0 | 0 | |
#!/usr/bin/env python2.7 #coding=utf-8 import tensorflow as tf #输入的图像矩阵 input = tf.constant([[1, 1, 1, 0,0], [0,1,1,1,0], [0,0,1,1,1], [0,0,1,1,0], [0,1,1,0,0]],shape=[1,5,5,1],dtype=tf.float32) #卷积核矩阵 filter = tf.constant([[1,0,1], [0,1,0], [1,0,1]],shape=[3,3,1,1],dtype=tf.float32) op1 = tf.nn.conv2d(input,filter,strides = [1,1,1,1],padding ='VALID') #卷积计算 op2 = tf.nn.conv2d(input,filter,strides = [1,1,1,1],padding = 'SAME') with tf.Session() as sess: result1 = sess.run(op1) result2 = sess.run(op2) print(result1) print('###############') print(result2)
运行结果如下:
[[[[4.]
[ 3.]
[ 4.]]
[[ 2.]
[ 4.]
[ 3.]]
[[ 2.]
[ 3.]
[ 4.]]]]
###############
[[[[2.]
[ 2.]
[ 3.]
[ 1.]
[ 1.]]
[[ 1.]
[ 4.]
[ 3.]
[ 4.]
[ 1.]]
[[ 1.]
[ 2.]
[ 4.]
[ 3.]
[ 3.]]
[[ 1.]
[ 2.]
[ 3.]
[ 4.]
[ 1.]]
[[ 0.]
[ 2.]
[ 2.]
[ 1.]
[ 1.]]]]
2 多通道多卷积核
下面对http://blog.csdn.net/huahuazhu/article/details/73469491中多通道多卷积核的例子进行实现。下图中左侧为输入的三通道(R\G\B)的7*7图片,中间为两个核函数(即滤波器)Filter W0,Filter W1,右侧为输出Output Volume为两张3*3的feature map
代码实现如下:
#!/usr/bin/env python2.7 #coding=utf-8 import tensorflow as tf #输入的图像矩阵:下面每行数据对应图像矩阵的行;每行中的每组值,分别对应0,1,2三个通道相应位置的值 input = tf.constant([[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,1],[1,0,0],[2,1,1],[0,0,2],[1,0,2],[0,0,0]], [[0,0,0],[2,0,0],[0,1,1],[1,1,2],[0,2,0],[0,1,1],[0,0,0]], [[0,0,0],[0,0,0],[0,2,1],[2,1,0],[2,0,2],[1,0,2],[0,0,0]], [[0,0,0],[2,2,0],[2,1,1],[0,2,1],[1,1,2],[0,0,0],[0,0,0]], [[0,0,0],[1,2,2],[2,1,2],[0,1,2],[0,1,1],[0,2,1],[0,0,0]], [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]],shape=[1,7,7,3],dtype=tf.float32) #input = tf.truncated_normal([1,5,5,3],stddev=0.1) #卷积核矩阵1 #filter = tf.truncated_normal([3,3,3,2], stddev=0.1) bias = tf.constant([1,0],shape=[2],dtype=tf.float32) #滤波器(卷积核)矩阵:两个卷积核,每个卷积核有三个通道,共六个矩阵。第一行[[-1,1],[0,0],[0,1]]为六个矩阵第0行0列的值,[-1,1]第一个数-1是第一个卷积核W0第0通道中(也就是第一个矩阵)第0行第0列的值,第二个数1是第二个卷积核W1第0通道中第0行第0列的值;[0,0] 第一个数0是第一个卷积核W0第1通道中第0行第0列的值,第二个数0是第二个卷积核W1第1通道中第0行第0列的值;以此类推。 filter = tf.constant([[[[-1,1],[0,0],[0,1]], [[0,1],[-1,-1],[-1,0]], [[1,0],[-1,0],[1,0]]], [[[0,-1],[-1,-1],[0,-1]], [[1,-1],[1,0],[0,-1]], [[0,0],[-1,-1],[-1,0]]], [[[0,1],[0,-1],[0,1]], [[-1,1],[-1,-1],[1,-1]], [[-1,-1],[1,1],[-1,-1]]]], shape=[3,3,3,2],dtype=tf.float32) #卷积计算,两个维度窗口滑动步长分别都为2 op1 = tf.nn.conv2d(input,filter,strides = [1,2,2,1],padding ='VALID')+bias op2 = tf.nn.conv2d(input,filter,strides = [1,2,2,1],padding = 'SAME')+bias with tf.Session() as sess: result1 = sess.run(op1) result2 = sess.run(op2) print(sess.run(input)) print(sess.run(filter)) print(result1) print('###############')
运行结果如下:
[[[[0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 1.]
[ 1. 0. 0.]
[ 2. 1. 1.]
[ 0. 0. 2.]
[ 1. 0. 2.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 2. 0. 0.]
[ 0. 1. 1.]
[ 1. 1. 2.]
[ 0. 2. 0.]
[ 0. 1. 1.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 2. 1.]
[ 2. 1. 0.]
[ 2. 0. 2.]
[ 1. 0. 2.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 2. 2. 0.]
[ 2. 1. 1.]
[ 0. 2. 1.]
[ 1. 1. 2.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 1. 2. 2.]
[ 2. 1. 2.]
[ 0. 1. 2.]
[ 0. 1. 1.]
[ 0. 2. 1.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]]]
[[[[-1. 1.]
[ 0. 0.]
[ 0. 1.]]
[[ 0. 1.]
[-1. -1.]
[-1. 0.]]
[[ 1. 0.]
[-1. 0.]
[ 1. 0.]]]
[[[ 0. -1.]
[-1. -1.]
[ 0. -1.]]
[[ 1. -1.]
[ 1. 0.]
[ 0. -1.]]
[[ 0. 0.]
[-1. -1.]
[-1. 0.]]]
[[[ 0. 1.]
[ 0. -1.]
[ 0. 1.]]
[[-1. 1.]
[-1. -1.]
[ 1. -1.]]
[[-1. -1.]
[ 1. 1.]
[-1. -1.]]]]
[[[[-1. 1.]
[ 4. -4.]
[ 2. -9.]]
[[-8. -2.]
[-8. -7.]
[ 0. -6.]]
[[ 1. -4.]
[-4. -7.]
[ 1. 0.]]]]
对比一下,和理论分析的一致。
参考文档
【1】http://blog.csdn.net/mao_xiao_feng/article/details/53444333
相关文章推荐
- 【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?
- 【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?
- 【Tensorflow】tf.nn.depthwise_conv2d如何实现深度卷积?
- 【Tensorflow】tf.nn.depthwise_conv2d如何实现深度卷积?
- 【Tensorflow】tf.nn.separable_conv2d如何实现深度可分卷积?
- 【TensorFlow】tf.nn.conv2d实现卷积
- 【TensorFlow】tf.nn.conv2d如何实现卷积
- tf.nn.conv2d实现卷积的过程
- 【TensorFlow】tf.nn.max_pool实现池化操作
- tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None) 除去name参数用以指定该操作的nam
- Tensorflow(r1.4)API--tf.nn.conv2d详解
- 【TensorFlow】tf.nn.max_pool实现池化操作
- tensorflow学习:tf.nn.conv2d 和 tf.layers.conv2d
- TensorFlow--tf.nn.max_pool实现池化操作
- 学习笔记TF052:卷积网络,神经网络发展,AlexNet的TensorFlow实现
- TensorFlow 用 tf.nn.max_pool 实现最大池化操作
- TensorFlow 用 tf.nn.conv2d 实现卷积操作
- 学习笔记TF052:卷积网络,神经网络发展,AlexNet的TensorFlow实现
- 【TensorFlow】tf.nn.max_pool实现池化操作
- TensorFlow:tf.nn.max_pool实现池化操作(转载)