法→原理, 深度学习

深度学习算法之卷积神经网络(CNN)

钱魏Way · · 7,039 次浏览

[LATEXPAGE]

卷积神经网络简介

传统的BP神经网络与DNN(深度神经网络)不同层神经元的连接方式是“全连接”,也就是这一次层的一个神经元的输入,会接受上一次每一个神经元的输出,这种方式即为“全连接神经网络”。这样的连接方式有一个的缺点:因为权值与偏置等参数量大,导致训练收敛十分缓慢。特别是对于图像这样的训练数据,动不动就是数以百万的像素,理论上虽然可以收敛,但你可能得等上N年才有结果,而且它的泛化性也会变差。例如一张黑白的 28×28 的手写数字图片,输入层的神经元就有784个,如下图所示:

若在中间只使用一层隐藏层,我们设定hidden layer有15层,此时参数 w 就有 784×15=11760 多个;若输入的是28×28 带有颜色的RGB 格式的手写数字图片,输入神经元就有28×28×3=2352 个。这很容易看出使用全连接神经网络处理图像中的需要训练参数过多的问题。而在卷积神经网络(Convolutional Neural Network,CNN)中,卷积层的神经元只与前一层的部分神经元节点相连,即它的神经元间的连 接是非全连接的,且同一层中某些神经元之间的连接的权重 w 和偏移 b 是共享的(即相同的),这样大量地减少了需要训练参数的数量。

全卷积神经网络输出的特征图如同昆虫的复眼,每个grid为一只眼睛,每只眼睛所看到的东西不一样,但是每只眼睛的视野范围相同(即,每只眼睛的感受野大小相同), 每只眼睛单独工作,互不影响。然后每只眼睛会判断:1、它看到了什么物体(类别);2、这个物体有什么特点(属性,可选项)。

卷积神经网络的特点

局部感知

一张图像,我们实际上并不需要让每个神经元都接受整个图片的信息,而是让不同区域的神经元对应一整张图片的不同局部,最后只要再把局部信息整合到一起就可以了。这样就相当于在神经元最初的输入层实现了一次降维。

局部感知即卷积核的局部感受野,指的是卷积核所覆盖的像素面积,由于每个卷积核所覆盖的面积仅是很少的一部分,是局部特征,即为局部感知。CNN是一个从局部到整体的过程(局部到整体的实现是在全连通层)。下图是全连接层和卷积层的对比。

权重共享

传统的神经网络的参数量巨大,例如对1000X1000像素的图片做一次全连接操作,需要(1000X1000)10的6次方个参数。这可以说是卷积神经网络的最重要也是它牛逼之处,刚刚我们说到全连接神经网络最大的问题就是权值参数太多,而卷积神经网络的卷积层,不同神经元的权值是共享的,这使得整个神经网络的参数大大减小,提高了整个网络的训练性能。

降采样

降采样是卷积神经网络的另一重要概念,通常也称之为池化(Pooling)。简单理解可以看作是对图像的一次“有损压缩”,因为在实际的训练中,我们并不需要对图像中的每一个细节都进行特征提取和训练,所以池化的作用就是更进一步的信息抽象和特征提取,当然也会减小数据的处理量。最常见的方式有最大值(Max)池化、最小值(Min)池化、平均值(Average)池化。池化的好处是降低了图像的分辨率,整个网络也不容易过拟合。最大值池化如图所示。

卷积神经网络的层次结构

CNN由输入和输出层以及多个隐藏层组成,隐藏层可分为卷积层,池化层、RELU层和全连通层,如下图:

  • 输入层:CNN的输入为原始图像,三维(RGB)或二维的向量。
  • 卷积层:CNN的核心,卷积层由一组可学习的滤波器(filter)或内核(kernels)组成,它们具有小的感受野,每个卷积核具有kernel size,padding,stride等参数。从图像的左上角依次做内积操作,提取出图片的高层次特征。
  • 池化层:对conv后输出的feature map进行下采样操作,这样的好处有降低参数的数量,防止过拟合等作用。
  • 激活层:在CNN中使用relu激活函数,在网络中引入了非线性。通过relu激活函数传递卷积运算的结果。因此,最终特征映射中的值不是简单的线性关系。
  • 全连接层:全连接层的输入是一维向量,需要将pooling 层的输出向量flatten成一个一维的向量,然后输入到全连接层中,最后送到soft Max层进行类别的分类。
  • 输出层:用于输出结果

