【Deep learning】卷积神经网络CNN结构

写在前面

今天不想写。


1.卷积神经网络(CNN)简介

直接贴出这张CNN最经典的图。从图中也可以出,其实CNN和传统的深度神经网络相差不多,唯一的区别就在于神经网络中相邻两层的连接方式。那么,问题来了,为什么CNN要选择不一样的连接方式呢(神经网络中使用的为全连接方式,即相邻两层之间所有神经元都有连接)???

首先是数据数量级问题,我们知道在处理图像是输入为所选图像的像素矩阵,这个数据量是非常大的。而若使用全连接网络不难想象我们需要学习的参数会有多爆炸,直接导致计算速度的减慢。另外,参数增多还很容易导致overfitting问题。所以需要一个更为合理的神经网络结构来有效地减少神经网络中参数个数。

接下来就具体地介绍CNN的模型结构。

2.CNN的基本结构

前一节的图对于结构的描述可能没那么明显,这里就另外找了一副更加明了的示意图如下:

(1)输入层(input layer)

图中是一个图形识别的CNN模型。可以看出最左边的船的图像就是我们的输入层,计算机理解为输入若干个矩阵,这点和DNN基本相同。

(2)卷积层(Convolution Layer)

这个是CNN特有的,卷积层中每一个结点的输入只是上一层神经网络的一小块,这个小块常用大小有3x3和5x5.一般来说,通过卷积层处理过的节点会使得矩阵变的更深。卷积层的激活函数使用的是ReLU。我们在DNN中介绍过ReLU的激活函数,它其实很简单,就是ReLU(x)=max(0,x)。我们后面专门来讲。

(3)池化层(pooling layer)

在卷积层后面是池化层(Pooling layer),这个也是CNN特有的,我们后面也会专门来讲。需要注意的是,池化层没有激活函数。他不会改变三维矩阵的深度,但是可以缩小矩阵的大小,从而达到减少整个网络中参数的目的。

卷积层+池化层的组合可以在隐藏层出现很多次,上图中出现两次。而实际上这个次数是根据模型的需要而来的。当然我们也可以灵活使用使用卷积层+卷积层,或者卷积层+卷积层+池化层的组合,这些在构建模型的时候没有限制。但是最常见的CNN都是若干卷积层+池化层的组合,如上图中的CNN结构。

(4)全连接层(Fully Connected Layer)& Softmax层

在若干卷积层+池化层后面是全连接层(Fully Connected Layer, 简称FC),全连接层其实就是我们讲的DNN结构,只是输出层使用了Softmax激活函数来做图像识别的分类,这点和DNN中也一样。

3.数学上的卷积

首先,我们去学习卷积层的模型原理,在学习卷积层的模型原理前,我们需要了解什么是卷积,以及CNN中的卷积是什么样子的。

微积分中卷积的表达式为:


其离散形式为:


矩阵形式为(其中*表示卷积操作):


如果是二维的卷积,则表达式为:


在CNN中,虽然我们也是说卷积,但是我们的卷积公式和严格意义数学中的定义稍有不同,比如对于二维的卷积,定义为:


这个式子虽然从数学上讲不是严格意义上的卷积,但是大牛们都这么叫了,那么我们也跟着这么叫了。后面讲的CNN的卷积都是指的上面的最后一个式子

其中,我们叫W为我们的卷积核,而X则为我们的输入。如果X是一个二维输入的矩阵,而W也是一个二维的矩阵。但是如果X是多维张量,那么W也是一个多维的张量。

4. CNN中的卷积

有了卷积的基本知识,我们现在来看看CNN中的卷积,假如是对图像卷积,回想我们的上一节的卷积公式,其实就是对输入的图像的不同局部的矩阵和卷积核矩阵各个位置的元素相乘,然后相加得到。

