赞
踩
百度百科中的定义是 卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一,擅长处理图像特别是图像识别等相关机器学习问题。
而卷积神经网络一词表明该网络使用了卷积(convolutional)这种数学运算。卷积神经网络的运作模式如下图所示:
CNN现在已经被用来应用于各个领域,物体分割啦,风格转换啦,自动上色啦等等,但是!!CNN真正能做的,只是起到一个特征提取器的作用!所以这些应用,都是建立在CNN对图像进行特征提取的基础上进行的。
好了,言归正传。那CNN怎么进行识别呢?
举个例子,拿到一张图片,要对它进行识别,最简单的例子是,这张图是什么?
比如,我现在要训练一个最简单的CNN,用来识别一张图片里的字母是X还是O。
我们人眼一看,很简单嘛,明显就是X啊,但是计算机不知道,它不明白什么是X。所以我们给这张图片加一个标签,也就是俗称的Label,Label=X,就告诉了计算机这张图代表的是X。它就记住了X的长相。
但是并不是所有的X都长这样呀。比如说
这四个都是X,但它们和之前那张X明显不一样,计算机没见过它们,又都不认识了。
不认识了怎么办,当然是回忆看看是不是见过差不多的呀。这时候CNN要做的,就是如何提取内容为X的图片的特征。
具体而言,为了确定一幅图像是包含有"X"还是"O",相当于我们需要判断它是否含有"X"或者"O",并且假设必须两者选其一,不是"X"就是"O"。
理想情况:
现实情况:
计算机的“视觉”中,一幅图看起来就像是一个二维的像素数组(可以想象成一个棋盘),每一个位置对应一个数字。像素值"1"代表白色,像素值"-1"代表黑色。
如果每个像素逐个比较肯定是不科学的,结果不对而且效率低下,而且这么做太不合理了。理想的情况下,我们希望,对于那些仅仅只是做了一些像平移,缩放,旋转,微变形等简单变换的图像,计算机仍然能够识别出图中的"X"和"O"。就像下面这些情况,我们希望计算机依然能够很快并且很准的识别出来:
上图中CNN要做的事情是:给定一张图片,是车还是马未知,是什么车也未知,现在需要模型判断这张图片里具体是一个什么东西,总之输出一个结果:如果是车,那是什么车。
1.最左边是数据输入层(input layer),对数据做一些处理,比如去均值(把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果)、归一化(把所有的数据都归一到同样的范围)、PCA/白化等等。CNN只对训练集做“去均值”这一步。
2.CONV:卷积计算层(conv layer),线性乘积求和。
3.RELU:激励层(activation layer),下文有提到:ReLU是激活函数的一种。
4.POOL:池化层(pooling layer),简言之,即取区域平均或最大。
5.FC:全连接层(FC layer)。
这几个部分中,卷积计算层是CNN的核心。
对于CNN来说,它是一块一块地来进行比对。它拿来比对的这个“小块”我们称之为Features(特征)。在CNN中,Features又称为卷积核(filter)。在两幅图中大致相同的位置找到一些粗糙的特征进行匹配,这种匹配又称之为patch匹配。相比起传统的整幅图逐一比对的方法,CNN能够更好的看到两幅图的相似性。
每一个feature就像是一个小图(就是一个比较小的有值的二维数组)。不同的Feature匹配图像中不同的特征。在字母"X"的例子中,那些由对角线和交叉线组成的features基本上能够识别出大多数"X"所具有的重要特征。
如果你不理解,你可以借助下面这个例子。
如果你要在一张照片上进行人脸定位,但是CNN不知道什么是人脸,我就告诉它:人脸上有三个特征,眼睛鼻子嘴巴是什么样,再告诉它这三个长啥样,只要CNN去搜索整张图,找到了这三个特征在的地方就定位到了人脸。
这些features很有可能就是匹配任何含有字母"X"的图中字母X的四个角和它的中心。那么具体到底是怎么匹配的呢?如下:
看到这里你可能感觉看懂了不少。但这只是第一步,比如你知道了这些Features是怎么在原图上面进行匹配的,但是你还不知道在这里面究竟进行的是怎样的数学计算,比如这个下面3*3的小块到底干了什么?
这里面的数学操作,就是我们常说的“卷积”操作。接下来,我们来了解下什么是卷积操作。
在做输入的时候,需要把图片处理成同样大小的图片才能够进行处理。
常见的处理数据的方式有:
1.去均值(常用):
AlexNet:训练集中100万张图片,对每个像素点求均值,得到均值图像,当训练时用原图减去均值图像。
VGG:对所有输入在三个颜色通道R/G/B上取均值,只会得到3个值,当训练时减去对应的颜色通道均值。(此种方法效率高)
2.归一化:
幅度归一化到同样的范围。
3.PCA/白化(很少用)
1>.用PCA降维
2>.白化是对数据每个特征轴上的幅度归一化。
当给你一张新的图时,CNN并不能准确地知道这些features到底要匹配原图的哪些部分,所以它会在原图中每一个可能的位置进行尝试。这样在原始整幅图上每一个位置进行匹配计算,我们相当于把这个feature变成了一个过滤器。这个我们用来匹配的过程就被称为卷积操作,这也就是卷积神经网络名字的由来。
这个卷积操作背后的数学知识其实非常的简单。要计算一个feature和其在原图上对应的某一小块的结果,只需要简单地将两个小块内对应位置的像素值进行乘法运算,然后将整个小块内乘法运算的结果累加起来,最后再除以小块内像素点总个数即可。如果两个像素点都是白色(也就是值均为1),那么
1
∗
1
1*1
1∗1 = 1,如果均为黑色,那么
(
−
1
)
∗
(
−
1
)
(-1)*(-1)
(−1)∗(−1) = 1。不管哪种情况,每一对能够匹配上的像素,其相乘结果为1。类似地,任何不匹配的像素相乘结果为-1。如果一个feature(比如
n
∗
n
n*n
n∗n)内部所有的像素都和原图中对应一小块(
n
∗
n
n*n
n∗n)匹配上了,那么它们对应像素值相乘再累加就等于
n
∗
n
n*n
n∗n,然后除以像素点总个数
n
2
n^2
n2,结果就是1。同理,如果每一个像素都不匹配,那么结果就是-1。具体过程如下:
9个都计算完了后就得到了下图:
然后进行计算:
补充: 可能有同学要举手问了,为什么绿色框要放在图中这个位置呢?
这只是个例子嘛。 这个绿色框我们称之为 “窗口”,窗口的特性呢,就是要会滑动。
其实最开始,它应该在起始位置。
进行卷积对应相乘运算并求得均值后,滑动窗便开始向右边滑动。根据步长的不同选择滑动幅度。
比如,若 步长 stride=1,就往右平移一个像素;若 步长 stride=2,就往右平移两个像素。
就这么移动到最右边后,返回左边,开始第二排。同样,若步长stride=1,向下平移一个像素;stride=2则向下平移2个像素。
继续接着上面的计算,刚才我们只是计算了一个图,而对于其他部分的图片,我们计算方法是完全一样的。整张图算完,我们可以得到下图:
然后换用其他feature进行同样的操作,最后得到的结果就是这样了:
为了完成我们的卷积,我们不断地重复着上述过程,将feature和图中每一块进行卷积操作。最后通过每一个feature的卷积操作,我们会得到一个新的二维数组。这也可以理解为对原始图像进行过滤的结果,我们称之为feature map,它是每一个feature从原始图像中提取出来的“特征”。其中的值,越接近为1表示对应位置和feature的匹配越完整,越是接近-1,表示对应位置和feature的反面匹配越完整,而值接近0的表示对应位置没有任何匹配或者说没有什么关联。
这样我们的原始图,经过不同feature的卷积操作就变成了一系列的feature map。我们可以很方便,直观地将这整个操作视为一个单独的处理过程。在CNN中,我们称之为卷积层(convolution layer),这样你可能很快就会想到后面肯定还有其他的layer。没错,后面会提到。我们可以将卷积层看成下面这个样子:
因此可想而知,CNN其实做的操作也没什么复杂的。但是尽管我们能够以这一点篇幅就描述了CNN的工作,其内部的加法,乘法和除法操作的次数其实会增加地很快。从数学的角度来说,它们会随着图像的大小,每一个filter的大小和filter的数目呈线性增长。由于有这么多因素的影响,很容易使得这个问题的计算量变得相当的庞大,这也难怪很多微处理器制造商现在都在生产制造专业的芯片来跟上CNN计算的需求。
随着模型网络不断加深,卷积核越来越多,要训练的参数还是很多,而且直接拿卷积核提取的特征直接训练也容易出现过拟合的现象。CNN使用的另一个有效的工具被称为“池化(Pooling)”出现并解决了上面这些问题,为了有效地减少计算量,池化就是将输入图像进行缩小,减少像素信息,只保留重要信息;为了有效地解决过拟合问题,池化可以减少数据,但特征的统计属性仍能够描述图像,而由于降低了数据维度,可以有效地避免过拟合。
给出池化的定义,对不同位置区域提取出有代表性的特征(进行聚合统计,例如最大值、平均值等),这种聚合的操作就叫做 池化,池化的过程通常也被称为 特征映射 的过程(特征降维)。听起来很高深,其实简单地说就是下采样。
池化主要有两种,除了 最大值池化(Max Pooling) 之外,还有 平均值池化(Average pooling),CNN中随机池化使用的较少。
最大池化是对局部的值取最大;平均池化是对局部的值取平均;随机池化是根据概率对局部的值进行采样,采样结果便是池化结果。概念非常容易理解,其示意图如下所示:
三种池化的意义:
最大池化可以获取局部信息,可以更好保留纹理上的特征。如果不用观察物体在图片中的具体位置,只关心其是否出现,则使用最大池化效果比较好。
平均池化往往能保留整体数据的特征,能凸出背景的信息。
随机池化中元素值大的被选中的概率也大,但不是像最大池化总是取最大值。随机池化一方面最大化地保证了Max值的取值,一方面又确保了不会完全是max值起作用,造成过度失真。除此之外,其可以在一定程度上避免过拟合。
拿最大池化举例:选择池化尺寸为2x2,因为选定一个2x2的窗口,在其内选出最大值更新进新的feature map。
下面是池化具体操作:
注意:不足的外面补"0":
经过最大池化操作(比如2*2大小)之后,一幅图就缩小为原来的四分之一了:
然后对所有的feature map执行同样的操作,得到如下结果:
因为最大池化(max-pooling)保留了每一个小块内的最大值,所以它相当于保留了这一块最佳的匹配结果(因为值越接近1表示匹配越好)。这也就意味着它不会具体关注窗口内到底是哪一个地方匹配了,而只关注是不是有某个地方匹配上了。这也就能够看出,CNN能够发现图像中是否具有某种特征,而不用在意到底在哪里具有这种特征。这也就能够帮助解决之前提到的计算机逐一像素匹配的死板做法。
当对所有的feature map执行池化操作之后,相当于一系列输入的大图变成了一系列小图。同样地,我们可以将这整个操作看作是一个操作,这也就是CNN中的池化层(pooling layer),如下:
卷积层对原图运算多个卷积产生一组线性激活响应,而非线性激活层是对之前的结果进行一个非线性的激活响应。如下图,这是官方说法。是不是感觉头脑一团雾水。
不过别怕,其实我们只需要知道在神经网络中用到最多的非线性激活函数是Relu函数,它的公式定义如下:
f(x)=max(0,x)
即,保留大于等于0的值,其余所有小于0的数值直接改写为0。
为什么要这么做呢?上面说到,卷积后产生的特征图中的值,越靠近1表示与该特征越关联,越靠近-1表示越不关联,而我们进行特征提取时,为了使得数据更少,操作更方便,就直接舍弃掉那些不相关联的数据。
下面是具体操作:
对整幅图操作完后,结果如下:
同样地,在CNN中,我们这一系列操作视为一个操作,那么就得到Relu Layer,如下:
在常见的几种CNN中,这三层都是可以堆叠使用的,将前一层的输入作为后一层的输出。比如:
然后,我们加大网络的深度,增加更多的层,就得到深度神经网络了:
为什么要采用局部感知呢?因为可以降低参数量级。为什么要降低参数量级呢?因为如果采用经典的神经网络模型,如下图所示:
则需要读取整幅图像作为神经网络模型的输入(即全连接的方式),当图像的尺寸越大时,其连接的参数将变得很多,从而导致计算量非常大。比如对于一张1000x1000像素的图片,如果我们有1M隐藏层单元,那么一共有 pow(10,12) 个参数,这显然是不能接受的。如下图所示:
而人类对外界的认知一般是从局部到全局、从片面到全面,先对局部有感知的认识,再逐步对全体有认知,这是人类的认识模式。类似的,在机器识别图像时也没有必要把整张图像按像素全部都连接到神经网络中,局部范围内的像素之间联系较为紧密,而距离较远的像素则 相关性较弱。因而,每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。这种模式就是卷积神经网络中降低参数数目的重要神器:局部感受野,节省了内存。
每张自然图像(人物、山水、建筑等)都有其固有特性,也就是说,图像其中一部分的统计特性与其它部分是接近的。这也意味着这一部分学习的特征也能用在另一部分上。因此,在局部连接中隐藏层的每一个神经元连接的局部图像的权值参数(例如5×5),将这些 权值参数共享 给其它剩下的神经元使用,那么此时不管隐藏层有多少个神经元,需要训练的参数就是这个局部图像的权限参数(例如5×5),也就是卷积核的大小,这样大大减少了训练参数。如下图所示:
举个例子,假设使用某一特征过滤器(检测器)提取 “手写5” 的特征,那么图片的右下角区域,以及旁边的各个区域都可以使用这个过滤器。每个特征检测器以及输出都可以在输入图片的不同区域中使用同样的参数,以便提取特征 “5”。而对于全连接网络来说,如果模式出现在新的位置,它只能重新学习这个模式。这使得卷积神经网络在处理图像时可以高效利用数据(因为视觉世界从根本上具有 平移不变性),只需要更少的训练样本就可以学到具有泛化能力的数据表示。
全连接层的形式和前馈神经网络(feedforward neural network)的形式一样,或者称为多层感知机(multilayer perceptron,MLP),这里直接放了一个链接给大家。前馈神经网络的介绍
回到导论中识别图片的例子:
原图片尺寸为9X9,在一系列的卷积、relu、池化操作后,得到尺寸被压缩为2X2的三张特征图。
从9X9,到2X2,看起来我们已经做了很多事情了哎!似乎胜利就在前方啦(ง •_•)ง。
而全连接层要做的,就是对之前的所有操作进行一个总结,给我们一个最终的结果。
它最大的目的是对特征图进行维度上的改变,来得到每个分类类别对应的概率值。
全连接层,顾名思义就是全部都连接起来,让我们把它与卷积层对比起来看。
这么说来的话前面的卷积层肯定就不是全连接了,没错,卷积层采用的是“局部连接”的思想,回忆一下卷积层的操作,是用一个3X3的图与原图进行连接操作,很明显原图中只有一个3X3的窗口能够与它连接起来。
那除窗口之外的、未连接的部分怎么办呢? 我们都知道,采用的是将窗口滑动起来的方法后续进行连接。这个方法的思想就是“参数共享” ,参数指的就是filter,用滑动窗口的方式,将这个filter值共享给原图中的每一块区域连接进行卷积运算。
敲一下黑板:局部连接与参数共享是卷积神经网络最重要的两个性质!
那么接下来再来看全连接神经网络。
还是拿9X9的输入原图做栗子,要进行全连接的话,那权值参数矩阵应该也是9x9才对,保证每一个值都有对应的权值参数来运算。(二者坐标直接一一对应)
还是回来看接下来的操作,得到了2X2的特征图后,对其应用全连接网络,再全连接层中有一个非常重要的函数----Softmax,它是一个分类函数,输出的是每个对应类别的概率值。比如:
【0.5,0.03,0.89,0.97,0.42,0.15】就表示有6个类别,并且属于第四个类别的概率值0.97最大,因此判定属于第四个类别。
注意:本例中因为只有两个类别X和O,而且数据量到此已经非常少了,因此直接将三个特征图改变维度直接变成一维的数据。(相当于全连接层的每个参数均为1)
展开的数据即为属于类别X的概率值,值大小也在对应X的线条粗细中表现出来了。
以上所有的操作都是对标准的原图X来进行的,因此最终分类显示即为X毋庸置疑。
假设对一张看起来并不标准的图进行分类。如下
对于进行一系列操作后,假设得到的概率值如下所示:
0.9表示极其大可能是X,因此对应到X的黄色线条比对应到O的绿色线条要粗很多很多。
我们对结果进行统计分析后可判断这张图片里的字母为X。
前面说了那么多,其实只是一个大致的框架的设计而已,里面的参数具体是多少则是需要训练的。
在我们搭建完毕神经网络的结构之后,我们需要对这个网络进行训练。训练的过程就是给这个网络模型不断的提供任务,让模型在执行任务的过程中积累经验,最终对类似的事件可以做出正确的判断。通俗的解释就是,假设我们教导一个小孩子认识狗,我们会给他看各种各样的狗,并告诉他,这是狗时间长了之后,当小孩见到狗这个物种的时候,就自然而然的知道是狗了。当然有时候也会有例外。比如来了一只狼,也许就会被误认为也是狗(狼狗)。造成这个误差的原因也许是我们给小孩看的狗的样本还不够多(可以理解为数据量不够,欠拟合),也有可能是我们教的方式不是最好的(选用的模型不是最优的)
那么神经网络到底需要训练什么呢?
训练的就是那些卷积核(filter)。
针对这个识别X的例子,我们可以人为定义三个3X3的卷积核,便可实现对X的特征提取。但是在实际运用中,比如识别手写字母,几乎不可能存在标准的写法,每个人的字迹都完全不同,因此原来的那三个标准的卷积核就变得不再适用了,为了提高CNN模型的通用性(机器学习中的“泛化能力”),就需要对卷积核进行改写。经过成千上万的训练集来训练,每一次加入新的数据,都有可能对卷积核里的值造成影响。
那么具体的训练方法是什么呢?
就是赫赫有名的BP算法—BackProp反向传播算法。
反向传播的详细讲解
在训练时,我们采用的训练数据一般都是带有标签label的图片。如果图片中的字母是X,则label=x,如果图片中的字母是A,则label=A。 标签能直观地反映图片。
在最开始,训练前,我们定义一个大小为3X3的卷积核,那么里面具体的值是多少,我们都不知道,但又不能为0吧,所以就用随机初始化法来进行赋值,卷积核获取到了一个随机值,便可以开始工作。
卷积神经网络便可以开始工作了,输入一张带有标签的图片(假设图片内容是字母X)。经网络识别后判断是X的概率为0.3。本来应该是1.0的概率,现在只有0.3,问题就很明显了,存在了很大的误差。
一种简单定义误差error的计算公式为 :
error=(result-label)*2
训练的终极目的就是使得这个误差最小,常用的方法是 梯度下降法。梯度下降的讲解
内部设计的具体复杂公式在此不多做叙述。
简单的说可以参照下图,要使得误差error最小,就是让卷积核里的参数w往梯度下降最小的反向改变。
用这种方法来改变卷积核里的参数W使得误差最小。
在现有的各大深度学习框架中,CNN的优化可直接通过定义优化器解决,因此这里只是简单叙述原理以供了解。
CNN层次结构 | 作用 |
---|---|
输入层 | 卷积网络的原始输入,可以是原始或预处理后的像素矩阵 |
卷积层 | 参数共享、局部连接,利用平移不变性从全局特征图提取局部特征 |
激活层 | 将卷积层的输出结果进行非线性映射 |
池化层 | 进一步筛选特征,可以有效减少后续网络层次所需的参数量 |
全连接层 | 用于把该层之前提取到的特征综合起来 |
受Hubel和Wiesel对猫视觉皮层电生理研究启发,有人提出卷积神经网络(CNN),Yann Lecun 最早将CNN用于手写数字识别并一直保持了其在该问题的霸主地位。近年来卷积神经网络在多个方向持续发力,在语音识别、人脸识别、通用物体识别、运动分析、自然语言处理甚至脑电波分析方面均有突破。
卷积神经网络与普通神经网络的区别在于,卷积神经网络包含了一个由卷积层和子采样层构成的特征抽取器。在卷积神经网络的卷积层中,一个神经元只与部分邻层神经元连接。在CNN的一个卷积层中,通常包含若干个特征平面(featureMap),每个特征平面由一些矩形排列的的神经元组成,同一特征平面的神经元共享权值,这里共享的权值就是卷积核。卷积核一般以随机小数矩阵的形式初始化,在网络的训练过程中卷积核将学习得到合理的权值。共享权值(卷积核)带来的直接好处是减少网络各层之间的连接,同时又降低了过拟合的风险。子采样也叫做池化(pooling),通常有均值子采样(mean pooling)和最大值子采样(max pooling)两种形式。子采样可以看作一种特殊的卷积过程。卷积和子采样大大简化了模型复杂度,减少了模型的参数。
都看到这里了,还不给我点赞,评论加收藏?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。