Tensorflow快餐教程(9) - 卷积

简介: 卷积的计算方法

卷积

卷积就是滑动中提取特征的过程

在数学中,卷积convolution是一种函数的定义。它是通过两个函数f和g生成第三个函数的一种数学算子,表征函数f与g经过翻转和平移的重叠部分的面积。其定义为:
$h(x)=f(x)*g(x) =\int_{-\infty}^{\infty}f(t)g(x-t)dt$
也可以用星号表示:$h(x)=(f*g)(x)$
卷积的第一个参数(上例中的f),通常叫做输入。第二个参数(函数g)叫做核函数kernel function。输出有时候叫特征映射feature map.
也可以定义离散形式的卷积:
$h(x)=(f*g)(x) = \sum_{t=-\infty}^{\infty}f(t)g(x-t)$

g(x-t)是变化的,而f(t)是固定不动的。我们可以将卷积理解成是g(x-t)滑动过程中对f(t)进行采样。

我们一般可以用$f(x)=wx+b$来作为核函数提取特征

我们来举个小例子说明一下卷积对于特征提取的过程。

假设有一个5*5的矩阵做为输入:

array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]], dtype=float32)

y=wx+b我们取w为3*3的全1矩阵,b=0。
这样我们计算左边第一个3*3的小块,得$1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1+1*1=9$。
以此类推,最后我们得到一个
[[9,9,9],
[9,9,9],
[9,9,9]]
的矩阵。
相当于我们把一个55的黑白矩阵压缩成了33的灰度矩阵。

全是1的话大家看不太清楚,我们选一个对角矩阵再来计算一下:

array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]], dtype=float32)

计算卷积之后的结果为:

[[3,2,1],
[2,3,2],
[1,2,3]]

图像缩小了之后,仍然是主对角线最黑。基本特征还是被提取出来了。

填充Padding

从前面对角线的例子可以看出,由于图片中间的点被计算的次数多,而边缘上的点计算的次数少,所以明明右上角和左下角都是0,提取完特征之后被中间的1给影响了。
我们可以选择给这个55的矩阵外边加上一圈padding,将其变成77的矩阵。

我们再重新计算一下卷积,获取下面一个5*5的新矩阵:

[[2,2,1,0,0],
 [2,3,2,1,0],
 [1,2,3,2,1],
 [0,1,2,3,2],
 [0,0,1,2,2]]

这样边缘的0就被识别出来了。Padding的最主要作用就是让边界变得更清晰。

步幅Stride

上面我们求卷积的时候,每次向右移到一步,这个移动距离就是Stride。
比如我们想把图片压缩得更狠一点,取得更高的压缩率,我们就可以加大步幅。

卷积用Tensorflow实现

上面知识储备已足,我们开始用Tensorflow来计算卷积吧。

首先是输入,按照Tensorflow的要求,我们得把5*5的,resize成[1,5,5,1]格式的,如下:

>>> c
array([[[[1.],
         [0.],
         [0.],
         [0.],
         [0.]],

        [[0.],
         [1.],
         [0.],
         [0.],
         [0.]],

        [[0.],
         [0.],
         [1.],
         [0.],
         [0.]],

        [[0.],
         [0.],
         [0.],
         [1.],
         [0.]],

        [[0.],
         [0.],
         [0.],
         [0.],
         [1.]]]], dtype=float32)

然后我们还需要准备卷积核,先生成一个3*3全1矩阵:

>>> a2 = sess.run(tf.ones([3,3]))
>>> a2
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]], dtype=float32)

然后将其reshape成[3,3,1,1]格式的:

>>> a3 = sess.run(tf.reshape(a2,[3,3,1,1]))
>>> a3
array([[[[1.]],

        [[1.]],

        [[1.]]],


       [[[1.]],

        [[1.]],

        [[1.]]],


       [[[1.]],

        [[1.]],

        [[1.]]]], dtype=float32)

步幅我们设成[1,1,1,1],其实就是x轴1,y轴1,前面和后面的1先不用管它。padding设成'SAME':

>>> a1 = tf.nn.conv2d(c,a3,strides=[1,1,1,1],padding='SAME')
>>> sess.run(a1)
array([[[[2.],
         [2.],
         [1.],
         [0.],
         [0.]],

        [[2.],
         [3.],
         [2.],
         [1.],
         [0.]],

        [[1.],
         [2.],
         [3.],
         [2.],
         [1.]],

        [[0.],
         [1.],
         [2.],
         [3.],
         [2.]],

        [[0.],
         [0.],
         [1.],
         [2.],
         [2.]]]], dtype=float32)