当然中间还可以使用一些其他的功能层:

  • 归一化层(Batch Normalization):在CNN中对特征的归一化
  • 切分层:对某些(图片)数据的进行分区域的单独学习
  • 融合层:对独立进行特征学习的分支进行融合

输入层

输入层(Input Layer)是将原始数据或者其他算法预处理后的数据输入到卷积神经网络,数据没有明确定义,可以是数字图像,可以是音频识别领域经过傅里叶变换的二维波形数据,也可以是自然语言处理中一维表示的句子向量。输入层的作用是将输入数据送入卷积神经网络进行特征提取,然后获得我们想要的结果。同时根据计算能力差异,机器存储能力差异和模型参数多少可以控制输入不同数量的数据。

在CNN的输入层中,(图片)数据输入的格式 与 全连接神经网络的输入格式(一维向量)不太一样。CNN的输入层的输入格式保留了图片 本身的结构。对于黑白的 28×28 的图片,CNN的输入是一个 28×28 的的二维神经元。

而对于RGB格式的28×28图片,CNN的输入则是一个 3×28×28 的三维神经元(RGB中的每一个颜色通道都有一个 28×28 的矩阵)。

卷积层

卷积层可以说是 CNN 架构中最重要的步骤之一。基本而言,卷积是一种线性的、平移不变性的运算,其由在输入信号上执行局部加权的组合构成。根据所选择的权重集合(即所选择的点扩散函数(point spread function))的不同,也将揭示出输入信号的不同性质。在频率域中,与点扩散函数关联的是调制函数——说明了输入的频率组分通过缩放和相移进行调制的方式。因此,选择合适的核(kernel)对获取输入信号中所包含的最显著和最重要的信息而言至关重要,这能让模型对该信号的内容做出更好的推断。

在卷积层中有几个重要的概念:

  • local receptive fields(感受视野)
  • shared weights(共享权值)

假设输入的是一个 28×28 的的二维神经元,我们定义5×5 的 一个 local receptive fields(感受视野),即 隐藏层的神经元与输入 层的5×5个神经元相连,这个5*5的区域就称之为Local Receptive Fields,如下图所示:

可类似看作:隐藏层中的神经元具有一个固定大小的感受视野去感受上一层的部分特征。在全连接神经网络中,隐藏层中的神经元的感受 视野足够大乃至可以看到上一层的所有特征。而在卷积神经网络中,隐藏层中的神经元的感受视野比较小,只能看到上一次的部分特征,上一层的其他特征可以通过平移感受视野来得到同一层的其他神经元,由同一层其他神经元来看:

设移动的步长为1:从左到右扫描,每次移动 1 格,扫描完之后,再向下移动一格,再次从左到右扫描。具体过程请看:

可看出 卷积层的神经元是只与前一层的部分神经元节点相连,每一条相连的线对应一个权重w。一个感受视野带有一个卷积核,我们将感受视野中的权重w矩阵称为卷积核将感受视野对输入的扫描间隔称为步长(stride); 当步长比较大时(stride>1),为了扫描到边缘的一些特征,感受视野可能会“出界”,这时需要对边界扩充(pad),边界扩充可以设为0 或其他值。卷积核的大小由用户来定义,即定义的感受视野的大小;卷积核的权重矩阵的值,便是卷积神经网络的参数,为了有一个偏移项,卷积核可附带一个偏移项b ,它们的初值可以随机来生成,可通过训练进行变化。因此感受视野(5X5)扫描时可以计算出下一层神经元的值为:$b+\sum_{i=0}^{4}\sum_{j=0}^{4}w_{ij}x_{ij}$

对下一层的所有神经元来说,它们从不同的位置去探测了上一层神经元的特征。我们将通过一个带有卷积核的感受视野扫描生成的下一层神经元矩阵称为一个feature map (特征映射图),如下图的右边便是一个 feature map:

