CNN中的卷积核及TensorFlow中卷积的各种实现

声明:

1. 我和每一个应该看这篇博文的人一样,都是初学者,都是小菜鸟,我发布博文只是希望加深学习印象并与大家讨论。

2. 我不确定的地方用了“应该”二字

首先,通俗说一下,CNN的存在是为了解决两个主要问题:

1. 权值太多。这个随便一篇博文都能解释

2. 语义理解。全连接网络结构处理每一个像素时,其相邻像素与距离很远的像素无差别对待,并没有考虑图像内容的空间结构。换句话说,打乱图像像素的输入顺序,结果不变。

然后,CNN中的卷积核的一个重要特点是它是需要网络自己来学习的。这一点很简单也很重要:一般的卷积核如sobel算子、平滑算子等,都是人们根据数学知识得到的,比如求导,平均等等。所以一般的人工卷积核是不能放进卷积层的,这有悖于“学习”的概念。我们神经网络就是要自己学习卷积核的参数。来提取人们想不到甚至是无法理解的空间结构或特征。其他特征包括全局共享(一个卷积核滑动一整张图像),多核卷积(用一个卷积核只能提取一种空间结构或特征)。

最后,说一说TensorFlow中卷积的各种实现API(经常用到的):

import tensorflow as tf #自己去加,下面用tf代替tensorflow模块

1  tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, Name=None)

#输入:

# input: 一个张量。数据类型必须是float32或者float64。记住这个张量为四维[batch, in_height, in_width, in_channels],batch应该是指每次feed给网络的数据的个数,和mini-batch gradient descend有关;中间是长宽两项;最后是通道,灰度为1,RGB等为3

# filter: 输入的卷积核,也是四维[filter_height,filter_width,in_channels,channel_multiplier],前两维是尺寸比如3x3,2x2(注意是可以2x2的,这个涉及到非对称卷积核),第三维等于 in_channels,第四维是输出通道数,也就是你要输出的通道数,也就是你要使用的卷积核数

# strides: 一个长度是4的一维整数类型的数组,一般设为[1,1,1,1],注意第一个和第四个"1”固定不变(我试过改了结果不变,并且没有意义)中间的两个1,就是横向步长和纵向步长,意思是卷积核不一定是一步一步的滑动的。

# padding: 有两个值‘SAME’和'VALID',前者使得卷积后图像尺寸不变;后者尺寸变化

# use_cudnn_on_gpu: 在gpu上处理,tensorflow-gpu都默认设为了True

# data_format=None, Name=None 这两项请博友们自己查查,应该问题不大,Name应该与TensorFlow的图结构以及Session(会话)有关系;data_format的默认值应该为'NHWC',及张量维度的顺序应该是batch个数,高度,宽度和通道数。

可以说, tf.nn.conv2d就是处理的典型的卷积,例子和图示如下:

1 input_data =tf.Variable(np.random.rand(10,9,9,3),dtype=np.float32)
2 filter_data = tf.Variable(np.random.rand(2,2,3,2),dtype=np.float32)
3 y = tf.nn.conv2d(input_data,filter_data,strides=[2,5,5,3],padding='SAME') #中间5,5大家自己设置一下,自己感受
4 y.shape

结果是 TensorShape([Dimension(10), Dimension(2), Dimension(2), Dimension(2)])

2  tf.nn.depthwise_conv2d(input, filter, strides, padding, rate=None, name=None, data_format=None)

与1的不同有有两点:

1. depthwise_conv2d将不同的卷积核独立地应用在in_channels的每个通道:我们一般对于三通道图像做卷积,都是先加权求和再做卷积(注意先加权求和再卷积与先卷积再加权求和结果一样),形象化描述就是我先把3通道压扁成1通道,在把它用x个卷积核提溜成x通道(或者我先把3通道用x个卷积核提溜成3x个通道,再分别压扁得到x通道); 而depthwise_conv2d就不加权求和了,直接卷积,所以最后输出通道的总数是in_channels*channel_multiplier

2. rate参数是一个1维向量,of size 2,由两个元素组成,这个参数与atrous convolution(孔卷积)和感受野有关,我下面会给出参考链接。注意, If it is greater than 1, then all values of strides must be 1.

3 tf.nn.separable_conv2d(input, depthwise_filter, pointwise_filter, strides, padding, rate=None, name=None, data_format=None)

#特殊参数:

# depthwise_filter。一个张量,数据维度是四维[filter_height,filter_width,in_channels,channel_multiplier],如1中所述,但是卷积深度是1,如2中所述。

# pointwise_filter。一个张量,数据维度是四维[1,1,in_channels*channel_multiplier,out_channel]

tf.nn.separable_conv2d是利用几个分离的卷积核去做卷积。首先用depthwise_filter做卷积,效果与depthwise_conv2d相同,然后用1x1的卷积核pointwise_filter去做卷积。实例图如下:

这个理解困难就是最后一步,pointwise_filter是什么?需要说明的是,我只知道原理,我还不知道这样做的目的是什么。最后pointwise原理很简单,就和2中我说过的一样,我先把DM*in_channels(即in_channels*channel_multiplier)个通道压扁成1个通道,再用pointwise_filter这个1*1的卷积核提溜成out_channel个通道,所以pointwise_filter相当于out_channel个scalar。

例子如下:

1 1 input_data = tf.Variable(np.random.rand(10,9,9,3),dtype=np.float32)
2 2 depthwise_filter = tf.Variable(np.random.rand(2,2,3,5),dtype=np.float32)
3 3 pointerwise_filter = tf.Variable(np.random.rand(1,1,15,20),dtype=np.float32)
4 4 #out_channels >= channel_multiplier * in_channels
5 5 y =tf.nn.separable_conv2d(input_data, depthwise_filter, pointerwise_filter, strides = [1,1,1,1], padding='SAME')
6 y.shape