结果看起来不爽的话,我们再重新将其reshape成[5,5]的:

>>> a5 = tf.reshape(a4,[5,5])                               
>>> sess.run(a5)
array([[2., 2., 1., 0., 0.],
       [2., 3., 2., 1., 0.],
       [1., 2., 3., 2., 1.],
       [0., 1., 2., 3., 2.],
       [0., 0., 1., 2., 2.]], dtype=float32)

嗯,是不是跟我们手动计算的一样呢?恭喜你,已经学会卷积啦!

池化层

池化层跟卷积也很像,但是计算要简单得多。池化主要有两种,一种是取最大值,一种是取平均值。而卷积是要做矩阵内积运算的。

我们以2*2最大池化为例,处理一下上节加了padding的卷积

[[2,2,1,0,0],
 [2,3,2,1,0],
 [1,2,3,2,1],
 [0,1,2,3,2],
 [0,0,1,2,2]]

最大池化就是取最大值,比如[[2,2],[2,3]]就取3。结果如下:

[[3,3,2,1],
  [3,3,3,2],
  [2,3,3,3],
  [1,2,3,3,]]

可以看到,池化虽然进一步丢失了信息,但是基本规律还是不变的。

池化被认为可以提高泛化性,对于微小的变动不敏感。比如对于少量的平移,旋转或者缩放保持同样的识别。但是,池化层不是必须的。

在Tensorflow中,可以用tf.nn.max_pool来实现最大池功能。

首先我们要把图片resize成(-1,高,宽,1)这样格式的:

>>> b = tf.reshape(a,[-1,5,5,1])
>>> c = sess.run(b)
array([[[[1.],
         [0.],
         [0.],
         [0.],
         [0.]],

        [[0.],
         [1.],
         [0.],
         [0.],
         [0.]],

        [[0.],
         [0.],
         [1.],
         [0.],
         [0.]],

        [[0.],
         [0.],
         [0.],
         [1.],
         [0.]],

        [[0.],
         [0.],
         [0.],
         [0.],
         [1.]]]], dtype=float32)

然后我们用步幅为2。2*2窗口计算max pooling。
命令如下:

