【TensorFlow】tf.nn.conv2d是怎样实现卷积的?

原文:http://blog.csdn.net/mao_xiao_feng/article/details/78004522

实验环境:tensorflow版本1.2.0,python2.7


介绍

惯例先展示函数:

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 是另外一个极其重要的参数,其为一个长度为4 的一维整数类型数组,每一位对应input中每一位对应的移动步长. 
    步长为一的卷积操作,不补零: 
     
    步长为二的卷积操作,不补零: 

    padding 与步长

    padding=’SAME’ 时,TensorFlow会自动对原图像进行补零,从而使输入输出的图像大小一致 
    效果如下: 

    padding=’VALLLD’ 时,则会缩小原图像的大小. 

    输入输出图像大小的计算

    此段内容引自我翻译的一篇文章 
    上面的内容可能会使你混淆每一层的输出尺寸。 所以我决定使用下面的内容让你能够识别输出尺寸。 在卷积层中,有三个关键控制着输出尺寸的大小

    1. 过滤器的数量 ——输出音量的深度就等于滤波器应用的数量。 每个滤波器(卷积核)可以输出一个图片,卷积核增加,输出图片的数量增加 
    2. 步长 ——控制着卷积核向下移动的像素值。 高步值长时我们跨过的像素值,因此产生较小的输出量。
    3. 补零 ——这有助于我们保持输入图像的大小。 如果只在原始图像周围添加一个补零的层数,并且步长为一,那么输出将保留原始图像的大小。

    我们可以应用一个简单的公式来计算输出尺寸。 输出图像的空间大小可以计算(W-F + 2 p / S)+ 1。 这里,W是输入图片大小,F是卷积核的大小,P是填充应用的数量和S是步长的数量。 假设我们有一个输入图像的大小32 * 32 * 3,我们应用10过滤器的大小3 * 3 * 3,与单步和补零。

    W = 32,F = 3,P = 0和S = 1。 输出深度等于过滤器应用的数量即10。

    输出音量的大小将(32-3 + 0)/ 1 + 1 = 30。 因此,输出音量将30 * 30 * 10。


  • padding: 
    string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同的卷积方式(后面会介绍)

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

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


实验

那么TensorFlow的卷积具体是怎样实现的呢,用一些例子去解释它:

1.考虑一种最简单的情况,现在有一张3×3单通道的图像(对应的shape:[1,3,3,1]),用一个1×1的卷积核(对应的shape:[1,1,1,1])去做卷积,最后会得到一张3×3的feature map

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

input = tf.Variable(tf.random_normal([1,3,3,5]))
filter = tf.Variable(tf.random_normal([1,1,5,1]))op = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')

3.把卷积核扩大,现在用3×3的卷积核做卷积,最后的输出是一个值,相当于情况2的feature map所有像素点的值求和

input = tf.Variable(tf.random_normal([1,3,3,5]))
filter = tf.Variable(tf.random_normal([3,3,5,1]))op = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')

4.使用更大的图片将情况2的图片扩大到5×5,仍然是3×3的卷积核,令步长为1,输出3×3的feature map

.....
.xxx.
.xxx.
.xxx.
.....

5.上面我们一直令参数padding的值为‘VALID’,当其为‘SAME’时,表示卷积核可以停留在图像边缘,如下,输出5×5的feature map

input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,1]))op = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')
xxxxx
xxxxx
xxxxx
xxxxx
xxxxx

6.如果卷积核有多个

input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))op = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')

此时输出7张5×5的feature map

7.步长不为1的情况,文档里说了对于图片,因为只有两维,通常strides取[1,stride,stride,1]

input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))op = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')

此时,输出7张3×3的feature map

x.x.x
.....
x.x.x
.....
x.x.x

8.如果batch值不为1,同时输入10张图