在同一个feature map上的神经元使用的卷积核是相同的,因此这些神经元 shared weights,共享卷积核中的权值和附带的偏移。一个 feature map对应一个卷积核,若我们使用 3 个不同的卷积核,可以输出3个feature map:(感受视野:5×5,布长stride:1)

因此在CNN的卷积层,我们需要训练的参数大大地减少到了 (5×5+1)×3=78个。假设输入的是 28×28 的RGB图片,即输入的是一个 3×28×28 的二维神经元,这时卷积核的大小不只用长和宽来表示,还有深度, 感受视野也对应的有了深度,如下图所示:

由图可知:感受视野:3×2×2 ; 卷积核:3×2×2 ,深度为3;下一层的神经元的值为: $b+\sum_{i=0}^{2}\sum_{i=0}^{1}\sum_{j=0}^{1}w_{dij}x_{dij}$。卷积核的深度和感受视野的深度相同,都由输入数据来决定,长宽可由自己来设定,数目也可以由自己来设定,一个卷积核依然对应一个 feature map。

总结一下,卷积层的优点在于局部连接(有助于减少参数量)和权值共享。我们分别来举例说明一下:

  • 局部连接 :假设现在输入图片分辨率是100*100,然后隐藏层神经元有10^5个,如果全连接的话,那么每个隐藏层神经元都连接图像的一个像素点,就有个连接,这个参数量是很大的。对于卷积层来讲,如果卷积核大小为那么每个神经元只需要和原始图像中的一个的局部区域连接,所以一共只有个连接。可以看到通过局部连接,卷积层的参数量减少了很多。
  • 权值共享:在上面的局部连接中,一个有个参数。如果每个神经元对应的参数都相同的话,那么需要训练的参数实际上就只有个了。这个就是的卷积核。而权值共享的意思就是训练好的一个卷积核表示了在图像中提取某种特征的能力,例如提取人脸上的眼睛,也就是说卷积核具有了这种能力,无论在图像的哪个地方都可以起作用。这只是一个卷积核的作用,作用肯定是有限的,那么如果我们用100个卷积核来提取特征,那么特征提取能力就会大大增强。同时参数两也不过才。所以是非常cheap并且effective的。

激活层

激活层(Activation Layer)负责对卷积层抽取的特诊进行激活,由于卷积操作是把输入图像和卷积核进行相应的线性变换,需要引入激活层(非线性函数)对其进行非线性映射。激活层由非线性函数组成,常见的如sigmoid、tanh、relu。最常用的激活函数是Relu,又叫线性整流器。公式表达为:$f(x)=max(x,0)$

池化层

当输入经过卷积层时,若感受视野比较小,步长stride比较小,得到的feature map (特征图)还是比较大,可以通过池化层来对每一个 feature map进行降维操作,输出的深度还是不变的,依然为 feature map 的个数。

池化层也有一个“池化视野(filter)”来对feature map矩阵进行扫描,对“池化视野”中的矩阵值进行计算,一般有两种计算方式:

  • Max pooling:取“池化视野”矩阵中的最大值
  • Average pooling:取“池化视野”矩阵中的平均值 扫描的过程中同样地会涉及的扫描步长stride,扫描方式同卷积层一样,先从左到右扫描,结束则向下移动布长大小,再从左到右。如下图示例所示:

其中“池化视野”filter: 2×2;步长stride:2。最后可将 3 个 24×24 的 feature map 下采样得到 3 个 24×24 的特征矩阵:

总结一下,池化层优点有:

  • 不变性,更关注是否存在某些特征而不是特征具体的位置。可以看作加了一个很强的先验,让学到的特征要能容忍一些的变化。(实际上这个容忍能力是非常有限的)
  • 减少下一层输入大小,减少计算量和参数量。
  • 获得定长输出。(文本分类的时候输入是不定长的,可以通过池化获得定长输出)
  • 防止过拟合或有可能会带来欠拟合。

全连接层与输出层

全连接层(Full Connected Layer)就是一个线性特征映射的过程,将多维的特征输入映射为二维的特征输出,高维表示样本批次,低位常常对应任务目标(例如分类就对应每一个类别的概率)。全连接层主要对特征进行重新拟合,减少特征信息的丢失;输出层主要准备做好最后目标结果的输出。