d =tf.nn.max_pool(c,ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

四元组中我们不必管第一个和最后一个,中间两个是高和宽。ksize和步幅皆如此。
运行结果是一个3*3的对角阵:

>>> sess.run(d)
array([[[[1.],
         [0.],
         [0.]],

        [[0.],
         [1.],
         [0.]],

        [[0.],
         [0.],
         [1.]]]], dtype=float32)

卷积网络的结构

卷积神经网络也叫卷积网络,是一种善于处理网格数据的网络。典型应用是处理一维网格数据语音和二维网格数据图像。只要是在网络结构中使用了哪怕一层的卷积层,就叫做卷积神经网络。

与之前介绍的神经网络都是全连接网络,即每一层的每个节点都是上一层的所有节点相连接。
而卷积网络一般是五种连接结构的组合:

  1. 输入层:一般认为就是原图片
  2. 卷积层:与全连接网络不同,卷积层中每一个节点的输入只是上一层神经网络的一小块,常用的块大小为33或者55。一般来说,通过卷积层处理过的节点的矩阵的深度会变深
  3. 池化层:Pooling层不会改变矩阵的深度,但是会使矩阵变小。可以理解为池化层是把高分辨率的图片转化成低分辨率的图片
  4. 全连接层:最后的分类工作一般还是由一至两个全连接层来实现的。
  5. Softmask层:可以得到当前样例属于不同分类的概率情况

卷积网络简史

上节深度学习简史中我们提到过,第一个卷积网络模型于1989年由Yann LeCun提出。卷积网络的主要概念如为什么要卷积,为什么要降采样,什么是径向基函数RBF(Radial Basis Function)等。
10年后的1998年,Yann LeCun设计了LeNet网络。在论文《Gradient-Based Learning Applied to Document Recognition》中提出了LeNet-5的模型,结构如下:
LeNet-5
论文原文在:http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf

但是,正如我们前面介绍的,当时还是SVM辉煌的时代。
转折点要到十几年后的2012年,Hinton的学生Alex Krizhevsky发明的AlexNet之时。AlexNet在2012年的图像分类竞赛中将Top-5错误率从上一年的25.8%降到15.3%.

AlexNet成功之后,大家的研究热情空前高涨。主要方向有网络加深和功能增强。

  1. 网络加深:深度学习的优势就是突破了加深层数的关键点。那么就可以构建比AlexNet层数更多的网络。代表作是2014年ImageNet比赛的亚军牛津大学的VGGNet,它的层数可以达到16~19层。从而将Top-5错误率从AlexNet的15.3%降到了7.32%.
  2. 功能增强:代表作是GoogLeNet。GoogLeNet参考了NIN(Network In Network)的思想,将原来的线性卷积层改成了多层感知机。同时,将全连接层改进为全局平均池化。功能增强之后,GoogLeNet力压VGGNet,获得2014年ImageNet的冠军,将Top-5错误率降到6.67%. 虽然功能有增强,但是在层数上GoogLeNet也毫没客气地增加到22层。后来在GoogLeNet的基础上又推出Inception V3, V4等网络。
  3. 既加深也增强:代表作是2015年的ImageNet分类冠军,由微软亚洲研究院发明的ResNet残差网络。ResNet在2015年的成绩把错误率降到3.57%.

话说ImageNet真是个群英荟萃的地方。2012年第一名是Alex。2013的第一名是Matthew Zeiler,之前讲过他提出的AdaGrad。
值得一提的是,在最近几年的ImageNet中,华人屡创佳绩。比如2016年的冠军被公安部第三研究所搜神团队获得,成绩是错误率2.99%。

目录
相关文章
|
6月前
|
机器学习/深度学习 算法 TensorFlow
文本分类识别Python+卷积神经网络算法+TensorFlow模型训练+Django可视化界面
文本分类识别Python+卷积神经网络算法+TensorFlow模型训练+Django可视化界面
117 0
文本分类识别Python+卷积神经网络算法+TensorFlow模型训练+Django可视化界面
|
6月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
|
2月前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
82 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
5月前
|
机器学习/深度学习 人工智能 算法
海洋生物识别系统+图像识别+Python+人工智能课设+深度学习+卷积神经网络算法+TensorFlow
海洋生物识别系统。以Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经网络算法,通过对22种常见的海洋生物('蛤蜊', '珊瑚', '螃蟹', '海豚', '鳗鱼', '水母', '龙虾', '海蛞蝓', '章鱼', '水獭', '企鹅', '河豚', '魔鬼鱼', '海胆', '海马', '海豹', '鲨鱼', '虾', '鱿鱼', '海星', '海龟', '鲸鱼')数据集进行训练,得到一个识别精度较高的模型文件,然后使用Django开发一个Web网页平台操作界面,实现用户上传一张海洋生物图片识别其名称。
175 7
海洋生物识别系统+图像识别+Python+人工智能课设+深度学习+卷积神经网络算法+TensorFlow
|
5月前
|
机器学习/深度学习 人工智能 算法
【乐器识别系统】图像识别+人工智能+深度学习+Python+TensorFlow+卷积神经网络+模型训练
乐器识别系统。使用Python为主要编程语言,基于人工智能框架库TensorFlow搭建ResNet50卷积神经网络算法,通过对30种乐器('迪吉里杜管', '铃鼓', '木琴', '手风琴', '阿尔卑斯号角', '风笛', '班卓琴', '邦戈鼓', '卡萨巴', '响板', '单簧管', '古钢琴', '手风琴(六角形)', '鼓', '扬琴', '长笛', '刮瓜', '吉他', '口琴', '竖琴', '沙槌', '陶笛', '钢琴', '萨克斯管', '锡塔尔琴', '钢鼓', '长号', '小号', '大号', '小提琴')的图像数据集进行训练,得到一个训练精度较高的模型,并将其
67 0
【乐器识别系统】图像识别+人工智能+深度学习+Python+TensorFlow+卷积神经网络+模型训练
|
4天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
12 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
2月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
92 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
16天前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
38 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
2月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
86 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
3月前
|
机器学习/深度学习 人工智能 算法
【眼疾病识别】图像识别+深度学习技术+人工智能+卷积神经网络算法+计算机课设+Python+TensorFlow
眼疾识别系统,使用Python作为主要编程语言进行开发,基于深度学习等技术使用TensorFlow搭建ResNet50卷积神经网络算法,通过对眼疾图片4种数据集进行训练('白内障', '糖尿病性视网膜病变', '青光眼', '正常'),最终得到一个识别精确度较高的模型。然后使用Django框架开发Web网页端可视化操作界面,实现用户上传一张眼疾图片识别其名称。
79 9
【眼疾病识别】图像识别+深度学习技术+人工智能+卷积神经网络算法+计算机课设+Python+TensorFlow