深度学习(三)——卷积神经网络

寵の児 提交于 2020-01-27 22:29:23

深度学习(三)——卷积神经网络

概述

这篇博文主要讨论卷积神经网络(Convolutional Neural Networks,CNN)。CNN是目前最流行的神经网络类型之一,特别是对于图像或是视频这种高维数据。与多层感知器不同,CNN层中的每层单元是一个二维(或高维)滤波器,这样的滤波器又被称为卷积核,它能够对输入数据进行卷积运算,这是最关键的区别。

CNN的产生也同样来源于人类对自我认知过程的思考。考虑人类辨识一头大象的过程,人类往往是在看到大象的一部分,才能够辨识出这是大象的。例如看到大象的大耳朵、长鼻子、粗壮的腿等。但在计算机中,图像的每一个像素点都是三个数字。人类辨识图像的过程启示我们在辨识过程中,单一的像素点是没有意义的,只有将像素点放在一块区域中,才能显示出它的作用。

因此,利用卷积核,可以将一块区域中的像素值进行一些运算得到一个值,就实现了上面的过程。也因为这个,CNN在计算机视觉领域得到了非常广泛的应用。接下来就依次介绍CNN的各个组成部分和一些模型上的细节。

CNN的神经网络层

CNN是由几个基本构建块组成的,称为CNN层。最基本的CNN具备的层次有:

  • 卷积层
  • 池化层
  • 全连接层

另外还有一些更复杂的层次:

  • 转置卷积层
  • 感兴趣区域(RoI)池化层
  • 空间金字塔池化层
  • 局部特征聚合描述符层
  • 空间变换层

卷积层

卷积层是CNN中最重要的组成部分。它包括一组卷积核,它们与给定输入进行卷积以生成输出特征图。

卷积核和卷积操作

卷积核实际上是含有离散数字的网格。下图给出了一个2X2的卷积核的例子:
在这里插入图片描述
卷积核中每个网格中有一个数字,表示的是权重,是卷积神经网络需要训练的参数。

利用卷积核可以实现卷积操作。接下来举一个简单的例子说明卷积操作。假设我们有一个2X2的卷积核和一个3X3的图片。想像我们有一张2X2的方格纸和一个3X3的方格纸,首先我们将2X2的方格纸(卷积核)放到另一张方格纸的左上角,让它的每一个网格对应图片中一个像素的值。然后对应数字相乘,再求和得到输出的一个数字。
在这里插入图片描述
8×2+2×5+1×7+3×5=16-8\times2+2\times5+1\times7+3\times5=16
然后我们将上面的方格纸向右移一格,再对应相乘求和,得到一个数字,继续重复,如果不能右移,就重新转到最左边再下移一格,直到上面的方格纸移动到右下角。这样就完成了卷积操作,得到了输出特征图。在上面的例子中,最后输出的特征图为:
在这里插入图片描述
在上面的例子中,为了计算特征图中的每个值,卷积核沿着水平和垂直方向每次移动了一格。这个距离称为卷积核的步幅。目前应用最广泛的步幅是1,但是在需要的时候,也可以设置为不同的值。例如使用步幅为2的卷积核。步幅更大意味着输出的特征图会更小。这种使得维度缩减的方法称为子采样操作。这种维度的缩减提供了对象的规模和姿势的适度不变性,这在诸如目标识别的应用中是有用的属性。假定我们使用f×ff\times f的卷积核,对h×kh\times khhkk列)的图像进行卷积操作,步幅为ss,最终生成的特征图大小为:
h=hf+ssh^{'}=\lfloor\frac{h-f+s}{s}\rfloor k=kf+ssk^{'}=\lfloor\frac{k-f+s}{s}\rfloor

零填充和填充卷积

从上面的公式不难看出,如果我们不对原图像做其他任何操作,并且使用大于1×11\times1的卷积核,我们得到的生成特征图总是比原图像要小的。但是在某些应用(例如图像去噪,图像超分辨率或图像分割)中,我们希望在卷积后保持空间大小不变甚至更大。这样做的原因是:

  • 这些应用程序需要在像素级别进行更加密集的预测。
  • 这样做可以避免输出特征维度的快速崩塌,从而允许我们设计更深的网络。
  • 有助于实现更好的性能和更高分辨率的输出标签。

这可以通过零填充来实现。所谓零填充,就是在图像周围填充一圈或多圈零。下面给出了一个2×22\times2的图像进行两次零填充的例子:
在这里插入图片描述
(需要说明的是,这是一个图像比较小的例子。实际上的图像往往都是很大的,进行零填充后的效果不会像上面这样夸张。)

对进行零填充后的图像进行卷积操作,就可以使得输出图像大小不变甚至扩大,假设进行零填充的次数为pp,那么零填充后的输出特征图尺寸为:
h=hf+s+psh^{''}=\lfloor\frac{h-f+s+p}{s}\rfloor k=kf+s+psk^{''}=\lfloor\frac{k-f+s+p}{s}\rfloor