归一化层

由于网络中存在级联的非线性运算,所以多层架构是高度非线性的。除了整流非线性,归一化(normalization)是 CNN 架构中有重要作用的又一种非线性处理模块。

Batch Normalization

Batch Normalization(批量归一化)实现了在神经网络层的中间进行预处理的操作,即在上一层的输入归一化处理后再进入网络的下一层,这样可有效地防止“梯度弥散”,加速网络训练。

Batch Normalization具体的算法如下图所示:

每次训练时,取batch_size大小的样本进行训练,在BN层中,将一个神经元看作一个特征,batch_size个样本在某个特征维度会有batch_size个值,然后在每个神经元$x_i$维度上的进行这些样本的均值和方差,通过公式得到 $\hat{x_{i}}$,再通过参数$\gamma$和$\beta$进行线性映射得到每个神经元对应的输出$y_i$。在BN层中,可以看出每一个神经元维度上,都会有一个参数$\gamma$和$\beta$,它们同权重$w$一样可以通过训练进行优化。

在卷积神经网络中进行批量归一化时,一般对未进行ReLu激活的 feature map进行批量归一化,输出后再作为激励层的输入,可达到调整激励函数偏导的作用。一种做法是将feature map中的神经元作为特征维度,参数$\gamma$和$\beta$的数量和则等于 2×fmapwidth×fmaplength×fmapnum2×fmapwidth×fmaplength×fmapnum,这样做的话参数的数量会变得很多;另一种做法是把一个feature map看做一个特征维度,一个feature map上的神经元共享这个feature map的参数$\gamma$和$\beta$,参数$\gamma$和$\beta$的数量和则等于 2×fmapnum2×fmapnum,计算均值和方差则在batch_size个训练样本在每一个feature map维度上的均值和方差。注:fmapnumfmapnum指的是一个样本的feature map数量,feature map 跟神经元一样也有一定的排列顺序。

Batch Normalization 算法的训练过程和测试过程的区别:在训练过程中,我们每次都会将 batch_size 数目大小的训练样本放入到CNN网络中进行训练,在BN层中自然可以得到计算输出所需要的均值和方差。而在测试过程中,我们往往只会向CNN网络中输入一个测试样本,这是在BN层计算的均值和方差会均为 0,因为只有一个样本输入,因此BN层的输入也会出现很大的问题,从而导致CNN网络输出的错误。所以在测试过程中,我们需要借助训练集中所有样本在BN层归一化时每个维度上的均值和方差,当然为了计算方便,我们可以在 batch_num 次训练过程中,将每一次在BN层归一化时每个维度上的均值和方差进行相加,最后再进行求一次均值即可。

Local Response Normalization

近邻归一化(Local Response Normalization)的归一化方法主要发生在不同的相邻的卷积核(经过ReLu之后)的输出之间,即输入是发生在不同的经过ReLu之后的 feature map 中。

LRN的公式如下:$b(i,x,y)=\frac{a(i,x,y)}{(k+\alpha \sum_{j=\max(0,i-\frac{n}{2})}^{\min(N-1,i+\frac{n}{2})}a(j,x,y)^2)^\beta }$

其中:

  • $a(i,x,y)$表示第i个卷积核的输出(经过ReLu层)的feature map上的 (x,y) 位置上的值。
  • $b(i,x,y)$表示$a(i,x,y)$经LRN后的输出。
  • N 表示卷积核的数量,即输入的 feature map的个数。
  • n 表示近邻的卷积核(或feature map)个数,由自己来决定。
  • $k,\alpha,\beta$是超参数,由用户自己调整或决定。

与BN的区别:BN依据mini batch的数据,近邻归一仅需要自己来决定,BN训练中有学习参数;BN归一化主要发生在不同的样本之间,LRN归 一化主要发生在不同的卷积核的输出之间。

切分层

在一些应用中,需要对图片进行切割,独立地对某一部分区域进行单独学习。这样可以对特定部分进行通过调整 感受视野进行力度更大的学习。

融合层

