在深度学习的图像识别领域中,我们经常使用卷积神经网络CNN来对图像进行特征提取,当我们使用TensorFlow搭建自己的CNN时,一般会使用TensorFlow中的卷积函数和池化函数来对图像进行卷积和池化操作,而这两种函数中都存在参数padding,该参数的设置很容易引起错误,所以在此总结下。

1.为什么要使用padding

在弄懂padding规则前得先了解拥有padding参数的函数,在TensorFlow中,主要使用tf.nn.conv2d()进行(二维数据)卷积操作,tf.nn.max_pool()、tf.nn.avg_pool来分别实现最大池化和平均池化,通过查阅官方文档我们知道其需要的参数如下:

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

tf.nn.max_pool_with_argmax(input, ksize, strides, padding, Targmax=None, name=None)

tf.nn.max_pool(value, ksize, strides, padding, name=None)

这三个函数中都含有padding参数,我们在使用它们的时候需要传入所需的值,padding的值为字符串,可选值为'SAME' 和 'VALID' ;

padding参数的作用是决定在进行卷积或池化操作时,是否对输入的图像矩阵边缘补0,'SAME' 为补零,'VALID' 则不补,其原因是因为在这些操作过程中过滤器可能不能将某个方向上的数据刚好处理完,如下所示:

当步长为5,卷积核尺寸为6×6时,当padding为VALID时,则可能造成数据丢失(如左图),当padding为SAME时,则对其进行补零(如右图),

2. padding公式

首先,定义变量:

输入图片的宽和高:i_w 和 i_h

输出特征图的宽和高:o_w 和 o_h

过滤器的宽和高:f_w 和 f_h

宽和高方向的步长:s_w 和 s_h

宽和高方向总的补零个数:pad_w 和 pad_h

顶部和底部的补零个数:pad_top 和 pad_bottom

左部和右部的补零个数:pad_left 和 pad_right

1.VALID模式

输出的宽和高为

o_w = (i_w - f_w + 1)/ s_w #(结果向上取整)

o_h = (i_h - f_h + 1)/ s_h #(结果向上取整)

2. SAME模式

输出的宽和高为

o_w = i_w / s_w#(结果向上取整)o_h= i_h / s_h#(结果向上取整)

各个方向的补零个数为:max()为取较大值,

pad_h = max(( o_h -1 ) × s_h + f_h -i_h , 0)

pad_top= pad_h / 2 #注意此处向下取整

pad_bottom = pad_h -pad_top

pad_w= max(( o_w -1 ) × s_w + f_w -i_w , 0)

pad_left= pad_w / 2 #注意此处向下取整

pad_right = pad_w - pad_left

3.卷积padding的实战分析

接下来我们通过在TensorFlow中使用卷积和池化函数来分析padding参数在实际中的应用,代码如下:

#-*- coding: utf-8 -*-

importtensorflow as tf#首先,模拟输入一个图像矩阵,大小为5*5#输入图像矩阵的shape为[批次大小,图像的高度,图像的宽度,图像的通道数]

input = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 1]))#定义卷积核,大小为2*2,输入和输出都是单通道#卷积核的shape为[卷积核的高度,卷积核的宽度,图像通道数,卷积核的个数]

filter1 = tf.Variable(tf.constant([-1.0, 0, 0, -1], shape=[2, 2, 1, 1]))#卷积操作 strides为[批次大小,高度方向的移动步长,宽度方向的移动步长,通道数]#SAME

op1_conv_same = tf.nn.conv2d(input, filter1, strides=[1,2,2,1],padding='SAME')#VALID

op2_conv_valid = tf.nn.conv2d(input, filter1, strides=[1,2,2,1],padding='VALID')

init=tf.global_variables_initializer()

with tf.Session() as sess:

sess.run(init)print("op1_conv_same:\n", sess.run(op1_conv_same))print("op2_conv_valid:\n", sess.run(op2_conv_valid))

VALID模式的分析:

SAME模式分析:

o_w = i_w / s_w = 5/2 = 3o_h= i_h / s_h = 5/2 = 3pad_w= max ( (o_w - 1 ) × s_w + f_w -i_w , 0 )= max ( (3 - 1 ) × 2 + 2 - 5 , 0 ) = 1pad_left= 1 / 2 =0

pad_right= 1 - 0 =0#同理

pad_top =0

pad_bottom= 1

运行代码后的结果如下:

4.池化padding的实战分析

这里主要分析最大池化和平均池化两个函数,函数中padding参数设置和矩阵形状计算都与卷积一样,但需要注意的是:

1. 当padding='SAME',计算avg_pool时,每次的计算是除以图像被filter框出的非零元素的个数,而不是filter元素的个数,如下图,第一行第三列我们计算出的结果是除以2而非4,第三行第三列计算出的结果是除以1而非4;

2. 当计算全局池化时,即与图像矩阵形状相同的过滤器进行一次池化,此情况下无padding,即在边缘没有补0,我们直接除以整个矩阵的元素个数,而不是除以非零元素个数(注意与第一点进行区分)

池化函数的代码示例如下:

#-*- coding: utf-8 -*-

importtensorflow as tf#首先,模拟输入一个特征图,大小为5*5#输入图像矩阵的shape为[批次大小,图像的高度,图像的宽度,图像的通道数]

input = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 1]))#最大池化操作 strides为[批次大小,高度方向的移动步长,宽度方向的移动步长,通道数]#ksize为[1, 池化窗口的高,池化窗口的宽度,1]#SAME

op1_max_pooling_same = tf.nn.max_pool(input, [1,2,2,1], strides=[1,2,2,1],padding='SAME')#VALID

op2_max_pooling_valid = tf.nn.max_pool(input, [1,2,2,1], strides=[1,2,2,1],padding='VALID')#平均池化

op3_avg_pooling_same = tf.nn.avg_pool(input, [1,2,2,1], strides=[1,2,2,1],padding='SAME')#全局池化,filter是一个与输入矩阵一样大的过滤器

op4_global_pooling_same = tf.nn.avg_pool(input, [1,5,5,1], strides=[1,5,5,1],padding='SAME')

init=tf.global_variables_initializer()

with tf.Session() as sess:

sess.run(init)print("op1_max_pooling_same:\n", sess.run(op1_max_pooling_same))print("op2_max_pooling_valid:\n", sess.run(op2_max_pooling_valid))print("op3_max_pooling_same:\n", sess.run(op3_avg_pooling_same))print("op4_global_pooling_same:\n", sess.run(op4_global_pooling_same))

运行结果如下:

5.总结

在搭建CNN时,我们输入的图像矩阵在网络中需要经过多层卷积和池化操作,在这个过程中,feature map的形状会不断变化,如果不清楚padding参数引起的这些变化,程序在运行过程中会发生错误,当然在实际写代码时,可以将每一层feature map的形状打印出来,了解每一层Tensor的变化。

转载请注明出处:https://www.cnblogs.com/White-xzx/p/9497029.html

