本文转载自:http://115.com/182920/T1266078.html

机器学习:让我们彻底搞懂CNN

上世纪科学家们发现了几个视觉神经特点,视神经具有局部感受眼,一整张图的识别由多个局部识别点构成;不同神经元对不同形状有识别能力,且视神经具有叠加能力,高层复杂的图案可以由低层简单线条组成。之后人们发现经过conclusional的操作,可以很好反映视神经处理计算的过程,典型的是1998年LeCun发明的LeNet-5,可以极大地提升识别效果。

本文主要就convolutional layer、pooling layer和整体CNN结构展开

一、Convolutional Layer卷积层

1、原理和参数

可以模拟局部感受眼的性质,同上一层不是全连接,而是一小块区域连接,这一小块就是局部感受眼(receptive field)。并且通过构造特定的卷积神经元,可以模拟不同神经元对不同形状刺激不同反应的性质。如下图所示,一个神经元处理一层会形成一个feature map,多层叠加,层数逐渐加深。

感受眼(kernel或filter)的尺寸可以看做fh*fw,由于感受眼本身具有尺寸,feature map会不断缩小,为了处理方便,使得每层大小不变,于是我们每层加值为0的边(zero padding),保证经过处理以后的feature map同前一层尺寸一样。多层之间的卷积运算操作,相当于和原来像素对应位置做乘法。如下左图所示,加了边后可以保证上下层大小一致,右图表示每层之间convolve的操作(如果不加zero padding)。

但上图所示只是简单例子,一般扫描的是三维图像(RGB),就不是一个矩阵,而是一个立方体,我们用一个三维块去扫描它,原理同上图相同。

有时扫描时不是顺序去扫,而是跳跃着扫描,每次移动2-3个像素值(stride),但并非完全分离不会造成信息丢失,这样形成的feature map相较于原始图片缩小,实现信息聚集的效果。

就像如下灰度图(2d)中所示,左边只提取竖线(vertical filter),右边只提取横线(horizontal filter)可看出横梁部分变亮,大量不同的这样的filter(比如可以识别边角、折线的filter)的叠加,可形成多张feature maps

下图是一个3d的RGB效果,每个kernel(filter)可以扫描出一张feature map,多个filter可以叠加出很厚的feature maps,前一层filter做卷积可以形成后一层的一个像素点

如下图,可以代表i行j列k深度的一个输出像素值,k’代表第k个filter,w代表filter中的值,x代表输入,b是偏值。

2、TensorFlow实现

以下是使用TensorFlow实现的代码,主要使用conv2d这个函数

下面是padding的值SAME和VALID的区别(filter的宽度为6,stride为5),SAME确保所有图像信息都被convolve添加zero padding,而VALID只添加包含在内的像素点

3、所耗内存计算

相比于传统的全连接层,卷积层只是部分连接,节省了很多内存。

比如:一个具有5*5大小filter的卷积层,输出200张150*100大小的feature maps,stride取1(即不跳跃),padding为SAME。输入是150*100大小的RGB图像(channel=3),总共的参数个数是200*(5*5*3+1)=15200,其中+1是bias;如果输出采用32-bits float表示(np.float32),那么每张图片会占据200*150*100*32=9600000bits(11.4MB),如果一个training batch包含100张图片(mini-batch=100),那么这一层卷积层就会占据1GB的RAM。

可以看出,训练卷积神经网络是非常消耗内存的,但是使用时,只用到最后一层的输出即可。

二、Pooling Layer池化层

1、原理和参数

当图片大小很大时内存消耗巨大,而Pooling Layer所起的作用是浓缩效果,缓解内存压力。

即选取一定大小区域,将该区域用一个代表元素表示。具体的Pooling有两种,取平均值(mean)和取最大值(max)。如下图所示是一个取最大值的pooling layer,kernel大小为2*2,stride大小取决于kernel大小,这里是2,即刚好使得所有kernel都不重叠的值,因而实现高效的信息压缩,将原始图像横纵压缩一半,如右图所示,特征基本都完全保留了下来。

