一. CNN简介
CNN(卷积神经网络)是传统神经网络的变种,CNN在传统神经网络的基础上,引入了卷积和pooling。与传统的神经网络相比,CNN更适合用于图像中,卷积和图像的局部特征相对应,pooling使得通过卷积获得的feature具有空间不变性
1、模型架构
这部分讲述如何去构建一个分级的特征提取和分类系统。分级通过堆叠一个或者多个特征提取阶段,每个阶段包括一个滤波器组合层、非线性变换层和一个pooling层,pooling层通过组合(取平均或者最大的)局部邻域的滤波器响应,因而达到对微小变形的不变性。
1)、滤波器组层Filter Bank Layer-FCSG:
FCSG一般包括三部分:一组卷积滤波器(C)、再接一个sigmoid/tanh非线性变换函数(S),然后是一个可训练的增益系数(G)。分别对应下面的三个运算:
2)、校正层Rectification Layer-Rabs:
只是简单的一个取绝对值的操作(如果是tanh,则存在负的值,但在图像中负值是不表示的,而对于卷积来说,里面的都是绝对值越大,非线性函数输出的绝对值最大,实际意义是一样的。卷积是越相似,输出值越大)。除了绝对值算子外,我们还试过了其他的非线性算子,产生的效果差不多。
3)、局部对比度归一化层Local Contrast Normalization Layer-N:
该模块主要进行的是局部做减和做除归一化,它会迫使在特征map中的相邻特征进行局部竞争,还会迫使在不同特征maps的同一空间位置的特征进行竞争。在一个给定的位置进行减法归一化操作,实际上就是该位置的值减去邻域各像素的加权后的值,权值是为了区分与该位置距离不同影响不同,权值可以由一个高斯加权窗来确定。除法归一化实际上先计算每一个特征maps在同一个空间位置的邻域的加权和的值,然后取所有特征maps这个值的均值,然后每个特征map该位置的值被重新计算为该点的值除以max(那个均值,该点在该map的邻域的加权和的值)。分母表示的是在所有特征maps的同一个空间邻域的加权标准差。哦哦,实际上如果对于一个图像的话,就是均值和方差归一化,也就是特征归一化。这个实际上是由计算神经科学模型启发得到的。
4)、平均池化和子采样层Average Pooling and Subsampling Layer -PA:
该层的作用是使得提取的特征对微小变形鲁棒,和视觉感知中的复杂细胞的角色差不多。采样窗口所有值取平均得到下采样层的值。
5)、最大值池化和子采样层Max-Pooling and Subsampling Layer -PM:
可以用任何一种对称的pooling操作实现对提取的特征的平移不变性。最大池与平均池相似,只是最大取代了平均。一般来说,池化窗口是不重叠的。
2、实验与结论
1)滤波器组后面接的non-linearities非线性算法是如何影响识别的准确性的?
俺们的实验结论是,简单的矫正过的非线性算子会提高识别性能。原因可能有二:
a)特征的对立polarity(也就是负值的特征)和目标的识别是无关的。
b)在采用平均池化的时候,矫正层的添加会消去邻近的滤波器输出之间的cancellations,因为如果没有矫正,平均下采样只会传播输入的噪声。另外,局部归一化层也会增加性能,因为它可以使监督学习算法更快,也许是因为所有的变量都具有相似的方差了(与其他白化和去相关的方法的优点一样),这样会加快收敛速度。
2)通过监督或者非监督方式学习到的滤波器组是否比随机的滤波器组或者人工指定的滤波器要好?
实验结果很惊喜,在两级系统中采样随机滤波器组在Caltech-101中居然达到了挺高的62.9%的识别率,但在NORB数据库中就显得有点低调了,可能这种情况只会在训练样本集较少的时候才出现。另外,非监督预训练接个监督微调会有最好的效果,尽管比单纯的全部使用监督会差点。
3)与仅有一级的特征提取对比,两级的特征提取是否还有其他优点?
实验证明,两级比一级好。我们这里,两级系统的性能和最好的一级系统的性能:SIFT特征+PMK-SVM分类器相媲美,也许PM Kernel还隐藏着实现了我们的第二级特征提取的功能。
3、关于local contract normalization
local contract normalization这个归一化包括两个部分:局部做减和局部做除
我的理解:自然图像存在低阶和高阶的统计特征,低阶(例如二阶)的统计特征是满足高斯分布的,但高阶的统计特性是非高斯分布。图像中,空间上相邻的像素点有着很强的相关性。而对于PCA来说,因为它是对协方差矩阵操作,所以可以去掉输入图像的二阶相关性,但是却无法去掉高阶相关性。而有人证明了除以一个隐含的变量就可以去除高阶相关性。你可以理解为一张图像x的像素值是一个随机变量,它由两个独立的随机变量相乘得到,分别是二阶量和高阶量相乘,二阶量的相关性可以由PCA去掉,然后高阶量(这个是隐含的,需要通过MAP最大后验估计等方法估计出来)直接用x除掉就好了。
对输入图像的每一个像素,我们计算其邻域(例如3x3窗口)的均值,然后每个像素先减去这个均值,再除以这个邻域窗口(例如3x3窗口)拉成的9维向量的欧几里德范数(如果这个范数大于1的时候才除:这个约束是为了保证归一化只作用于减少响应(除以大于1的数值变小),而不会加强响应(除以小于1的数值变大))。也有论文在计算均值和范数的时候,都加入了距离的影响,也就是距离离该窗口中心越远,影响越小,例如加个高斯权重窗口(空间上相邻的像素点的相关性随着距离变大而变小)。
1. 数据预处理
在训练神经网络前一般需要对数据进行预处理,一种重要的预处理手段是归一化处理。下面简要介绍归一化处理的原理与方法。
(1) 什么是归一化?
数据归一化,就是将数据映射到[0,1]或[-1,1]区间或更小的区间,比如(0.1,0.9) 。
(2) 为什么要归一化处理?
<1>输入数据的单位不一样,有些数据的范围可能特别大,导致的结果是神经网络收敛慢、训练时间长。
<2>数据范围大的输入在模式分类中的作用可能会偏大,而数据范围小的输入作用就可能会偏小。
<3>由于神经网络输出层的激活函数的值域是有限制的,因此需要将网络训练的目标数据映射到激活函数的值域。例如神经网络的输出层若采用S形激活函数,由于S形函数的值域限制在(0,1),也就是说神经网络的输出只能限制在(0,1),所以训练数据的输出就要归一化到[0,1]区间。
<4>S形激活函数在(0,1)区间以外区域很平缓,区分度太小。例如S形函数f(X)在参数a=1时,f(100)与f(5)只相差0.0067。
2. Pooling 池化层(降采样过程)
最常用的Maxpooling. 解决了两个问题:
1. 减少计算量
2. 旋转不变性 (原因自己悟)
PS:对于旋转不变性,回忆下SIFT,LBP:采用主方向;HOG:选择不同方向的模版
Maxpooling的降采样过程会将feature map的长宽各减半。(下面结果图中没有体现出来,python自动给拉到一样大了,但实际上像素数是减半的
1.ReLU非线性特征
一句话概括:不用simgoid和tanh作为激活函数,而用ReLU作为激活函数的原因是:加速收敛。
因为sigmoid和tanh都是饱和(saturating)的。何为饱和?个人理解是把这两者的函数曲线和导数曲线plot出来就知道了:他们的导数都是倒过来的碗状,也就是,越接近目标,对应的导数越小。而ReLu的导数对于大于0的部分恒为1。于是ReLU确实可以在BP的时候能够将梯度很好地传到较前面的网络。
ReLU(线性纠正函数)取代sigmoid函数去激活神经元
1. Convolution(卷积)
在图像处理中,对图像用一个卷积核进行卷积运算,实际上是一个滤波的过程。下面是卷积的数学表示:
f(x,y)是图像上点(x,y)的灰度值,w(x,y)则是卷积核,也叫滤波器。卷积实际上是提供了一个权重模板,这个模板在图像上滑动,并将中心依次与图像中每一个像素对齐,然后对这个模板覆盖的所有像素进行加权,并将结果作为这个卷积核在图像上该点的响应。如下图所示,卷积操作可以用来对图像做边缘检测,锐化,模糊等。
2、卷积神经网络
卷积神经网络是一个多层的神经网络,每层都是一个变换(映射),常用卷积convention变换和pooling池化变换,每种变换都是对输入数据的一种处理,是输入特征的另一种特征表达;每层由多个二维平面组成,每个平面为各层处理后的特征图(feature map)。
高帧率扑克牌识别技术详解(可用于车牌识别,字符识别,人脸检测,验证码识别等等成熟领域)
本文主要介绍目前主流的adaboost目标检测算法,和CNN卷积神经网络字符识别算法。以扑克牌识别技术为题介绍相关的开发流程和经验。
整个系统包括,
1、摄像头采集,这里以USB摄像头通过directShow采集为例进行介绍。一个线程做采集,一个线程做检测识别。
2、字符检测正负样本得取。后面会详细介绍怎么在只有视频的情况下,
(1)自己写个鼠标拉框手工割取样本的软件,采用OpenCV的鼠标相应控件很容易实现。
(2)或者通过灰度化,自适应二值化,ROI找轮廓,轮廓筛选,ROI轮廓分割,自动割取样本;
(3)以及通过pictureRelate进行重复高样本自动剔除等等筛选。
准备样本:
正样本:
3、adaboost字符检测:
(1)用adaboost+haar特征训练第2步中得取的样本。
(2)进一步将测试分割出的误识别样本,进行筛选,重复2,3两步。直到获得满意的检测率。
4、识别样本得取
(1)字符识别样本读取,分为0-10,JQK,共14个类别。
(2)花色样本得取,共桃杏梅方四个类。
5、采用CNN组进行样本训练识别。这里为了提高识别率,采用两个CNN分别识别4.1和4.2,采用两个CNN并行思路提升识别速度。
(1)针对4.1的14各类,训练一个CNN分类器;
(2)针对4.2的4各类训练一个CNN分类器。
在介绍系统之前先对本文涉及的两大算法做简要的介绍:
1、adaboost算法实例介绍,这里不上理论,直接来实例对照着学boosting的思路。
2、CNN算法详细介绍。
1. 输入图像是32x32的大小,局部滑动窗的大小是5x5的,由于不考虑对图像的边界进行拓展,则滑动窗将有28x28个不同的位置,也就是C1层的大小是28x28。这里设定有6个不同的C1层,每一个C1层内的权值是相同的。
2. S2层是一个下采样层(这个过程也叫Pool)。简单的说,由2*2=4个点下采样为1个点,也就是4个数的加权平均。但在LeNet-5系统,下采样层比较复杂,因为这4个加权系数也需要学习得到,这显然增加了模型的复杂度。
在斯坦福关于深度学习的教程中,这个过程叫做Pool。
3. 根据对前面C1层同样的理解,我们很容易得到C3层的大小为10x10. 只不过,C3层的变成了16个10x10网络! 试想一下,如果S2层只有1个平面,那么由S2层得到C3就和由输入层得到C1层是完全一样的。但是,S2层由多层,那么,我们只需要按照一定的顺利组合这些层就可以了。具体的组合规则,在 LeNet-5 系统中给出了下面的表格:
简单的说,例如对于C3层第0张特征图,其每一个节点与S2层的第0张特征图,第1张特征图,第2张特征图,总共3个5x5个节点相连接。后面依次类推,C3层每一张特征映射图的权值是相同的。
4. S4 层是在C3层基础上下采样,前面已述。在后面的层由于每一层节点个数比较少,都是全连接层
1.C1层是一个卷积层(为什么是卷积?卷积运算一个重要的特点就是,通过卷积运算,可以使原信号特征增强,并且降低噪音),由6个特征图Feature Map构成。特征图中每个神经元与输入中5*5的邻域相连。特征图的大小为28*28,这样能防止输入的连接掉到边界之外(是为了BP反馈时的计算,不致梯度损失,个人见解)。C1有156个可训练参数(每个滤波器5*5=25个unit参数和一个bias参数,一共6个滤波器,共(5*5+1)*6=156个参数),共156*(28*28)=122,304个连接。---->这一段作者说的很清楚,不用多说了
2.S2层是一个下采样层(为什么是下采样?利用图像局部相关性的原理,对图像进行子抽样,可以减少数据处理量同时保留有用信息),有6个14*14的特征图。特征图中的每个单元与C1中相对应特征图的2*2邻域相连接。S2层每个单元的4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。结果通过sigmoid函数计算。可训练系数和偏置控制着sigmoid函数的非线性程度。如果系数比较小,那么运算近似于线性运算,亚采样相当于模糊图像。如果系数比较大,根据偏置的大小亚采样可以被看成是有噪声的“或”运算或者有噪声的“与”运算。每个单元的2*2感受野并不重叠,因此S2中每个特征图的大小是C1中特征图大小的1/4(行和列各1/2)。S2层有12个可训练参数和5880个连接。
---->6个2*2的小方框,每个有一个参数,加上一个偏置,也就是(1+1)*6=12个可训练参数
---->对于S2层的每一个图的每一个点,连接数是(2*2+1)=5,总共是14*14*6*(2*2+1)=5880个连接
3.C3层也是一个卷积层,它同样通过5x5的卷积核去卷积层S2,然后得到的特征map就只有10x10个神经元,但是它有16种不同的卷积核,所以就存在16个特征map了。这里需要注意的一点是:C3中的每个特征map是连接到S2中的所有6个或者几个特征map的,表示本层的特征map是上一层提取到的特征map的不同组合(这个做法也并不是唯一的)。
例如,存在的一个方式是:C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。这样C3层有1516个可训练参数和151600个连接。
---->这里的参数和连接数最不好理解啦
---->从C3的角度看,它有16个图.把每个图对应的参数加起来就行了:
6*(3*25+1) + 6*(4*25+1) + 3*(4*25+1)+ 1*(6*25+1)=1516个可训练参数
---->上面的1516*10*10=151600个连接
4.S4层是一个下采样层,由16个5*5大小的特征图构成。特征图中的每个单元与C3中相应特征图的2*2邻域相连接,跟C1和S2之间的连接一样。S4层有32个可训练参数(每个特征图1个因子和一个偏置)和2000个连接。
---->16个2*2的小方框,每个有一个参数,加上一个偏置,也就是(1+1)*16=32个可训练参数
---->对于S4层的每一个图的每一个点,连接数是(2*2+1)=5,总共是5*5*16*(2*2+1)=2000个连接
5. C5层是一个卷积层,有120个特征图。每个单元与S4层的全部16个单元的5*5邻域相连。由于S4层特征图的大小也为5*5(同滤波器一样),故C5特征图的大小为1*1:这构成了S4和C5之间的全连接。之所以仍将C5标示为卷积层而非全相联层,是因为如果LeNet-5的输入变大,而其他的保持不变,那么此时特征图的维数就会比1*1大。C5层有48120个可训练连接。
---->120*(5*5*16+1)=48120个可训练连接
6. F6层有84个单元(之所以选这个数字的原因来自于输出层的设计),与C5层全相连。有10164个可训练参数。如同经典神经网络,F6层计算输入向量和权重向量之间的点积,再加上一个偏置。然后将其传递给sigmoid函数产生单元i的一个状态。
---->84*(120+1)=10164个可训练连接
一、准备样本:
正样本:
负样本:
二、训练算法与传统的BP算法差不多。主要包括4步,这4步被分为两个阶段:
第一阶段,向前传播阶段:
a)从样本集中取一个样本(X,Yp),将X输入网络;
b)计算相应的实际输出Op。
在此阶段,信息从输入层经过逐级的变换,传送到输出层。这个过程也是网络在完成训练后正常运行时执行的过程。在此过程中,网络执行的是计算(实际上就是输入与每层的权值矩阵相点乘,得到最后的输出结果):
Op=Fn(…(F2(F1(XpW(1))W(2))…)W(n))
第二阶段,向后传播阶段
a)算实际输出Op与相应的理想输出Yp的差;
b)按极小化误差的方法反向传播调整权矩阵。(后面具体讲权重是如何调整的)