介绍
关于空洞卷积的理论可以查看以下链接,这里我们不详细讲理论:

1.Long J, Shelhamer E, Darrell T, et al. Fully convolutional networks for semantic segmentation[C]. Computer Vision and Pattern Recognition, 2015.

2.Yu, Fisher, and Vladlen Koltun. “Multi-scale context aggregation by dilated convolutions.” arXiv preprint arXiv:1511.07122 (2015).

3.如何理解空洞卷积(dilated convolution)?

其实用一句话概括就是,在不用pooling的情况下扩大感受野(pooling层会导致信息损失)

为了阅读方便再贴一些相关链接:

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

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

惯例先展示函数:

tf.nn.atrous_conv2d(value,filters,rate,padding,name=None)
1
除去name参数用以指定该操作的name,与方法有关的一共四个参数:

value:
指需要做卷积的输入图像,要求是一个4维Tensor,具有[batch, height, width, channels]这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数]

filters:
相当于CNN中的卷积核,要求是一个4维Tensor,具有[filter_height, filter_width, channels, out_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],同理这里第三维channels,就是参数value的第四维

rate:
要求是一个int型的正数,正常的卷积操作应该会有stride(即卷积核的滑动步长),但是空洞卷积是没有stride参数的,这一点尤其要注意。取而代之,它使用了新的rate参数,那么rate参数有什么用呢?它定义为我们在输入图像上卷积时的采样间隔,你可以理解为卷积核当中穿插了(rate-1)数量的“0”,把原来的卷积核插出了很多“洞洞”,这样做卷积时就相当于对原图像的采样间隔变大了。具体怎么插得,可以看后面更加详细的描述。此时我们很容易得出rate=1时,就没有0插入,此时这个函数就变成了普通卷积。

padding:
string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同边缘填充方式。

ok,完了,到这就没有参数了,或许有的小伙伴会问那“stride”参数呢。其实这个函数已经默认了stride=1,也就是滑动步长无法改变,固定为1。

结果返回一个Tensor,填充方式为“VALID”时,返回[batch,height-2*(filter_width-1),width-2*(filter_height-1),out_channels]的Tensor,填充方式为“SAME”时,返回[batch, height, width, out_channels]的Tensor,这个结果怎么得出来的?先不急,我们通过一段程序形象的演示一下空洞卷积。

实验
首先创建一张2通道图

img = tf.constant(value=[[[[1],[2],[3],[4]],[[1],[2],[3],[4]],[[1],[2],[3],[4]],[[1],[2],[3],[4]]]],dtype=tf.float32)
img = tf.concat(values=[img,img],axis=3)
1
2
然后用一个3*3卷积核去做卷积

filter = tf.constant(value=1, shape=[3,3,2,5], dtype=tf.float32)
out_img = tf.nn.atrous_conv2d(value=img, filters=filter, rate=1)
1
2
建立好了img和filter,就可以做卷积了

out_img = tf.nn.conv2d(input=img, filter=filter, strides=[1,1,1,1], padding='VALID')
1
输出5个channel,我们设置rate=1,此时空洞卷积可以看做普通的卷积,分别在SAME和VALID模式下输出如下:

ok,调整rate=2,继续运行程序

out_img = tf.nn.atrous_conv2d(value=img, filters=filter, rate=2, padding='SAME')
1
查看输出结果