pooling这个操作不影响channel数,在feature map上也一般不做操作(即z轴一般不变),只改变横纵大小。

2、TensorFlow实现

三、整体CNN框架

典型CNN architecture

有名的CNN架构:

LeNet(MISIT上)-1998:

输入32*32(在28*28图像上加了zero padding)。第一层kernel用了6个神经元,kernel大小5*5,stride取1,输出就是28*28;第二层做了average pooling,2*2的kernel,stride是2,输出就变为原来的一半,不改变feature map数目;第三层放了16个神经元,其他同理;第五层用了120个神经元,5*5的kernel对5*5的输入做卷积,没法再滑动,输出为1*1;F6用120个1*1的输出全连接84个神经元,Out全连接10个神经元,对应手写体识别输出的10个数字。

激活函数前面都用的tanh,是传统CNN中常用的,输出层用了RBF比较特殊,是一个计算距离的方式去判断和目标输出间距离做lost。。

AlexNet-2012:

最早应用于竞赛中,近10%的提高了准确度

输入224*224的彩色图像,C1是个很大的11*11的filter,stride=4。。最后连做3层convolution。。最后输出1000个类的分类结果。

激活函数使用ReLU,这在现今很流行,输出层用的softmax

AlexNet使用了一个小技巧是Local Response Normalization(LRN局部响应归一化)

这种操作可以在传统输出上加一个bias,考虑到近邻的一些输出影响。即一个输出旁边有很牛掰的输出的话,它的输出就会怂了,收到抑制,可以看到,含β的整个项都在分母上。但后来发现,这个技术对分类器的提升也不是很明显,有的就没有用。

GoogleLeNet-2014:

大量应用Inception module,一个输入进来,直接分四步进行处理,这四步处理完后深度直接进行叠加。在不同的尺度上对图片进行操作。大量运用1*1的convolution,可以灵活控制输出维度,可以降低参数数量。

如右图所示,输入是192,使用了9层inception module,如果直接用3*3,5*5参数,可以算一下,之后inception参数数目是非常大的,深度上可以调节,可以指定任意数目的feature map,通过增加深度把维度减下来。inception模块6个参数刚好对应这6个convolution,上面4个参数对应上面4个convolution,加入max pool不会改变feature map数目(如480=128+192+96+64)。

将正确率升高到95-96%,超过人类分辨率,因为image net中但是狗的种类就有很多,人类无法完全一一分辨出。

ReSNet残差网络-2015:

不再直接学习一个目标函数,输入直接跳过中间层直接连到输出上,要学习的是残差f(x),输入跳过中间层直接加到输出上。

好处是:深度模型路径依赖的限制,即gradient向前传导时要经过所有层,如果中间有层死掉了,前面的层就无法得到训练。残差网络不断跳跃,即使中间有的层已经死掉,信息仍旧能够有效流动,使得训练信号有效往回传导。