基于零填充的卷积称为填充卷积,通常可分为三种类型:

  • 有效卷积:不进行任何零填充的卷积。
  • 同尺寸卷积:确保输出和输入特征图具有相同的大小(尺寸)。因此需要进行零填充,对于步幅为1,需要进行的零填充次数为:p=f2p=\lfloor\frac{f}{2}\rfloor因此同尺寸卷积也被称为半卷积
  • 全尺寸卷积:全尺寸卷积指的是一种最大可能的填充的卷积。这个最大可能的填充指的是使得在卷积运算过程中,每一次都至少要有一个有效输入值的最大的填充
    例如上面零填充的例子,如果使用2×22\times2的卷积核,在最左上方运算时,四个值都是零填充的值,不是有效值,因此不是全尺寸卷积。如果使用3×33\times3的卷积核,进行每一次卷积操作时都至少有一个有效值,并且如果多填充一圈零,就不满足全尺寸卷积的条件,因此这就是最大的填充,是全尺寸卷积。
    不难看出,对于大小为ff的卷积核,进行全尺寸卷积需要填充f1f-1个零,使得在极端的角落处,卷积中将包括至少一个有效值。

感受野与扩张卷积

卷积核的尺寸被称为感受野。例如2×22\times2的卷积核的感受野就是2×22\times2。当我们将多个卷积层堆叠在彼此之上时,每层相对于输入的有效感受野将会与它前面的卷积层的感受野有关。计算连续堆叠的卷积层中某一层的有效感受野的递推公式如下:
RFeffn=RFeffn1+((fn1)×i=1n1si)RF_{eff}^n=RF_{eff}^{n-1}+((f_n-1)\times\prod_{i=1}^{n-1}s_i)
其中,RFeffnRF_{eff}^n表示第nn层的感受野,fnf_n表示第nn层的卷积核大小,sis_i表示第ii层卷积时的步幅。

为了实现具有相对较少的参数数量但深度较大的模型,一个成功的策略是将许多具有较小感受野的卷积层堆叠。例如,我们可以堆叠两个3×33\times3的卷积层,利用上面的公式计算,最终输出的有效感受野为5×55\times5。但相比于直接使用5×55\times5的卷积核,堆叠两个3×33\times3的卷积核只需要训练18个参数,比原来少了7个。

但随之而来的问题是这样限制了所学习的卷积核的空间上下文,换句话说,不够灵活,并且卷积的粒度会更大,会使得特征不太理想。因此在需要像素级别密集预测的分割和标记任务中效果不佳。

另外一种方法是扩张卷积。这是一种能够扩展感受野大小而不增加参数数量的方法。扩张卷积的中心思想是加入一个参数空洞因子dd,一个空洞因子为dd的扩张卷积核表示在原始卷积核的每个元素之间加入d1d-1个空格,在空格中填充0。下面是一个d=2d=2的扩张卷积核的例子:
在这里插入图片描述
图中橘黄色所示位置就是空格,在进行卷积运算时,将会固定权重为0进行运算。因此执行卷积操作时,只有四个角上的像素参与运算。这样就可以将一个2×22\times2的卷积核的感受野扩展到3×33\times3,并且不增加参数数量。这允许我们在执行卷积时可以更广泛地混合上下文。实践检验证明扩张卷积的方法可以提高基于深度CNN的分类、检测和分割的性能。

需要注明的是,上面的讨论是基于输入是二维数据的情况下,对于输入是张量的情况,是类似的。如果输入是三维数据,那么卷积核就是一个空间立方体,卷积操作要向着长、宽、高三个方向进行卷积,零填充、扩充卷积等等都是类似的操作,这里不再赘述。

池化层

池化层也是对输入特征图的块进行操作。与卷积层类似,池化层也需要指定池化区域的大小和步幅的大小,但与卷积层不同的是,池化层指定的是处理这一块的规则,而没有类似权重的参数需要训练。下面是一个最大池化操作的例子:
在这里插入图片描述
我们有一张3×33\times3的输入图,我们指定池化区域大小为2×22\times2,于是我们先找到左上方四个方块,取最大值6作为输出,然后和卷积操作一样,向右、向下移动,直到到达右下角。最终的结果如下图所示:
在这里插入图片描述
常用的池化操作有:

  • 取最大值
  • 取最小值
  • 取平均值
  • 取中位数

池化操作能够有效地对输入特征图进行采样,作用主要有下面几点:

  • 能够使得特征更加紧凑;
  • 能够滤去重复特征,降低数据维度
  • 进行平移、旋转和图片扩大缩小等操作下,该特征具有不变性

全连接层

CNN中的全连接层和多层感知器中的一层完全相同,每一层由多个人工神经元组成,每个神经元有其权重参数和激活函数,在这里给出一张图进行说明,详细的内容可以看我之前的博文:网页链接
在这里插入图片描述
上面就是卷积神经网络的三种基本网络层。通常的卷积神经网络一般前几层由卷积层和池化层交替组成,后面几层为全连接层。例如:输入\rightarrow卷积层\rightarrow池化层\rightarrow卷积层\rightarrow池化层\rightarrow全连接层\rightarrow全连接层\rightarrow全连接层\rightarrow输出。每一层与后一层完全连接。