融合层可以对切分层进行融合,也可以对不同大小的卷积核学习到的特征进行融合。例如在GoogleLeNet中,使用多种分辨率的卷积核对目标特征进行学习,通过 padding 使得每一个 feature map 的长宽都一致,之后再 将多个 feature map 在深度上拼接在一起:

融合的方法有几种,一种是特征矩阵之间的拼接级联,另一种是在特征矩阵进行运算 (+,−,x,max,conv)。

卷积神经网络应用场景

卷积神经网络很擅长处理图像。而视频是图像的叠加,所以同样擅长处理视频内容。下面给大家列一些比较成熟的应用:

图像分类、检索

图像分类是比较基础的应用,他可以节省大量的人工成本,将图像进行有效的分类。对于一些特定领域的图片,分类的准确率可以达到 95%+,已经算是一个可用性很高的应用了。

典型场景:图像搜索…

目标定位检测

可以在图像中定位目标,并确定目标的位置及大小。

典型场景:自动驾驶、安防、医疗…

目标分割

简单理解就是一个像素级的分类。

他可以对前景和背景进行像素级的区分、再高级一点还可以识别出目标并且对目标进行分类。

典型场景:美图秀秀、视频后期加工、图像生成…

人脸识别

人脸识别已经是一个非常普及的应用了,在很多领域都有广泛的应用。

典型场景:安防、金融、生活…

骨骼识别

骨骼识别是可以识别身体的关键骨骼,以及追踪骨骼的动作。

典型场景:安防、电影、图像视频生成、游戏…

卷积神经网络经典框架

CNN最早由LeCun 在1998年《Gradient-based learning applied to document recognition》中提出,并提出了一个目标检测的模型:LeNet-5,随后在2012年ImageNet竞赛上,基于CNN网络的AlexNet取得了第一,且正确率超出第二近10%,取得了历史性的突破。CNN开始大放异彩,VGG Net,Google Net,ResNet等,都是基于CNN网络的一些杰出的工作。

LeNet

非常经典的网络结构,具体不介绍了,直接贴个结构图:

  • 输入层,尺寸大于任何一个字母,以保证每个字母都会出现在第七层单元的感受野的中心。
  • 中间五层分别是:卷积层→降采样层→卷积层→降采样层→卷积层。
  • 第一个卷积层使用了六种滤波器,因此具有六个通道的 feature maps 。
  • 第二个卷积层上升到16个通道。每一个通道与前6个通道的关系都不一样,见上图,目的是破坏对称性,迫使每个通道学习不同的特征(理想情况是互补特征)。
  • 在全连接层,特征进行内积和非线性激活。
  • 最后是输出层,10种数字对应10个输出单元,分别计算输出向量和该分类参考向量的欧式距离。
  • loss 为 MSE loss,输出向量和分类参考向量最近则将其判为这一类。

可以看出来,这是一个识别字母的神经网络。首先经过一次卷积滤波处理,得到了C1(卷积层 Feature map),然后又经过了一次下采样(池化)处理得到了S2(下采样层),之后又是一次卷积滤波得到C3卷积层,依次处理至途中的C5位全连接层,至此卷积的过程结束,被抽象的特征输入至传统的全连接神经网络,之后就又是熟悉的节奏了。

AlexNet

2012 年 AlexNet 在 ImageNet 2012 图像识别挑战赛上一鸣惊人,证明了学习到的特征可以超越手工特征,结构如下:

该网络有以下的创新:

ReLU

之前使用的 tanh 和 sigmoid 激活函数都存在饱和区。改用无饱和的 ReLU ,收敛速度可以达到数倍于 tanh !

BTraining on Multiple GPUs

2个 GPU 协同,最直接的作用是加快了训练速度。作者尝试将网络改为单GPU,同时保证参数数量不变,速度略逊于双 GPUs 。

Overlapping Pooling

实验证明,重叠池化可以更好地抑制过拟合,使准确率提高约0.4%和0.3%。

Data Augmentation

最简单的抑制过拟合技术,就是 label-preserving transformations 。简单来说,就是让图像进行各种不影响目标本质的变换,扩大数据量。

  • 镜像对称变换
  • 图像光照强度和色彩变换
    • 先提取 RGB 三通道分量;
    • 对每一个通道分别进行主成分分析,提取出主成分;
    • 然后再进行三通道的随机系数线性组合。