机器学习:让我们彻底搞懂CNN【转】的更多相关文章

  1. 【机器学习】彻底搞懂CNN

    之前通过各种博客视频学习CNN,总是对参数啊原理啊什么的懵懵懂懂..这次上课终于弄明白了,O(∩_∩)O~ 上世纪科学家们发现了几个视觉神经特点,视神经具有局部感受眼,一整张图的识别由多个局部识别点构 ...

  2. 一天搞懂深度学习-训练深度神经网络(DNN)的要点

    前言 这是<一天搞懂深度学习>的第二部分 一.选择合适的损失函数 典型的损失函数有平方误差损失函数和交叉熵损失函数. 交叉熵损失函数: 选择不同的损失函数会有不同的训练效果 二.mini- ...

  3. 彻底搞懂Javascript的“==”

    本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...

  4. 完全搞懂傅里叶变换和小波(2)——三个中值定理<转载>

    书接上文,本文章是该系列的第二篇,按照总纲中给出的框架,本节介绍三个中值定理,包括它们的证明及几何意义.这三个中值定理是高等数学中非常基础的部分,如果读者对于高数的内容已经非常了解,大可跳过此部分.当 ...

  5. 完全搞懂傅里叶变换和小波(1)——总纲<转载>

    无论是学习信号处理,还是做图像.音视频处理方面的研究,你永远避不开的一个内容,就是傅里叶变换和小波.但是这两个东西其实并不容易弄懂,或者说其实是非常抽象和晦涩的! 完全搞懂傅里叶变换和小波,你至少需要 ...

  6. 不想再被鄙视?那就看进来! 一文搞懂Python2字符编码

    程序员都自视清高,觉得自己是创造者,经常鄙视不太懂技术的产品或者QA.可悲的是,程序员之间也相互鄙视,程序员的鄙视链流传甚广,作为一个Python程序员,自然最关心的是下面这幅图啦 我们项目组一值使用 ...

  7. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

  8. java线程间通信:一个小Demo完全搞懂

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...

  9. for语句,你真正搞懂了吗?

    今天看书时,无意间看到了这个知识点,啥知识点?也许在各位大神看来,那是再简单不过的东西了. 说来惭愧.原来直到今天我才真正搞懂for语句. for语句的结构如下所示: for(语句A;语句B;语句C) ...

随机推荐

  1. R语言中的MySQL操作

    R语言中,针对MySQL数据库的操作执行其实也有很多中方式.本人觉得,熟练掌握一种便可,下面主要就个人的学习使用情况,总结其中一种情况-----使用RMySQL操作数据库. 1.下载DBI和RMySQ ...

  2. MapReduce分布式编程框架

    一.MapReduce分布式编程框架及yarn集群搭建 1.大数据解决的问题? 海量数据的存储:hadoop->分布式文件系统HDFS 海量数据的计算:hadoop->分布式计算框架Map ...

  3. 解决iOS xcode打包unknown error -1=ffffffffffffffff错误

    # 网上很多文档说重启机器,清除缓存什么的,纯属扯淡,都是相互复制粘贴,经测验在stackoverflow找到以下解决方法,亲测可用security unlock-keychain -p " ...

  4. 7.Git工作区和暂存区

    Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念. 先来看名词解释. 1.工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的test文件夹就是一个工作区 ...

  5. SQL学习笔记。

    数据库视图: 视图是虚表,是从一个或几个基本表(或视图)中导出的表,在系统的数据字典中仅存放了视图的定义,不存放视图对应的数据. 视图是原始数据库数据的一种变换,是查看表中数据的另外一种方式.可以将视 ...

  6. OpenCV膨胀与腐蚀

    膨胀与腐蚀 本篇博客主要介绍使用OpenCV中的函数接口实现对一个图片的腐蚀或者膨胀,听起来有点像是对图像进行放大和缩小的意思,如果你也是这样认为,那我只能说你跟我一样肤浅!!在OpenCV中几乎所有 ...

  7. spring MVC学习(三)

    1. @RequestMapping: 在请求的路径中传递参数:参数作为路径的一部分,可以在路径中直接使用 {paramName}来表示,另一种就是更加传统的表示方式?paramName=paramV ...

  8. oracle 查看隐藏参数

    隐藏参数 (hidden parameters) ,由oracle内部使用,以 '_' 开头. 可以通过以下两种方式查看所有隐藏参数: SELECT   i.ksppinm name, i.ksppd ...

  9. Selenium2.0 Webdriver 随笔

    Webdriver can't action the element when the element is out of view 1. Scroll to the element use Java ...

  10. php处理restful请求的路由(转载 http://www.jb51.net/article/47333.htm)

    <?php    class Router {        // 路由表        private $routers = array(            array("nam ...