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就是处理的典型的卷积,例子和图示如下:
input_data =tf.Variable(np.random.rand(10,9,9,3),dtype=np.float32)
filter_data = tf.Variable(np.random.rand(2,2,3,2),dtype=np.float32)
y = tf.nn.conv2d(input_data,filter_data,strides=[2,5,5,3],padding='SAME') #中间5,5大家自己设置一下,自己感受
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 input_data = tf.Variable(np.random.rand(10,9,9,3),dtype=np.float32)
2 depthwise_filter = tf.Variable(np.random.rand(2,2,3,5),dtype=np.float32)
3 pointerwise_filter = tf.Variable(np.random.rand(1,1,15,20),dtype=np.float32)
4 #out_channels >= channel_multiplier * in_channels
5 y =tf.nn.separable_conv2d(input_data, depthwise_filter, pointerwise_filter, strides = [1,1,1,1], padding='SAME')
y.shape
结果是 TensorShape([Dimension(10), Dimension(9), Dimension(9), Dimension(20)])
参考资料:
《深度学习原理与Tensorflow实践》
《TensorFlow技术解析与实战》
Tensorflow(API MASTERT),也就是API Documentation
CNN中的卷积核及TensorFlow中卷积的各种实现的更多相关文章
- TensorFlow中卷积
CNN中的卷积核及TensorFlow中卷积的各种实现 声明: 1. 我和每一个应该看这篇博文的人一样,都是初学者,都是小菜鸟,我发布博文只是希望加深学习印象并与大家讨论. 2. 我不确定的地方用了“ ...
- python/numpy/tensorflow中,对矩阵行列操作,下标是怎么回事儿?
Python中的list/tuple,numpy中的ndarrray与tensorflow中的tensor. 用python中list/tuple理解,仅仅是从内存角度理解一个序列数据,而非数学中标量 ...
- tensorflow中的卷积和池化层(一)
在官方tutorial的帮助下,我们已经使用了最简单的CNN用于Mnist的问题,而其实在这个过程中,主要的问题在于如何设置CNN网络,这和Caffe等框架的原理是一样的,但是tf的设置似乎更加简洁. ...
- Tensorflow中使用CNN实现Mnist手写体识别
本文参考Yann LeCun的LeNet5经典架构,稍加ps得到下面适用于本手写识别的cnn结构,构造一个两层卷积神经网络,神经网络的结构如下图所示: 输入-卷积-pooling-卷积-pooling ...
- 在 TensorFlow 中实现文本分类的卷积神经网络
在TensorFlow中实现文本分类的卷积神经网络 Github提供了完整的代码: https://github.com/dennybritz/cnn-text-classification-tf 在 ...
- 第十四节,TensorFlow中的反卷积,反池化操作以及gradients的使用
反卷积是指,通过测量输出和已知输入重构未知输入的过程.在神经网络中,反卷积过程并不具备学习的能力,仅仅是用于可视化一个已经训练好的卷积神经网络,没有学习训练的过程.反卷积有着许多特别的应用,一般可以用 ...
- TensorFlow中的卷积函数
前言 最近尝试看TensorFlow中Slim模块的代码,看的比较郁闷,所以试着写点小的代码,动手验证相关的操作,以增加直观性. 卷积函数 slim模块的conv2d函数,是二维卷积接口,顺着源代码可 ...
- 【深度学习】CNN 中 1x1 卷积核的作用
[深度学习]CNN 中 1x1 卷积核的作用 最近研究 GoogLeNet 和 VGG 神经网络结构的时候,都看见了它们在某些层有采取 1x1 作为卷积核,起初的时候,对这个做法很是迷惑,这是因为之前 ...
- TensorFlow 中的卷积网络
TensorFlow 中的卷积网络 是时候看一下 TensorFlow 中的卷积神经网络的例子了. 网络的结构跟经典的 CNNs 结构一样,是卷积层,最大池化层和全链接层的混合. 这里你看到的代码与你 ...
随机推荐
- UEditor上传图片到七牛C#(后端实现)
由于个人网站空间存储有所以选择将图片统一存储到七牛上,理由很简单 1 免费10G 的容量 ,对个人网站足够用 2 规范的开发者文档 和完善的sdk(几乎所有热门语言sdk) 整体思路 图片上传七 ...
- JEESZ-kafka消息服务平台实现
JEESZ的消息服务平台已经抛弃了之前的ActiveMQ,改用高吞吐量比较大的Kafka分布式消息中间件方案:JEESZ-kafka消息平台使用spring+kafka的集成方案,详情如下:1. 使用 ...
- Mybatis的mapper文件引起模块划分的思考
起因:项目中将公用的代码抽离到单独一个项目 cms-common.jar (注:公用的代码不只是工具类代码,包含service和dao等) 构建:每次构建项目 cms.war 的时候,需要引入cms- ...
- Android 工程集成React Native 0.44 注意点
当前(2017年5月22日 )React Native开发相当火爆,但是搜索下来,没有最新版本0.44集成的教程,因此尝试了一下如何集成到Android原生工程中去.本篇旨在记录出现的问题以及应对方式 ...
- 写给Android App开发人员看的Android底层知识(4)
(八)App内部的页面跳转 在介绍完App的启动流程后,我们发现,其实就是启动一个App的首页. 接下来我们看App内部页面的跳转. 从ActivityA跳转到ActivityB,其实可以把Activ ...
- Flight学习(一)
翻看git时看到有新消息提示,点进去第一个就是Flight,那么今天就简单来翻译和了解一下这个框架吧,锻炼下自己的英文文档阅读能力,同时也熟悉下JavaScript.时间太赶,难免出现翻译失误和错误, ...
- nodeJS之路径PATH模块
前面的话 path模块包含一系列处理和转换文件路径的工具集,通过 require('path') 可用来访问这个模块.本文将详细介绍path模块 路径组成 [path.dirname(p)] 返回路径 ...
- javascript基础-DOM原理
解释清楚DOM原理并不是一件容易的事,但是任何一个前端工程师,都必须牢牢掌握它. DOM整体架构: 图解: DOM,即针对XML文档的应用程序编程接口(API).通俗一点说,HTML属于XML的一种, ...
- 【2017-06-01】Linq基础+Lambda表达式实现对数据库的增删改查
一.Linq to sql 类 高集成化的数据库访问技术 使用Linq可以代替之前的Ado.Net.省去了自己敲代码的实体类和数据访问类的大量工作. 实体类: 添加一个Linq to sql 类 -- ...
- laravel中的多对多关系详解
数据表之间是纵横交叉.相互关联的,laravel的一对一,一对多比较好理解,官网介绍滴很详细了,在此我就不赘述啦,重点我记下多对多的关系 一种常见的关联关系是多对多,即表A的某条记录通过中间表C与表B ...