[[[[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]
[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]]

[[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]
[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]]

[[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]
[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]]

[[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]
[ 16. 16. 16. 16. 16.]
[ 24. 24. 24. 24. 24.]]]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这个结果怎么出来的呢?再用一张图

这里我们看到rate=2时,通过穿插“0”,卷积核由3*3膨胀到了5*5。再看看“VALID”模式下,会发生什么?

直接报错了。因为卷积核的大小已经超过了原图大小

好了,看到这里相信大家对于空洞卷积有了基本的了解了。那么,填充方式为“VALID”时,返回[batch,height-2*(filter_width-1),width-2*(filter_height-1),out_channels]的Tensor,这个结果,相信大家就可以证明了。

代码清单
import tensorflow as tf

img = tf.constant(value=[[[[1],[2],[3],[4]],[[1],[2],[3],[4]],[[1],[2],[3],[4]],[[1],[2],[3],[4]]]],dtype=tf.float32)
img = tf.concat(values=[img,img],axis=3)
filter = tf.constant(value=1, shape=[3,3,2,5], dtype=tf.float32)
out_img1 = tf.nn.atrous_conv2d(value=img, filters=filter, rate=1, padding='SAME')
out_img2 = tf.nn.atrous_conv2d(value=img, filters=filter, rate=1, padding='VALID')
out_img3 = tf.nn.atrous_conv2d(value=img, filters=filter, rate=2, padding='SAME')

#error
#out_img4 = tf.nn.atrous_conv2d(value=img, filters=filter, rate=2, padding='VALID')

with tf.Session() as sess:
print 'rate=1, SAME mode result:'
print(sess.run(out_img1))

print 'rate=1, VALID mode result:'
print(sess.run(out_img2))

print 'rate=2, SAME mode result:'
print(sess.run(out_img3))

# error
#print 'rate=2, VALID mode result:'
#print(sess.run(out_img4))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
TensorFlow实现卷积、反卷积和空洞卷积
阅读数 1532

TensorFlow实现卷积、反卷积和空洞卷积TensorFlow已经实现了卷积(tf.nn.conv2d卷积函数),反卷积(tf.nn.conv2d_transpose反卷积函数)以及空洞卷积(tf...
博文
来自: pan_jinquan的博客

wsdgh: Nice, but `height - [filter_width + (filter_width - 1) * (rate - 1)] + 1` make more sense, when `padding=VALID`.
import tensorflow as tf
import numpy as np

kernel_height = 3
kernel_width = kernel_height

img_height = 9
img_width = img_height
rate = 2
padding = 'VALID'
sz_same = img_height
sz_valid = img_height - ((kernel_height - 1)*(rate - 1) + kernel_height) + 1

img = np.random.randn(1, img_height, img_width, 3)
kernel = np.random.randn(kernel_height, kernel_width, 3, 1)

imgT = tf.constant(img)
kernelT = tf.constant(kernel)

imgO1 = tf.nn.atrous_conv2d(imgT, kernel, rate=rate, padding=padding)
print(imgO1.shape)
print(sz_same if padding.upper() == 'SAME' else sz_valid)
# (1, 5, 5, 1)
# 5

---------------------
作者:xf__mao
来源:CSDN
原文:https://blog.csdn.net/mao_xiao_feng/article/details/78003730
版权声明:本文为博主原创文章,转载请附上博文链接!

【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?膨胀卷积的更多相关文章

  1. 深度学习原理与框架- tf.nn.atrous_conv2d(空洞卷积) 问题:空洞卷积增加了卷积核的维度,为什么不直接使用7*7呢

    空洞卷积, 从图中可以看出,对于一个3*3的卷积,可以通过使用增加卷积的空洞的个数,来获得较大的感受眼, 从第一幅图中可以看出3*3的卷积,可以通过补零的方式,变成7*7的感受眼,这里补零的个数为1, ...

  2. 深度学习原理与框架-图像补全(原理与代码) 1.tf.nn.moments(求平均值和标准差) 2.tf.control_dependencies(先执行内部操作) 3.tf.cond(判别执行前或后函数) 4.tf.nn.atrous_conv2d 5.tf.nn.conv2d_transpose(反卷积) 7.tf.train.get_checkpoint_state(判断sess是否存在

    1. tf.nn.moments(x, axes=[0, 1, 2])  # 对前三个维度求平均值和标准差,结果为最后一个维度,即对每个feature_map求平均值和标准差 参数说明:x为输入的fe ...

  3. [TensorFlow] tf.nn.softmax_cross_entropy_with_logits的用法

    在计算loss的时候,最常见的一句话就是tf.nn.softmax_cross_entropy_with_logits,那么它到底是怎么做的呢? 首先明确一点,loss是代价值,也就是我们要最小化的值 ...

  4. 转置卷积&&膨胀卷积

    Convolution arithmetic tutorial theano Convolution arithmetric github 如何理解深度学习中的deconvolution networ ...

  5. 【Tensorflow】tf.nn.depthwise_conv2d如何实现深度卷积?

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/mao_xiao_feng/article/ ...

  6. tensorflow 之tf.nn.depthwise_conv2d and separable_conv2d实现及原理

    Depthwise Separable Convolution 1.简介 Depthwise Separable Convolution 是谷歌公司于2017年的CVPR中在论文”Xception: ...

  7. TensorFlow使用记录 (二): 理解tf.nn.conv2d方法

    方法定义 tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=True, data_format="NHWC&quo ...

  8. 膨胀卷积与IDCNN

    Dilation 卷积,也被称为:空洞卷积.膨胀卷积. 一.一般的卷积操作: 首先,可以通过动态图,理解正常卷积的过程: 如上图,可以看到卷积操作. 对于CNN结构,通常包括如下部分: 输入层 (in ...

  9. NLP进阶之(七)膨胀卷积神经网络

    NLP进阶之(七)膨胀卷积神经网络1. Dilated Convolutions 膨胀卷积神经网络1.2 动态理解1.2.2 转置卷积动画1.2.3 理解2. Dilated Convolutions ...

随机推荐

  1. php语言的核心知识点

    PHP:脚本语言,网站建设,服务器端运行PHP定义:一种服务器端的 HTML 脚本/编程语言,是一种简单的.面向对象的.解释型的.健壮的.安全的.性能非常之高的.独立于架构的.可移植的.动态的脚本语言 ...

  2. js计算精度问题(浮点数误差,大数计算出错)

    https://github.com/camsong/blog/issues/9 0.1+0.2 //0.30000000000000004 1-0.9 //0.09999999999999998 9 ...

  3. update批量更新某一列成其它列对应的值【原】

    update批量更新某一列成其它列对应的值 postgresql 标准sql语句 update AA set name = BB.name , AA.sex = BB.sex from BB wher ...

  4. Swift 之数组与字典

    http://www.cocoachina.com/swift/20151230/14802.html 说到数组和字典,只要是编过程的小伙伴并不陌生.在Swift中的数组与字典也有着一些让人眼前一亮的 ...

  5. word之图表目录中点号位置提升3磅

  6. ios开发ARC,IBOutlets之strong与weak

    今天在写程序的时候,用IBOutlets连了一个自定义的控件,出现了问题,后面访问的时候,控件里有些subviews没有初始化好,取到的时候为nil, 程序里用了ARC, IBOutlets一连接上, ...

  7. 【JZOJ4761】【NOIP2016提高A组模拟9.7】鼎纹

    题目描述 输入 输出 样例输入 2 3 4 4 2 1100 0110 1100 10 01 10 00 2 2 2 2 11 11 01 10 样例输出 YES NO 数据范围 解法 由于鼎纹中的第 ...

  8. cocos2dx3.0项目创建流程

    cocos2dx3.0不是beta,新增了wp项目创建的支持 但不知道为啥非beta版本号的tools文件夹中取消了project-creator,可能有更改吧 没有这个工具还挺麻烦.就自己手动创建c ...

  9. Directx11教程(42) 纹理映射(12)-简单的bump mapping

    原文:Directx11教程(42) 纹理映射(12)-简单的bump mapping        有时候,我们只有一个粗糙的模型,但是我们想渲染纹理细节,比如一个砖墙,我们如何在只有一个平面的时候 ...

  10. 将数组对象转换成DataSet

    public static DataSet ObjectArrayToDataSet(object[] objArr) { if (objArr.Length == 0) return null; D ...