「机器学习」彻底搞懂CNN

作者: 水奈樾 2017-12-05 17:44:31

「机器学习」彻底搞懂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这个函数

  1. import numpy as np 
  2.  
  3. from sklearn.datasets import load_sample_images 
  4.  
  5. Load sample images 
  6.  
  7. dataset = np.array(load_sample_images().images, dtype=np.float32) 
  8.  
  9. # 一共4维,channel表示通道数,RGB是3 
  10.  
  11. batch_size, height, width, channels = dataset.shape 
  12.  
  13. Create 2 filters 
  14.  
  15. # 一般感受眼大小7*7,5*5,3*3,设置2个kernel,输出2层feature map 
  16.  
  17. filters_test = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32) 
  18.  
  19. # 第一个(0)filter的设定,7*7矩阵中,3是中间 
  20.  
  21. filters_test[:, 3, :, 0] = 1 # vertical line 
  22.  
  23. # 第二个(1)filter的设定 
  24.  
  25. filters_test[3, :, :, 1] = 1 # horizontal line 
  26.  
  27. # a graph with input X plus a convolutional layer applying the 2 filters 
  28.  
  29. X = tf.placeholder(tf.float32, shape=(None, height, width, channels)) 
  30.  
  31. # 虽然输入是一个四维图像,但是由于batch_size和channel都已经固定,所以使用conv2d 
  32.  
  33. # strides设定,第一个和第四个都是1表示不可以跳过batch_size和channel 
  34.  
  35. # 那两个2表示横纵向都缩减2,相当于整张图片缩减为原来四分之一,做了75%的缩减 
  36.  
  37. convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], padding="SAME"
  38.  
  39. with tf.Session() as sess: 
  40.  
  41.     output = sess.run(convolution, feed_dict={X: dataset}) 

下面是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实现

  1. Create a graph with input X plus a max pooling layer 
  2.  
  3. X = tf.placeholder(tf.float32, shape=(None, height, width, channels)) 
  4.  
  5. # 选用取最大值的max_pool方法 
  6.  
  7. # 如果是取平均值,这里是mean_pool 
  8.  
  9. # ksize就是kernel大小,feature map和channel都是1,横向纵向是2 
  10.  
  11. max_pool = tf.nn.max_pool(X, ksize=[1,2,2,1], strides=[1,2,2,1],padding="VALID"
  12.  
  13. with tf.Session() as sess: 
  14.  
  15.     output = sess.run(max_pool, feed_dict={X: dataset}) 

三、整体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 卷积层
上一篇:深度学习也解决不掉语音识别问题 下一篇:深度学习和普通机器学习之间有何区别?
评论
取消
暂无评论,快去成为第一个评论的人吧

更多资讯推荐

高位截瘫患者重新行走:靠意念指挥外骨骼,法国脑机接口新突破

依靠介入头部的 2 个传感器,法国里昂的一名瘫痪男子 Thibault 实现了操控外骨骼装备来助力行走。

孙滔 ·  23h前
2008 年预测 2020 年生活方式:基本都实现了

美国皮尤研究中心曾在 2008 年预测 2020 年的生活方式,目前来看,该研究的预测基本已经实现。而对于未来 10 年,也就是 2030 年左右人们的生活,在 2017 年底的世界经济论坛上,800 多名信息和通讯技术领域的技术高管和专家给出了如下预测。

佚名 ·  23h前
机器学习的正则化是什么意思?

正则化的好处是当特征很多时,每一个特征都会对预测y贡献一份合适的力量;所以说,使用正则化的目的就是为了防止过拟合。

佚名 ·  23h前
为什么我的CV模型不好用?没想到原因竟如此简单……

机器学习专家 Adam Geitgey 近日发布了一篇文章探讨了这一简单却又让很多人头痛的问题,并分享了他为解决这一问题编写的自动图像旋转程序。

机器之心 ·  1天前
机器学习与预测分析的区别在何处? 精选

如今,认知学习的应用比以往更为普遍。通常意义上讲,认知学习与认知计算就是涉及AI技术与信号处理的操作过程或技术平台。

读芯术 ·  1天前
大盘点:8月Github上7个值得关注的数据科学项目

本文带你来看看GitHub上创建于2019年8月的7个数据科学项目。笔者所选项目的范围十分广泛,涉及从机器学习到强化学习的诸多领域。

读芯术 ·  1天前
非监督学习最强攻略

本次主要讲解的内容是机器学习里的非监督学习经典原理与算法,非监督,也就是没有target(标签)的算法模型。

SAMshare ·  1天前
PyTorch终于能用上谷歌云TPU,推理性能提升4倍,该如何薅羊毛?

Facebook在PyTorch开发者大会上正式推出了PyTorch 1.3,并宣布了对谷歌云TPU的全面支持,而且还可以在Colab中调用云TPU。

晓查 ·  2天前
Copyright©2005-2019 51CTO.COM 版权所有 未经许可 请勿转载