举个例子如下,图中的输入是一个二维的3x4的矩阵,而卷积核是一个2x2的矩阵。这里我们假设卷积是一次移动一个像素来卷积的,那么首先我们对输入的左上角2x2局部和卷积核卷积,即各个位置的元素相乘再相加,得到的输出矩阵S的S00的元素,值为aw+bx+ey+fz。接着我们将输入的局部向右平移一个像素,现在是(b,c,f,g)四个元素构成的矩阵和卷积核来卷积,这样我们得到了输出矩阵S的S01的元素,同样的方法,我们可以得到输出矩阵S的S02,S10,S11,S12的元素。


最终我们得到卷积输出的矩阵为一个2x3的矩阵S。

再举一个动态例子,我们有下面这个绿色的5x5输入矩阵,卷积核是一个下面这个黄色的3x3的矩阵。卷积的步幅是一个像素,过程如下:


前面几个例子都是简单的二维矩阵,卷积的过程比较简单,那么如果输入是多维的呢?

再举个例子:多维卷积操作

大家打开这个例子可以看到,这里面输入是3个7x7的矩阵。实际上原输入是3个5x5的矩阵。只是在原来的输入周围加上了1的padding,即将周围都填充一圈的0,变成了3个7x7的矩阵。例子里面使用了两个卷积核,我们先关注于卷积核W0。和上面的例子相比,由于输入是3个7x7的矩阵,或者说是7x7x3的张量,则我们对应的卷积核W0也必须最后一维是3的张量,这里卷积核W0的单个子矩阵维度为3x3。那么卷积核W0实际上是一个3x3x3的张量。同时和上面的例子比,这里的步幅为2,也就是每次卷积后会移动2个像素的位置。最终的卷积过程和上面的2维矩阵类似,上面是矩阵的卷积,即两个矩阵对应位置的元素相乘后相加。这里是张量的卷积,即两个张量的3个子矩阵卷积后,再把卷积的结果相加后再加上偏置b。7x7x3的张量和3x3x3的卷积核张量W0卷积的结果是一个3x3的矩阵。由于我们有两个卷积核W0和W1,因此最后卷积的结果是两个3x3的矩阵。或者说卷积的结果是一个3x3x2的张量。

对于卷积后的输出,一般会通过ReLU激活函数,将输出的张量中的小于0的位置对应的元素值都变为0。

经过卷积层输出矩阵尺寸?

参考斯坦福cs231n课程sildes可以看出,其中N为输入矩阵尺寸,F为过滤器矩阵尺寸,stride为过滤器在输入矩阵上的滑动间隔。


经过上述操作的输出矩阵尺寸会有所减小,如果想要保持与原矩阵相同的尺寸,可以采用一种叫padding的操作。


总结一下


5. CNN中的池化层

相比卷积层的复杂,池化层则要简单的多,所谓的池化,个人理解就是对输入张量的各个子矩阵进行压缩。假如是2x2的池化,那么就将子矩阵的每2x2个元素变成一个元素,如果是3x3的池化,那么就将子矩阵的每3x3个元素变成一个元素,这样输入矩阵的维度就变小了。所以池化层可以非常有效地缩小矩阵的尺寸,从而减少最后全连接层中的参数,可以加快计算速度的同时也有防止过拟合的作用。

要想将输入子矩阵的每nxn个元素变成一个元素,那么需要一个池化标准。常见的池化标准有2个,MAX或者是Average。即取对应区域的最大值或者平均值作为池化后的元素值。

下面这个例子采用取最大值的池化方法。同时采用的是2x2的池化。步幅为2。

首先对红色2x2区域进行池化,由于此2x2区域的最大值为6.那么对应的池化输出位置的值为6,由于步幅为2,此时移动到绿色的位置去进行池化,输出的最大值为8.同样的方法,可以得到黄色区域和蓝色区域的输出值。最终,我们的输入4x4的矩阵在池化后变成了2x2的矩阵。进行了压缩。



以上~

2018.06.09

猜你喜欢

转载自blog.csdn.net/Kaiyuan_sjtu/article/details/80632935