一文简单弄懂tensorflow_【TensorFlow】一文弄懂CNN中的padding参数相关推荐

  1. python爬虫简单实例-最简单的Python爬虫案例,看得懂说明你已入门,附赠教程

    原标题:最简单的Python爬虫案例,看得懂说明你已入门,附赠教程 这是最简单的Python爬虫案例,如果你能看懂,那么请你保持信心,因为你已经入门Python爬虫,只要带着信心和努力,你的技术能力在 ...

  2. 如何简单粗暴地上手 TensorFlow 2.0?

    整理 | 夕颜 出品 | AI科技大本营(ID:rgznai100) [导读] TensorFlow 2.0 于近期正式发布后,立即受到学术界与科研界的广泛关注与好评.此前,我们曾特邀专家回顾了 Te ...

  3. 让别人和自己看懂自己的程序代码?一文掌握Java单行多行、文档注释以及注解(Annotation)超详细的理解使用,IDEA注释注解快捷键和模板,提高程序代码更有可读性

    文章目录 单行和多行注释 文档注释(Java特有) Annotation(注解)的理解 常见的Annotation示例 IDEA注释注解快捷键及模板 自定义 Annotation JDK 中的元注解 ...

  4. 一个简单的解决方法:word文档打不开,错误提示mso.dll模块错误。

    一个简单的解决方法:word文档打不开,错误提示mso.dll模块错误. 参考文章: (1)一个简单的解决方法:word文档打不开,错误提示mso.dll模块错误. (2)https://www.cn ...

  5. 一文简单理解《Effective Java》建议

    考虑用静态工厂方法替代构造方法 传统的获取一个对象实例,通常是通过构造方法,new一个对象:不同数量的入参,会有不同的构造方法: 例如,统一的返回结果类,传统方式(伪代码)如下: //成功 retur ...

  6. 计算机培训软文,软文诊断62期: 学写软文标题,只需懂电脑开机即可

    原标题:软文诊断62期: 学写软文标题,只需懂电脑开机即可 学技能,一定要有好奇心.要有一双善于发现的眼睛! 秋香姐每天启动电脑,在没点击浏览器之前,电脑屏幕上就会出现杀毒软件如上图类似的热门动态推送 ...

  7. 【C语言】简单判断字符串是否为回文

    **C语言简单判断字符串是否为回文**哈哈哈哈哈,作为一个刚学c语言不久的小白,今天来分享一下自己今天学到的一个判断字符串是否为回文的解决方法_(:з」∠)_小白用的编译器是Visual Studio ...

  8. 搭建去中心化交易所——分享一个简单的DEX项目代码及文档

    分享一个简单的DEX项目代码及文档 Dex.top项目源码及文档分享 // DEx.top - Instant Trading on Chain // // Author: DEx.top Teamp ...

  9. 【必懂概念】一文详解什么是空洞卷积?

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 空洞卷积(Dilated Convolution) 简介 空洞卷积也叫扩张卷积或者 ...

最新文章

  1. 为什么要重写 hashcode 和 equals 方法?
  2. zabbix_get 命令介绍
  3. 重写JFrame的扩大 缩小 关闭按钮 以及菜单等
  4. 计算机中国象棋书籍,[建议]中国的象棋永远不能被没有“思维”的电脑所代替(就目前的电脑象棋软件...
  5. xgboost: 速度快效果好的boosting模型
  6. kettle资源库配置
  7. 基于QGIS初探PostgreSQL的PostGIS插件,包括YUM和编译安装PostGIS
  8. 《精解Windows8》——1.2 告别开始按钮进入“开始”屏幕时代
  9. HTML出现jQuery.Deferred exception: undefined is not a function,已解决
  10. 7-1 关于堆的判断 (25 分)
  11. 【计算机网络】1.1 计算机网络的基本概念
  12. 6种 分布式限流方案,我替你整理好了
  13. 【我评】——关于《中國化風格的淺析》
  14. Android 自定义View 三板斧之三——重写View来实现全新控件
  15. jdbc连接linux下的mysql_Linux JDBC连接MySQL数据库
  16. NWA Quality Analyst应用案例:在食品加工中选择和实施SPC软件
  17. SpringBoot启动报错:Parameter 0 of method hmset in com.qcby.rbac.util.RedisUtils required a bean of type
  18. centos桌面版配置ip_CentOS7安装GNOME可视化界面和如何配置IP地址
  19. 关于解决文件夹变成*.EXE可执行文件的问题
  20. Android Studio 使用Profiler时App崩溃闪退

热门文章

  1. 【1024】不整虚的,红包以备,致敬一线同僚!
  2. 微软宣布加入 OpenJDK,打不过就改变 Java 未来!
  3. HTTP协议的挑战者:RSocket
  4. html百度地图app,uniapp H5 百度地图(示例代码)
  5. linux触摸屏两指缩放_自定义TextView实现单指拖动,双指缩放旋转
  6. 帝国cms后台编辑时日期显示保存使用时间戳的方法
  7. error: ‘__declspec‘ attributes are not enabled; use ‘-fdeclspec‘ or ‘-fms-extensions‘ to enabl
  8. retinaface 记录
  9. NoBrokersAvailableError
  10. Laravel-5.1验证码mews captcha