下面对于其他的一些网络层作简要介绍。

转置卷积层

转置卷积层是一种能将低分辨率的特征图转化为高分辨率的输出特征图的网络层,换句话说,它能够将小的特征图扩展为更大的特征图。转置卷积层相当于输入反向通过卷积层,卷积层能够将图片中的区域特征进行提取,从而输出更小的特征图,而反向通过特征图,起到的就是输出更大的特征图的效果。

要说明转置卷积层的工作原理,首先需要介绍卷积操作的另一种计算方法。我们可以将卷积“移动运算”转化为矩阵运算,这样就可以加快运算的速度。

2×22\times2的卷积核卷积3×33\times3的图像为例,首先将图像按从左到右、从上到下的次序编号,并展开成一个向量:
在这里插入图片描述
写成一般形式:
M=[a1a2a3a4a5a6a7a8a9]x=[a1a2a3a4a5a6a7a8a9] M=\left[ \begin{matrix} a_1 & a_2 & a_3 \\ a_4 & a_5 & a_6 \\ a_7 & a_8 & a_9 \\ \end{matrix} \right] \rightarrow\vec{x}= \left[ \begin{matrix} a_1\\ a_2\\ a_3\\ a_4\\ a_5\\ a_6\\ a_7\\ a_8\\ a_9\\ \end{matrix} \right]
然后将2×22\times2的卷积核展开成托普利兹矩阵:
W=[w11w12w21w22]K=[w11w120w21w2200000w11w120w21w22000000w11w120w21w2200000w11w120w21w22] W=\left[ \begin{matrix} w_{11} & w_{12} \\ w_{21} & w_{22} \\ \end{matrix} \right] \rightarrow K=\left[ \begin{matrix} w_{11} & w_{12} & 0 & w_{21} & w_{22} & 0 & 0 & 0 & 0 \\ 0 & w_{11} & w_{12} & 0 & w_{21} & w_{22} & 0 & 0 & 0 \\ 0 & 0 & 0 & w_{11} & w_{12} & 0 & w_{21} & w_{22} & 0 \\ 0 & 0 & 0 & 0 & w_{11} & w_{12} & 0 & w_{21} & w_{22} \\ \end{matrix} \right]
从这个简单的例子中,不难看出托普利兹矩阵的构造过程,假设我们有一个f×ff\times f的卷积核和一张h×wh\times w的图片,将卷积核展开得到的托普利兹矩阵的大小为hw×hwh^{'}w^{'}\times hw(这里的hwh^{'}w^{'}是利用卷积操作那里的公式计算得到的输出特征图的高和宽),步长为ss。构造过程为:

  1. KK矩阵第一行首先填充卷积核的第一行权重,后面补充wfw-f个零,再填充卷积核的第二行权重,再补零,循环执行。
  2. 卷积核权重全部填充完毕后,后面全部补零
  3. 第二行开始,每一行都是上面的数据右移ss左边补零(和逻辑移位类似)。
  4. 当行号为ww^{'}的倍数时,要右移到使得w11w_{11}的列号为kw+1kw+1kk为正整数)的第一个位置。

利用托普利兹矩阵,我们就可以将卷积移动运算转化为矩阵运算:
y=Kxy=Kx
转置卷积层就是将矩阵KK进行转置,进行运算,达到扩充维度的效果:
y=KTxy=K^Tx
注意这里的xx,yy在两个公式中的大小关系不同。

另外,实现转置卷积还可以通过对输入特征图补充零的方式,这里不再叙述。将转置卷积转化为矩阵形式,比起填充零的方法,可以得到更快的运算速度。

感兴趣区域(RoI)池化层

感兴趣区域(RoI)池化层是卷积神经网络的一个重要组成部分,主要用于目标检测。在目标检测问题中,最终的目标是使用一个图形框(一般为矩形框)精确定位图像中的某个对象。对于这类问题,一般采取的方法是首先生成大量可能出现某对象的建议区域(称为感兴趣区域(RoI)),对于这些区域,用已有的检测器去检测该区域是否含有目标对象。但由于对RoI的有效性的检测方法很少,因此会产生大量的区域是无用的,这就会产生资源的浪费。

RoI池化层为该问题提供了一个解决方案,RoI池化层的主要思想是推迟对单个感兴趣区域的处理,对输入图像分成两个并行步骤进行处理,一是通过已有的检测器检测感兴趣区域,另一部分通过卷积神经网络输出特征,然后将感兴趣区域的坐标处理后的特征图作为RoI池化层的输入(注意这里的输入特征图是已经进行过卷积、池化等处理后的),RoI池化层根据输入的坐标根据映射关系找到特征图中的区域,再进行池化操作(取最大值或者平均值等等)。由于每个RoI的大小可能不同,池化区域的大小也要进行调整,要保证每一个RoI进行池化操作后会得到大小相同的特征图,输出特征图的大小是一个超参数。对于这些输出特征图,再通过几个全连接层进行处理、分类和训练,最后得到输出。

RoI池化层极大地提高了深度网络的效率,它还使得以端到端的方式训练网络成为可能,并可以作为一个统一的系统。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!