第九章
- 前言
- 什么是卷积
- 神经网络里卷积的目的
- 什么是池化
- 卷积和池化的强先验
前言
卷积网络也叫卷积神经网络(或者CNN),是一种特殊的深层的神经网络模型,它适合于时间序列数据的处理和图像数据处理。
这章内容主要讨论内容:
- 什么是卷积
- 使用卷积的动机
- 什么是池化
- 用于实践中的神经网络的几个变化卷积函数
- 卷积如何应用于各种维度不同的数据
- 讨论一些如何使卷积神经更有效率
补充内容:
卷积神经网络的特殊性体现在两个方面,一方面它的神经元间的连接是非全连接
的, 另一方面同一层中某些神经元之间的连接的权重共享
的(即相同的)。它的非全连接和权值共享的网络结构使之更类似于生物神经网络,降低了网络模型的复杂度(对于很难学习的深层结构来说,这是非常重要的),减少了权值的数量。
9.1卷积运算
卷积运算是通过两个函数f和g 生成第三个函数的一种数学算子,表征函数f与g经过翻转和平移的重叠部分的面积。(百度百科)
为了说明卷积运算,我们一个通过激光传感器来定位飞船位置的例子。
x(t):激光传感器的输出
t:某个时刻,这2个 变量都是实数
假设:激光传感器有一定的噪声,为了获得较小的噪声,我们采用了几种测量方式,越新的测试方法,越可靠,所以我们给定比较新的测量方法,更大的权重。我们得到权重函数:w(a),变量a是测量的年代。如果我们将这个函数应用到每一个时刻,我们的得到了一个新的函数:
s(t)=∫x(a)w(t?a)da
这个操作叫卷积,通常卷积定义为:s(t)=(x?w)(t)
w代表概率密度函数,或者带有权重的均值。对于卷积函数第一个函数x,被称作输入,第二个w,被称作核函数。如果激光传感器每秒测量一次,t就是一个整数集合。s(t)=(x?w)(t)=∑a=?∞∞x(a)w(t?a)
我们经常会用卷积操作一个多坐标数据,比如我们用一个2维的图片作为输入,同样用2维的核K:
S(i,j)=(I?K)(i,j)=∑m∑nI(m,n)K(i?m)(j?n)
卷积的可计算性,我们可以等效的写成:
S(i,j)=(K?I)(i,j)=∑m∑nI(i?m,j?n)K(m)(n)
卷积运算的交换律的出现,是由于我们可以翻转核函数和输入值。很多深度学习库,都实现了互相关
的函数。它和卷积是一样的,不过没有翻转核函数。
S(i,j)=(I?K)(i,j)=∑m∑nI(i+m,j+n)K(m)(n)
一个基于核翻转卷积算法将学习到相不翻转内核无需翻转由算法学到的内核。这也是很难看到单独使用卷积到机器学习;卷积一般和其他算法组合使用,这些组合函数无论使用翻转核卷积运算还是非翻转核卷积运算都不再变换。
图9.1:非核翻转2-D卷积的一个例子。在这种情况下,我们限制输出的位置,其中核数据完全位于图像内,在某些情况下,被称为有效卷积
。我们用正方形上的箭头指示左上角输入矩阵数据的元素通过施加右上角输入矩阵的区域的核数据,进行一个互相关
计算。
9.2使用卷积的动机
卷积充分利用3个重要观点来改善深度学习系统:稀疏连接
,参数共享
和等效表示
。此外,卷积提供了一种方法,来处理可变长的输入数据。传统的神经网络使用每一个参数矩阵和输入矩阵相乘,算出输出值,这意味着每个输出单元和输入单元都相互作用。卷积网络是稀疏连接
的,这个是通过一个比输入小的核来实现的。比如,当处理图像时,这个输入图片,有成千或百万像素,但我们可以检测到一些小的有用的特征,比如核占据的几十或上百的像素的一些边缘。这意味着我们只需要保存更少的参数,这样可以降低模型所需内存,改善它的统计效率。如果存在一个m维的输入数据,和n维的输出数据,那么矩阵相乘需
要m×n个参数,算法需要一个O(m×n)复杂度。如果我们限制输出层的链接个数为k,那么仅仅需要O(k×n)复杂度。对于稀疏连接的图片展示,可以参考图9.2和图9.3.在卷积神经网络里, 隐含层单元不必直接和每一个输入层神经单元互联,如图9.4。
图9.2:稀疏连接,从图片的下面部分可知:我们高亮了输入单元x3,也高亮了受输入单元x3影响的输出单元,只有3个输出单元受它影响。(图底部)当s是由矩阵相乘得到,那么连接性不再是稀疏的,所有的输出单元都受到它的影响。
图9.3
图9.4
图9.4:卷积神经网络里的深层神经单元的感知野
比浅层神经元的感知野
要大得多,如果神经网络里加入一些像步长卷积或者池化,那么这个效果会增强。这意味着即使即使在在卷积神经网络里进行全连接
,也会变得稀疏,在深层的神经元可以不和所有或者大多数输入神经元连接。
参数共享
是指在模型中的多个函数共享相同的参数。在传统的神经网络里,在计算输出层时候,权重矩阵的每一个元素都会被计算一次,然后就不再使用。至于参数共享
的代名词,也可以说,网络连接权重,因为既然权值可以应用到一个输入单元上,那么就可以应用到任何地方。在卷积神经网络,核中的每个元素都被应用到输入数据的每个元素中(除或许有些边界像素,这取决于边界的设计决策)。通过卷积运算使用的参数的共享意味着我们不是在每一个位置上都学习一组独立的参数,而是我们只学一组参数。这不会影响前向反馈算法-它仍然是O(k×n)存储空间,但是它进一步减少了模型的存储需求。回想当k通常是远远小于m几个数量级。
因为m和n通常大小大致相同,k与M×N相比是几乎微不足道。卷积因此和密度矩阵乘法相比,在内存使用和统计效率方面更高效,为描述参数共享
是如何工作的,参见图9.5.
图 9.5:
权值共享
:黑色箭头表示用某个特定的参数来连接2个不同模型。(上面)黑色箭头表示在卷积神经模型里我们使用3个核元素中的中间那个元素。由于权重共享这个参数被所有的输入单元使用。(下面)单个那个黑色箭头表明权值矩阵的中间那个元素在一个全连接的网络模型中被使用。这个模型里参数没有被共享只是被使用了一次。
作为一个实战中利用前2个原理(稀疏连接
,参数共享
)的一个实例,图9.6 表明了,稀疏连接
,参数共享
如何在图片中检测边的线性函数提高了效率。
在卷积时,由于权重共享而产生的一个特性叫转换等效性
,如果说一个函数是等效的,那么意味着在输入中变化,那么在输出中也会同样变化。如果满足:f(g(x))=g(f(x)),那么函数f(x)和g(x)就是等效的。在卷积网络中,我们令函数g是一个对输入数据进行转换的函数,比如平移输入数据。然后卷积函数和g是等效的。举例,让I是一个图片关于整数坐标的亮度的函数。函数g是一个图片函数到另一个图片函数的映射。I′=g(I)是一个图片处理函数,I′(x,y)=I(x?1,y),这是一个将图片像素平移一个像素的函数,如果我们将这个变换应用于I,然后在卷积,那么结果将会和将图片先卷积运算,然后在作用变换函数g到输入的结果一样。当处理时间序列数据时,这意味着卷积处理在时间轴上,输入数据的不同特征。如果我们将输入数据里某个事件向后平移,那么在输出数据里某个将来的时间里出现。相似的,在图片处理上,卷积产生了一个2D的映射,这个映射里包含了输入数据里某种的特征。如果我们平移这个特征,那么在输出图片里也会同时平移相同的位移量。这是一个非常有用的功能,当我们知道某些函数里相邻像素是有用的,那么我们就将它多个输入图片的位置上。举例,当处理图片时,在卷积网络的第一层探测图片里边的时候,这非常有用。相同的边或多或少会出现在图片的几个位置上,所以权值共享一般是跨越整个图片的。在某些时候,我们不希望权值共享跨越整个图片,比如,我们处理人脸图片,整个图片被对称的剪裁掉。我们希望在不同部位找到相应的人体器官的特征,比如在脸部上部来找眉毛,在脸下部找下巴。
卷积相对于其他变换(图片缩放或者旋转),不是那么自然的等效。某种数据不能被神经网络处理,这种神经网络是矩阵和固定大小的矩阵相乘。但是卷积可以处理这种数据,我们会在9.7章讨论。
9.3 池化
一个卷积网络由3个特定的阶段组成。在第一个阶段,这个层并行处理几个卷积来产生一组线性激活函数。在第二阶段,每一个线性激活都是运行一个非线性激活函数(ReLu),这个阶段有时候也叫边缘检测阶段。在第三阶段,我们用池化来修正输出。
一个池化函数替换了网络中输出数据中的默写地方,它是一个输出值邻近的一个概括统计值。比如,最大池化
是一种统计矩形数据里最大值一种处理。其他一些池化还包括均值池化,L2正则池化,基于中心像素距离的加权均值池化。
在所有的场合,池化都有助于使得输入数据的发生小变换,而模型的表示的不变形。对于图片的偏移旋转的不可变性意味着,如果我们对输入数据进行少量变换,对于池化后的输出值是不变的。图9.8是一个池化如何产生作用的例子。本地变换的不可变性是非常有用的一个特性,当我关注与某个特征是否出现,而不是关心它具体的位置。比如,当决定一张图是不是有人脸,我们并不需要知道眼睛的精确像素的位置,我只需知道在脸的左右各有一个眼睛就行了。在其他一些场景,保持一些特征的位置是比较重要的。比如我们想要发现在一个特定的方位有一个由2个边构成的角,我们需要很好保存这个角的位置。
图9.8:最大池化的不可变性。(图片顶部)输出的是卷积层中间层,底部一行是非线性的。顶部表明了最大池化的输出,这个最大池化是步长1像素,区域为3像素的。(图片底部) 同样结构的网络,输入数据向右移动了一个像素,底部那层每一个值都发生了变换,但是顶部那层的值只有一半发生了变化。因为最大池化只对相邻区域的最大值敏感,而不是具体位置。
池化在一些学习平移不可变性的函数有着无与伦比的优势。如果这个论点是对的,那么可以极大提高卷积神经网络统计的效率。对空间区域的池化产生了平移的不可变性,但是如果池化带参数的卷积输出,那么我们可以学习到哪些的变换是不可变的特征。看图9.9.
图片9.9:学习的不可变性。一个池化单元,它池化了多个特征,这些特征是被哪些输入数据里转换不变性的那些参数学习得来的。这里我们显示了一组学习的3个滤波器,还有通过学习得到的最大池化单元,这个单元是对旋转不变的。所有的3个滤波器用来等数字5的边缘,每个滤波器试图匹配稍稍有些偏转的数字5。当5出现在输入数据中,滤波器将会匹配它,在探测单元里将会导致一个大的激活值。无论哪一个池化单元被激活,最大池化就会有一个较大激活值。这个原理被maxout网络(Goodfellow et al.,2013a)还有一些其他的卷积网络。最大池化对于空间的位置是自然的平移不变性,这个多通道的方案仅仅是对于学习变换是必要的。
因为池化反映了整个相邻区域的概括信息,所有用少量的池化单元来替代检测单元是可能的,我们可以通过池化K个像素的区域,而不是1个像素。看图9。10.这可以改善神经网络的计算效率,因为下一层的计算减少了K倍。当下一层的参数数量是函数的输入大小,这减少了输入数量的大小,从而改善了统计的效率,降低了存储参数的内存消耗。
图9.10:池化下采样。我们使用最大池化,池化的宽度为3,步长为2,。这通过2个因素降低了模型表达的大小,降低了下一层分析和计算的负担,最右边的池化有一个比较小的尺寸,但是如果我们不想忽略一些检测单元的信息,就必须将它包含进来。
对于很多任务,池化是必不可少的,比如处理可变的输入数据。比如我们打算分类一个大小可变的图片,对于输入的分类层,必须是一个固定大小的。这通常是通过改变池化区域的偏移大小来实现,这样无论输入大小,分类层总是能够接受相同的统计信息。统筹地区之间的偏移,这样无论图片的大小是多少,分类层始终接收相同数量的汇总统计的。
一些关于池化的理论性工作给出了我们一些如何使用池化的指导(Boureau et al., 2010)。也可以一起对所有的特征进行动态的池化 (Boureau et al., 2011)。这个研究领域是一组不同的池化。另一个研究是学习一个单个的池化结构,然后将它应用到所有的图片里(Jia et al., 2012)。
池化可以完成一些自顶向下的神经网络结构,比如Boltzmann机和自动编码器。这些话题将要在第三部分讨论。Boltzmann机的池化将会出现在20.6章,反向翻转的池化单元应用于一些小的神经网络,这个将出现在20.10.6。一个完整的利用卷积和池化的分类卷积神经网络架构如图9.11.
图9.11 使用卷积网络的分类架构。这个在图中涉及的步长和深度并不适用于实际的使用中,这个架构被设计的很浅,只是为了能够在一页里显示下来。实际的卷积网络都是涉及大量的分支,不像在这里使用的简单的链式结构。(左边)一个处理固定大小图片的卷积网络,当经过几个连续的卷积层和池化层,我们进行了调整,在卷积层的特征映射的张量被压扁到一个空间维度了。网络的其他部分是一个普通的前向反馈神经分类器,在第六章里描述的。(中间)一个处理可变大小图片的卷积网络,但是有一个全连接的层,这个网络结构是使用一个可变的池化,而不是固定池化,是为了提供576个固定的向量,来全连接到网络。(右边)一个没有任何全连接的权重层,最后的卷积层输出到一个对于每个分类的特征映射。这个模型学习了一个映射,这个映射显示了每个空间位置属于每个类的可能性,平均了这些特征映射到一个具体值,这些被用于softmax分类器的输入参数。
9.4卷积和池化的先验
回想一下关于5.2章的概率分布的先验,这是一种模型参数分布的概率分布,这个模型可在我们看到数据以前,对模型的可信度进行编码。先验被认为在先验里这个概率密度是多么集中。弱先验是一个有着高熵的先验分布,比如高斯分布的高方差。一个先验允许数据或多或少的移动充参数。一个强先验是低墒值的,比如高斯分布的低方差。先验在决定参数在哪里结束起着非常积极的作用。
一个无限强的先验使得在某些参数的概率为0,或者说这些参数的值是完全被禁止的,无论有多少数据的值支持是给定的这些值。
我们可以想象一个卷积网络可以作为一个全连接网,但是它的在权重上非常强的先验。这个强先验可以说对于隐含层的必须和它相邻数据非常相似,但是在空间上平移了。先验可以说权重必须为0,空间连续的感受野被指定为隐含层。总体来说,可以认为卷积层作用是通过这一层的参数引出强先验概率分布。先验可以说这一层的函数应该学习了某种本地互连性,并且它是平移旋转等效的。
当然用强先验的全连接来网络实现一个卷积网络,在计算上是极度浪费的,但是用这种方法可以给我一些关于卷积神经网络如何工作的知识。一个重要的见解就是卷积和池化可能导致欠拟合。像其他的先验一样,卷积和池化只有在假设先验是相当精确的时候才是有用的。如果某个工作依靠保存空间信息的精度,那么卷积和池化就提高训练误差。某些卷积网络架构(Szegedy et al., 2014a)被设计出来,使用池化在某些通道,而在某些通道不使用池化,目的是为了得到高不可变的特征和即时在旋转不可变的先验是不对的时候,也不会出现欠拟合的特征。当某个工作涉及到从输入数据中很远得位置整合信息,这时候通过先验强加的卷积就是不恰当的。
另一个重要的见解就是我们应该仅仅比较卷积模型和其他卷积模型在统计学习性能。那些没有使用卷积的模型即使我们置换了所以图片中所有的像素,也可以学习。在很多的图片数据集里都有一些分开的变换不变性的模型跑分,能发现通过学习得到的拓扑概念,还有一些关于空间关系的硬编码知识。
补充内容:
1 卷积含义
自然图像有其固有特性,也就是说,图像的一部分的统计特性与其他部分是一样的。这也意味着我们在这一部分学习的特征也能用在另一部分上,所以对于这个图像上的所有位置,我们都能使用同样的学习特征。
更恰当的解释是,当从一个大尺寸图像中随机选取一小块,比如说 8x8 作为样本,并且从这个小块样本中学习到了一些特征,这时我们可以把从这个 8x8 样本中学习到的特征作为探测器,应用到这个图像的任意地方中去。特别是,我们可以用从 8x8 样本中所学习到的特征跟原本的大尺寸图像作卷积,从而对这个大尺寸图像上的任一位置获得一个不同特征的激活值。
下面给出一个具体的例子:假设你已经从一个 96x96 的图像中学习到了它的一个 8x8 的样本所具有的特征,假设这是由有 100 个隐含单元的自编码完成的。为了得到卷积特征,需要对 96x96 的图像的每个 8x8 的小块图像区域都进行卷积运算。也就是说,抽取 8x8 的小块区域,并且从起始坐标开始依次标记为一直到(89,89),然后对抽取的区域逐个运行训练过的稀疏自编码来得到特征的激活值。在这个例子里,显然可以得到 100 个集合,每个集合含有 89x89 个卷积特征。
从知乎一个帖子拷贝过来的:两个函数,翻转其中一个,再滑动求积分,叫卷积(convultion);不翻转就滑动求积分,叫做互相关(cross-correlation,有时候简写为correlation)。如果其中之一是偶函数,那么卷积和互相关效果相同。
这里算的互相关在图像中就是很平常的滤波运算。(这里说的有点歧义,因为也有convolution filter这个说法,filter如果翻译成滤波器的话,那么“滤波”具有更加广的含义,只要符合“过滤掉某种频率的波形”的作用的kernel应该都可以称为滤波器,不管它是卷积还是相关的)
用matlab验证一下确实如此,互相关对应的是filter2,卷积对应的是conv2。(注意到matlab中还有filter和conv函数,应该是带2的是2维操作,不带2的是一维操作)
a = [1 2;3 4;5 6];
b = [1 2;3 4];
% 下面两个是等价的运算,其实filter2函数是调用conv2函数来实现的
filter2(b, a, ‘valid‘);
conv2(a, rot90(b, 2), ‘valid‘); %这里的rot90(b, 2)对应了“翻转”的操作,即旋转180度
2局部感知
卷积神经网络有两种神器可以降低参数数目,第一种神器叫做局部感知野。一般认为人对外界的认知是从局部到全局的,而图像的空间联系也是局部的像素联系较为紧密,而距离较远的像素相关性则较弱。因而,每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。网络部分连通的思想,也是受启发于生物学里面的视觉系统结构。视觉皮层的神经元就是局部接受信息的(即这些神经元只响应某些特定区域的刺激)。如下图所示:左图为全连接,右图为局部连接。
3 权值共享(Shared Weights)
在卷积网络中,每个稀疏过滤器hi通过共享权值都会覆盖整个可视域,这些共享权值的单元构成一个特征映射,如下图所示。
在图中,有3个隐层单元,他们属于同一个特征映射。同种颜色的连接权值是相同的,我们仍然可以使用梯度下降的方法来学习这些权值,只需要对原始算法做一些小的改动, 这里共享权值的梯度是所有共享参数的梯度的总和。我们不禁会问为什么要权重共享呢?一方面,重复单元能够对特征进行识别,而不考虑它在可视域中的位置。另一方面,权值 共享使得我们能更有效的进行特征抽取,因为它极大的减少了需要学习的自由变量的个数。通过控制模型的规模,卷积网络对视觉问题可以具有很好的泛化能力。
举例讲解:
下图左:如果我们有1000x1000像素的图像,有1百万个隐层神经元,那么他们全连接的话(每个隐层神经元都连接图像的每一个像素点),就有1000x1000x1000000=10^12个连接,也就是10^12个权值参数。
然而图像的空间联系是局部的,就像人是通过一个局部的感受野去感受外界图像一样,每一个神经元都不需要对全局图像做感受,每个神经元只感受局部的图像区域,然后在更高层,将这些感受不同局部的神经元综合起来就可以得到全局的信息了。这样,我们就可以减少连接的数目,也就是减少神经网络需要训练的权值参数的个数了。
下图右:假如局部感受野是10x10,隐层每个感受野只需要和这10x10的局部图像相连接,所以1百万个隐层神经元就只有一亿个连接,即10^8个参数。比原来减少了四个0(数量级),这样训练起来就没那么费力了,但还是感觉很多的啊。
我们知道,隐含层的每一个神经元都连接10x10个图像区域,也就是说每一个神经元存在10x10=100个连接权值参数(卷积核)。如果每个神经元用的是同一个卷积核去卷积图像,这样我们就只有100个参数啊,不管你隐层的神经元个数有多少,两层间的连接只有100个参数!这就是权值共享!
但这样只提取了一种特征,假如一种滤波器,也就是一种卷积核,能够提出图像的一种特征,例如某个方向的边缘。那么我们需要提取不同的特征,就需要多使用几种滤波器。所以假设使用100种滤波器,每种滤波器的参数不一样,表示它提出输入图像的不同特征,例如不同的边缘。这样每种滤波器去卷积图像就得到对图像的不同特征的放映,我们称之为Feature Map。所以100种卷积核就有100个Feature Map。这100个Feature Map就组成了一层神经元。100种卷积核x每种卷积核共享100个参数=100x100=10K,也就是1万个参数。见下图右:不同的颜色表达不同的滤波器。
刚才说隐层的参数个数和隐层的神经元个数无关,只和滤波器的大小和滤波器种类的多少有关。那么隐层的神经元个数怎么确定呢?它和原图像,也就是输入的大小(神经元个数)、滤波器的大小和滤波器在图像中的滑动步长都有关!例如,我的图像是1000x1000像素,而滤波器大小是10x10,假设滤波器没有重叠,也就是步长为10,这样隐层的神经元个数就是(1000x1000 )/ (10x10)=100x100个神经元了,假设步长是8,也就是卷积核会重叠两个像素,那么……我就不算了,思想懂了就好。注意了,这只是一种滤波器,也就是一个Feature Map的神经元个数哦,如果100个Feature Map就是100倍了。由此可见,图像越大,神经元个数和需要训练的权值参数个数的贫富差距就越大。
需要注意的一点是,上面的讨论都没有考虑每个神经元的偏置部分。所以权值个数需要加1 。这个也是同一种滤波器共享的。
总之,卷积网络的核心思想是将:局部感受野、权值共享(或者权值复制)以及时间或空间亚采样这三种结构思想结合起来获得了某种程度的位移、尺度、形变不变性。
4 池化
池化: 概述
在通过卷积获得了特征 (features) 之后,下一步我们希望利用这些特征去做分类。理论上讲,人们可以用所有提取得到的特征去训练分类器,例如 softmax 分类器,但这样做面临计算量的挑战。例如:对于一个 96X96 像素的图像,假设我们已经学习得到了400个定义在8X8输入上的特征,每一个特征和图像卷积都会得到一个 (96 ? 8 + 1) * (96 ? 8 + 1) = 7921 维的卷积特征,由于有 400 个特征,所以每个样例 (example) 都会得到一个 892 * 400 = 3,168,400 维的卷积特征向量。学习一个拥有超过 3 百万特征输入的分类器十分不便,并且容易出现过拟合 (over-fitting)。
为了解决这个问题,首先回忆一下,我们之所以决定使用卷积后的特征是因为图像具有一种“静态性”的属性,这也就意味着在一个图像区域有用的特征极有可能在另一个区域同样适用。因此,为了描述大的图像,一个很自然的想法就是对不同位置的特征进行聚合统计,例如,人们可以计算图像一个区域上的某个特定特征的平均值 (或最大值)。这些概要统计特征不仅具有低得多的维度 (相比使用所有提取得到的特征),同时还会改善结果(不容易过拟合)。这种聚合的操作就叫做池化 (pooling),有时也称为平均池化或者最大池化 (取决于计算池化的方法)。
下图显示池化如何应用于一个图像的四块不重合区域。
假设给定了 的大尺寸图像,将其定义为 xlarge。首先通过从大尺寸图像中抽取的 的小尺寸图像样本 xsmall 训练稀疏自编码,计算 f = σ(W(1)xsmall + b(1))(σ 是一个 sigmoid 型函数)得到了 k 个特征, 其中 W(1) 和 b(1) 是可视层单元和隐含单元之间的权重和偏差值。对于每一个 大小的小图像 xs,计算出对应的值 fs = σ(W(1)xs + b(1)),对这些 fconvolved 值做卷积,就可以得到 个卷积后的特征的矩阵。