结果是 TensorShape([Dimension(10), Dimension(9), Dimension(9), Dimension(20)])

参考资料:

《深度学习原理与Tensorflow实践》
《TensorFlow技术解析与实战》

Tensorflow(API MASTERT),也就是API Documentation

孔卷积或者扩张卷积

图的出处

TensorFlow中卷积的更多相关文章

  1. CNN中的卷积核及TensorFlow中卷积的各种实现

    声明: 1. 我和每一个应该看这篇博文的人一样,都是初学者,都是小菜鸟,我发布博文只是希望加深学习印象并与大家讨论. 2. 我不确定的地方用了"应该"二字 首先,通俗说一下,CNN ...

  2. tensorflow中卷积、转置卷积具体实现方式

    卷积和转置卷积,都涉及到padding, 那么添加padding 的具体方式,就会影响到计算结果,所以搞清除tensorflow中卷积和转置卷积的具体实现有助于模型的灵活部署应用. 一.卷积 举例说明 ...

  3. Tensorflow中卷积的padding方式

    根据tensorflow中的Conv2D函数,先定义几个基本符号: 输入矩阵W*W,这里只考虑输入宽高相等的情况,如果不相等,推导方法一样 filter矩阵F*F,卷积核 stride值S,步长 输出 ...

  4. Tensorflow中的padding操作

    转载请注明出处:http://www.cnblogs.com/willnote/p/6746668.html 图示说明 用一个3x3的网格在一个28x28的图像上做切片并移动 移动到边缘上的时候,如果 ...

  5. 记录:TensorFlow 中的 padding 方式

    TensorFlow 中卷积操作和池化操作中都有一个参数 padding,其可选值有 ['VALID', 'SAME']. 在 TensorFlow 文档中只是给出了输出张量的维度计算方式,但是并没有 ...

  6. CNN中卷积层的计算细节

    原文链接: https://zhuanlan.zhihu.com/p/29119239 卷积层尺寸的计算原理 输入矩阵格式:四个维度,依次为:样本数.图像高度.图像宽度.图像通道数 输出矩阵格式:与输 ...

  7. 在 TensorFlow 中实现文本分类的卷积神经网络

    在TensorFlow中实现文本分类的卷积神经网络 Github提供了完整的代码: https://github.com/dennybritz/cnn-text-classification-tf 在 ...

  8. 第十四节,TensorFlow中的反卷积,反池化操作以及gradients的使用

    反卷积是指,通过测量输出和已知输入重构未知输入的过程.在神经网络中,反卷积过程并不具备学习的能力,仅仅是用于可视化一个已经训练好的卷积神经网络,没有学习训练的过程.反卷积有着许多特别的应用,一般可以用 ...

  9. TensorFlow中的卷积函数

    前言 最近尝试看TensorFlow中Slim模块的代码,看的比较郁闷,所以试着写点小的代码,动手验证相关的操作,以增加直观性. 卷积函数 slim模块的conv2d函数,是二维卷积接口,顺着源代码可 ...

随机推荐

  1. C/C++函数指针声明

    前天看APUE,看到signal的声明竟然是 void (*signal(int,void(*)(int)))(int); 初看下面,还真是看不出这是啥意思.道行太浅,仅仅能看到这样的函数指针 voi ...

  2. [转]Linq使用心得——SelectMany替代二重foreach循环

    本篇记录了Linq学习的心得,较为浅显,各位大牛请轻拍. 学习Linq其实已经很久了,但是一直没有使用的习惯,故水平也始终没有提高.近来刻意强迫自己用Linq来替代C# 2.0的一些写法.这里有一些心 ...

  3. Spring HandlerInterceptor的使用

    http://blog.csdn.net/joeyon1985/article/details/49903761

  4. echarts+百度地图+vue 填坑记(一)(百度地图、鼠标移入移出标注,信息框会产生闪烁)

    大概七月底开始实习,到现在经历了两个完整的项目(c2b). 因为开发时间紧,任务重,所以在开发过程踩到的坑都没时间去记录. 现在在开发一个某链运输监控系统,到了收尾阶段,有时间写博客了!开心! 一.鼠 ...

  5. JS学习笔记 - 透明度运动框

    该练习的笔记如下: 1.  var cur=0;  //先声明一个变量. 2.  parseInt会舍掉小数,而opacity值恰恰是小数,所以对于opacity,必须用parseFloat. cur ...

  6. clear属性来取消浮动

    在非IE浏览器(如Firefox)下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外 ...

  7. 程序员的困境 - R中国用户组-炼数成金

    原文:http://www.oschina.net/news/43389/the-plight-of-programmer 在大型公司中不能腐蚀自己的学习能力和时间能力. 最近我为一个内核程序员的职位 ...

  8. vagrant 的安装与使用

    1. 安装 ubuntu 安装vagrant过程 ubuntu 安装 vagrant 时需要首先安装 virtualbox: (1)下载安装与当前 ubuntu 版本相适应的 virtualbox 安 ...

  9. Android java.lang.IllegalArgumentException: Object returned from onCreateLoader must not be a non-static inn

    AsyncTaskLoader: http://developer.Android.com/intl/zh-CN/reference/android/content/AsyncTaskLoader.h ...

  10. ios获取系统时间

    //获取系统时间 NSDate * date=[NSDate date]; NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init]; ...