Dropout

dropout是一种防止过拟合的正则化技术,具体做法是,对每个隐藏层的输入进行一个概率判决,比如我们设置概率为0.5(通常命名为keep_prob),根据0.5,随机生成一个跟隐藏层神经元个数相同的向量,true:false的比例是1:1(因为keep_prob=0.5),与隐藏层的神经元进行相乘,那么会有一半隐藏层的神经元被舍弃,不参与训练。重复迭代上诉操作。

如果我们有多个不同的模型合作进行预测,那么泛化误差将会有效降低。问题是,训练多个模型的计算成本很高昂。Dropout 为我们提供了新思路:让这些模型分享相同的权重系数,但神经元的输出结果不尽相同。具体而言,是让 hidden neuron 的输出有50%的概率被置零。这样,每次反向传播时,参考的 loss 都是由不同模型计算得到的。总的来说,Dropout 技术打破了神经元之间的依赖性,强迫网络学习更鲁棒的神经元连接。我们只在全连接层使用,因为全连接层的连接非常多。在测试阶段不采用 Dropout 。Dropout 会延长收敛时间,但能有效抑制过拟合。

VGGNet

AlexNet 取得了很不错的成绩,但问题在于这个过程太过于经验化,我们没办法借鉴太多经验设计其他网络(这并不代表 AlexNet 不行,相反,更是很伟大的突破)。而 VGG 就提出可以通过重复使用简单的基础块来构建深度模型。

VGG 块的组成规律是:连续使用多个相同的 padding 为 1,kernel size 为 3×3 的卷积层后,接上一个 stride 为 2,kernel 为 2×2 的最大池化层。卷积层保持输入的尺寸不变,而池化层则对其减半。

AlexNet和 VGGNet的对比如下图所示:

NiN

NiN 是网络中的网络,使用的窗口形状为 11×11, 5×5, 3×3,每个 NiN 块后接一个 stride 2,窗口 3×3 的最大池化层。最大的不同时 NiN 去掉了 AlexNet 的最后 3 个全连接层,用输出通道数等于标签类别数的 NiN 块,然后用全局平均池化并直接用于分类,可以显著减小模型参数尺寸,缓解过拟合,但是训练时间一般要增加。

GoogLeNet

GoogLeNet 在 2014 年的 ImageNet 图像识别挑战赛中大放异彩,吸收了 NiN 中网络串联网络的思想,并做了很大改进。这个model证明了一件事:用更多的卷积,更深的层次可以得到更好的结构。(当然,它并没有证明浅的层次不能达到这样的效果)

GoogLeNet 中的基础卷积块叫做 Inception,结构如下图所示:

可以看到一个 Inception 块中有 4 条并行的线路,我们可以自定义每层输出的通道数,借此来控制模型复杂度。注:卷积部分使用了 5 个 block,每个 block 之间使用 stride 2 的 3×3 最大池化层来减小输出宽度

ResNet

理论上来说,我们不断添加层,模型精度应该越来越高,但是实际情况并非如此,甚至可能变得更差了。为了解决这个问题,何恺明等人提出了残差网络 ResNet,夺得了 2015 年 ImageNet 冠军。

我们先来看看残差块的设计:

  • 左图:输入 x,希望虚线部分能够学习出 f(x)
  • 右图:输入 x,希望虚线部分能够学习出 f(x) – x,更容易学习,x 也可以通过跨层的数据线路更快向前传播

这个思路非常深刻影响了未来的神经网络设计,为了能够让 f(x)-x 和 x 相加,可能需要引入 1×1 的卷积层来变化尺寸。

DenseNet

DenseNet 可以看作是 ResNet 的发展创新,对比如下:

  • 左边:ResNet,A 的输出和 B 的输出相加(这就需要维度一致)
  • 右边:DenseNet,A 的输出和 B 的输出拼起来

DenseNet 主要通过 dense block(确定输入和输入如何连接)和 transititon layer(控制通道数量)构成。

参考链接:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注