input = tf.Variable(tf.random_normal([10,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))op = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')

每张图,都有7张3×3的feature map,输出的shape就是[10,3,3,7]


代码清单

最后,把程序总结一下:

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')
#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')
#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')
#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')
#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')
#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')
#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')init = tf.initialize_all_variables()
with tf.Session() as sess:sess.run(init)print("case 2")print(sess.run(op2))print("case 3")print(sess.run(op3))print("case 4")print(sess.run(op4))print("case 5")print(sess.run(op5))print("case 6")print(sess.run(op6))print("case 7")print(sess.run(op7))print("case 8")print(sess.run(op8))

TensorFlow tf.nn.conv2d是怎样实现卷积的?相关推荐

  1. 【TensorFlow】tf.nn.conv2d是怎样实现卷积的?

    int height_col= (height + 2 * pad_h - kernel_h) / stride_h + 1; int width_col = (width + 2 * pad_w - ...

  2. TensorFlow 从入门到精通(八):TensorFlow tf.nn.conv2d 一路追查

    读者可能还记得本系列博客(二)和(六)中 tf.nn 模块,其中最关心的是 conv2d 这个函数. 首先将博客(二) MNIST 例程中 convolutional.py 关键源码列出: def m ...

  3. 【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?膨胀卷积

    介绍 关于空洞卷积的理论可以查看以下链接,这里我们不详细讲理论: 1.Long J, Shelhamer E, Darrell T, et al. Fully convolutional networ ...

  4. tensorflow详解-tf.nn.conv2d(),tf.nn.max_pool()

    tf.nn.conv2d() 函数来计算卷积,weights 作为滤波器,[1, 2, 2, 1] 作为 strides.TensorFlow 对每一个 input 维度使用一个单独的 stride ...

  5. tf.nn.conv2d理解(带通道的卷积图片输出案例)

    三篇参考: 1.https://blog.csdn.net/goodshot/article/details/79655915 TF-卷积函数 tf.nn.conv2d 介绍 2.https://bl ...

  6. [TensorFlow 学习笔记-04]卷积函数之tf.nn.conv2d

    [版权说明] TensorFlow 学习笔记参考: 李嘉璇 著 TensorFlow技术解析与实战 黄文坚 唐源 著 TensorFlow实战郑泽宇  顾思宇 著 TensorFlow实战Google ...

  7. 通俗理解tf.nn.conv2d() tf.nn.conv3d( )参数的含义 pytorhc 卷积

    20210609 例如(3,3,(3,7,7))表示的是输入图像的通道数是3,输出图像的通道数是3,(3,7,7)表示过滤器每次处理3帧图像,卷积核的大小是3 x 7 x 7. https://blo ...

  8. 【TensorFlow】理解tf.nn.conv2d方法 ( 附代码详解注释 )

    最近在研究学习TensorFlow,在做识别手写数字的demo时,遇到了tf.nn.conv2d这个方法,查阅了官网的API 发现讲得比较简略,还是没理解.google了一下,参考了网上一些朋友写得博 ...

  9. TensorFlow学习笔记(十七)tf.nn.conv2d

    在给定的4D input与filter下计算2D卷积输入shape为[batch, height, width, in_channels] TensorFlow的CNN代码中有 tf.nn.conv2 ...

最新文章

  1. flash与php交互,flash与PHP的交互技巧
  2. java连接sqlserver2008_java连接sqlserver2008驱动包
  3. java gradle入门_Gradle入门:我们的第一个Java项目
  4. leetcode 705. 设计哈希集合
  5. 【英语学习】【WOTD】billion 释义/词源/示例
  6. 去掉字符串首尾逗号_去除字符串首尾空格和特殊字符
  7. 暴风影音使用技巧十则
  8. No discret job created in Oracle
  9. Vant2 源码分析之 vant-sticky
  10. kali安装配置使用手册
  11. bootstrap常用样式整理
  12. mysql 错误码1236_【MySql】MySQL Replication Fatal Error 1236
  13. 木瓜蛋白酶和胃蛋白酶对免疫球蛋白Ig处理的不同
  14. linux中fstab文件_如何在Linux上写入fstab文件
  15. javascript字符串匹配正则表达式方法
  16. pandas学习笔记之DateFrame
  17. 计算机打不开管理reg,windows为何打不开.reg文件了
  18. 作为一名计算机学院普通的大学生如何提高兴趣敲代码?谈谈我的感受,欢迎交流
  19. 燃情7月,ACMUG厦门、上海双城技术沙龙及MySQL/MariaDB创始人Monty中国行活动
  20. C语言100以内的素数

热门文章

  1. 实验一 linux命令使用,实验一XXXXX常用linux命令的使用(一)
  2. mysql的聚合查询_MySql聚合查询
  3. linux安装后硬盘变小,Linux硬盘安装步骤
  4. java耗时任务有哪些,java后台耗时任务多线程返回结果
  5. php中public放什么,PHP中常用关键字public, private, protected, static...
  6. php数字小数大小比较,PHP 常用的数学函数和数值处理函数
  7. 关不关机 扫地机器人_BOBOT扫地机器人能扫还能拖,你的家庭好助理
  8. 据说有大神形容这是三句话学会C语言
  9. 皮一皮:泡沫面膜,直男慎送此礼物...
  10. 还在封装各种 Util 工具类?这个神级框架帮你解决所有问题!