卷积神经网络 | 深度学习笔记1

时间:2022-05-03
本文章向大家介绍卷积神经网络 | 深度学习笔记1,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、初识卷积网络结构

01

概览

前面已经做过手写体识别的任务。之前我们只是使用了两层的全连接层,或者根据喜好多加几层。我更喜欢把这样的结构叫做多层感知机,即使用到了一些现代的权重初始化方式,更好的激活函数reLU等,我还是倾向于叫做多层感知机。

对于前面的这个手写体的识别任务,我们一开始就把图片展开成了一个一维的向量来做的(要是你有印象的话),虽然效果还行,但是却忽略了很重要的一点,那就是位置关系。

以这个喵的图片为例,我们的任务现在是想识别这只猫,按照之前的做法就是把这幅图片弄成一个一维向量,然后丢到网络里面去跑。但是人眼应该不是这样子的吧。虽然现在对于人眼识别东西原理还没有完全知道,但是你识别东西是先把你看到的弄成一个一维向量了去识别的?猫的鼻子下面有嘴巴,鼻子上面有眼睛,这都是很明确的位置关系,但是要是弄成了一维向量,那还有位置关系吗?也就没有了。

因此接下来就引入卷积神经网络以及卷积神经网络的一些基本概念:

局部感受野(local receptive fields) 权值共享(Shared weights and biases) 池化(pooling)

02

局部感受野(local receptive fields)

在讲局部感受野之前,首先要知道的是,这个中文名词看到很多地方都是这么翻译,所以就这么翻译了,我本人并不知道怎么翻译这个。你也可以叫做局部感知。要是都是不对你胃口,那就直接看英文就行了。

更重要的是我们不再需要将一幅图片做成一个一维向量了。比如你现在的输入是28x28,那就是28x28,或者当有颜色通道的时候,比如28x28x3,就是宽高都是28,有3个颜色通道。这个很简单很好理解。

没有图的话理解肯定是不是很直观的,这里开始搬图了。

从Deep learning 搬过来,上图就已经代表你的输入了,你原来是什么输入,不用再变成一维了,直接拿过来用就行了(可能有一些预处理什么的,但是不足以改变位置信息)

既然输入是上面这个样子了,这里就可以开始讲局部感受野了。有了输入之后,肯定要把输入连接到隐藏层的神经元了,这里应该怎么连接呢?还是像以前的全连接层那样每个输入都连接一个神经元?那肯定不是的,那样就和多层感知机没什么区别了。这里很大的一个改变就是采用了“可以滑动的窗口”。可以滑动的窗口在这里是一个非常不正规的名词,但是确是很通俗的。搬一张图片先感受一下。

图中间的那个就是可以滑动的窗口了,他的作用是和输入相应的“感受域”下的像素做运算得到新的值。这个运算就是“卷积”运算了。图上面有详细的运算过程。实际上就是每个相应元素的值相乘,然后把得到的都加起来。很简单。

重点说明,中间的这个窗口的本质是其中的数字和一个偏置构成的,非常常见的是把这个窗口叫做滤波器或者卷积核,要是看见了这两个名词,要能够知道是什么意思。

这里说两点,第一点就是上图是对于一个颜色通道的输入做卷积操作的。你看到这里只有一个通道。但是并不是意味输入只能够是一个通道。常见的三通道也是可以的。这个后面会再讲,原理差不多,很简单。

第二点就是,你看到的那个窗口是可以滑动的,你可以指定每次的滑动步长。这里太抽象,直接上经典的动图看感性理解一下。

这幅动图是一个三个通道的输入,然后“滑动窗口”的维度是3x3x3,至于为什么会是这样的维度后面会详细来讲。在这幅图片里面你暂时能够得出的信息就是他的滑动的直观理解,窗口是怎么样子的。知道这些就够了。这一节的目标就是建立一个感性的认识。等先有个模型在脑子里面,后面量化就简单了。

03

权值共享(Shared weights and biases)

你可以把滑动窗口看做是一个隐藏神经元,而窗口里面的数字就是连接输入(这里暂且看做是输入)局部感受野的上面的权重。我们的任务就是学习到这些权重来提取特征。如下图

要是这些话很难理解的话,你就记住,我们把卷积核(上面滑动的窗口)里面那些数字叫做权重,是可以学习的。我们要学习的就是窗口里面的那些数字,而这些数字对于一幅图来说都是相同的。就像动图里面的那个样子。就这么理解就行了。为什么要这个样子,后面会深入的来讲。你这里先记住。同样,一个卷积核(滑动窗口)都是带一个偏置的,同样的,偏置在整幅图上面也是一样的。

对于一幅图,你可以有多个卷积核,并不是只能够有一个。这里方便理解就没有多列出,后面详细讲。

04

池化(pooling)

原图经过一个“滑动窗口”的折腾,会得到什么呢?还是直接上图

上图是一个max pooling的过程,原理超简单,以这里为例,就是2x2的格子里面找到值最大的拿出来,所有的构成一个新的。

这个有什么用呢?上图4X4变成了2x2,数据量减少了。你自己可以通过20X20的试一下,明显会发现得到的新的map减少了。所以作用就是减少数据的量,进一步减少参数的量。参数减少了,内存会happy,速度会起来,过拟合也没有那么强烈了。这就是好处。

05

网络架构感性认识

至此,卷积网络的一些最基本的概念就在这里说了,感性认识也有了。但是还不是很系统。这里又搬过来一张图来大概的了解一下架构。

上面这幅图可以看做是一个识别车的架构。

中间交叉的有卷积层,reLU激活层,池化层(pooling),到最后的全连接层(FC),然后对类别打分,然后判断是否是车。要是前面亲手做过全连接网络版本的手写字体识别的话,这幅图很容易看懂。

至此,比较基本的结构就讲完了。这部分仅仅是非常基础的感性认识部分,并不是很困难。后面更加深入来讲卷积网络。

二、再看卷积神经网络结构

上一节我们感性认识了神经网络的基本结构,这一节更加深度的某些地方定量的来看一下卷积神经网路的结构。

这里以斯坦福的cs231n为主要的笔记来源。 Convolutional Neural Networks (CNNs / ConvNets) (http://cs231n.github.io/convolutional-networks/)

卷积神经网络的各层中的神经元是3维排列的:宽度、高度和深度

这里先解释下:一开始的时候我们讲深度,更多的是指代的神经网络的层数,在卷积层这里我们讲深度指的是数据或者filter的第三个维度。

这里的图是拿的CS231n的课件PPT

可以看到上图的图片就是一个32x32x3的图片,其中的3代表是3通道,也就是说有3个颜色通道,这个很简单。同样,这里的滤波器(filter)也是三维的结构,其中最后面的3和数据的第三个维度是一样的。这样是不是更加容易理解。

有了这个最基本的知识,就再次搬一下前面说的那幅图。

一般最基本的卷积神经网络的架构可以是:

[输入层-卷积层-ReLU层-汇聚层-全连接层]

我们使用上面的图片来大致讲解一下各层的作用:

输入层: 我更加喜欢直接叫做输入,比如上面那辆车可以抽象为[32x32x3]存有图像的原始像素值,表示宽32,高32,3个颜色通道 卷积层: 神经元与输入层中的一个局部区域相连,每个神经元都计算自己与输入层相连的小区域与自己权重的内积。也就是我们前面说过的卷积核运行的这层。 ReLU层: 将会逐个元素地进行激活函数ReLU操作,该层对数据尺寸没有改变。 Pooling层: Pooling层在在空间维度(宽度和高度)上进行降采样(downsampling)操作,数据的尺寸一般会变下。 全连接层: 将会计算分类评分,数据尺寸变为[1x1x10],其中10个数字对应的就是CIFAR-10中10个类别的分类评分值。也就是我们前面提到过得通俗意义上面的全连接层啦。

接下来就详细的一个层一个层的来讲了。

01

卷积层

卷积层肯定是卷积网络中最重要的一层啦,毕竟叫做卷积神经网络。

卷积层的参数是有一些可学习滤波器集合(前面提到过得滑动窗口)构成的。

滤波器的宽度和高度一般不大,深度和输入数据一致,这是前面说过的。见下图

上面的图的意思就是原图像是32x32x3,然后我们有一个滑动窗口(filter)为5x5x3,5x5的宽高相比起32x32来说,还是不大的,深度为3是和输入数据一样的。

一个卷积核在输入图上面滑动(见前面的动图)可以生成一个activation map(激活图?我不知道怎么翻译),激活图到底是什么东西呢?这里不理解没有关系,暂时理解为可以得到边缘呀,得到某些形状呀,得到某些特征的一个特征图就行了。之后会给出直观感性的解释。上图右边的就是activation map啦,至于28这个数字怎么来的,看一下动图就知道了,后面同样会给出计算的方法。

不同的卷积核(filter)能够得到不同的激活图,将这些激活映射在深度方向上层叠起来就生成了输出数据。所以,在用了6个filter之后,我们可以得到28x28x6的激活图。(参照图来看理论,这个计算要记得)

到这里就来一个例子来理一下,输入尺寸和滤波器尺寸之间的关系,(这里还还要注意的一个尺寸是激活图的尺寸,放到接下来讲零填充,步长等等的时候再讲怎么得到激活图的尺寸,其实超简单)

上图中,输入是32x32x3,用了6个5x5x3的滤波器,前面说过,滤波器的宽高尺寸自己定,深度为3是因为必须和输入的数据一样,用了6个滤波器,意味着接下来得到的激活图的深度是6维的。所以,接下来的激活图的尺寸为28x28x6。然后这个激活图作为输入,用了10个5x5x6的滤波器,还是那句话,滤波器的宽高尺寸自己定,但是深度为6是因为输入的深度是6,10个滤波器意味着得到的激活图的深度是6维的,即得到24x24x10.

上面的要是会了的话,就可以看窗口滑动的详细细节了。直观一点,丢一个动图。

这里可以看到是3x3的窗口,每次滑动的距离是1个,这个就叫做步长(stride)。你可以自己尝试着用笔画一下,得到的输出应该是5x5的激活图。 那么再试一下步长为2,照例丢一个动图。

那么会输出一个3x3的激活图。 那么使用步长为3呢?发现就无法很好地适配了。 这里给出一个通用的输出尺寸的计算公式:

但是有一个问题,比如下图,

每经过一个filter,得到的激活图就会小一些,要是多经过几个,那岂不是最后什么都不见啦?

所以解决的办法就叫做零填充(zero padding),其实很简单啦,就是在输入上面填充一圈或者几圈的0,就这么简单。如下图是填充了一圈的0之后的样子。

那么你会发现,N变为了N+p*2 (这里p代表圈数)为什么p乘以2呢,因为加了一圈之后两侧都加了1啊。所以N+p*2 ,那么得到新的公式为:

这个公式表示,相应原输入尺寸,步长,框口尺寸下面,加圈后得到的输出尺寸。

举例子:上面那幅图之前是7x7,也就是说N=7 ,窗口尺寸为3,即F=3 ,步长为1,stride=1 ,加了一圈即p=1

那么可以算出新的尺寸为:

还是7,意味着这样组合下面的新的尺寸是可以保持不变的。

那么,我希望加p圈保持原来的输入尺寸不变,怎么计算这个p的大小呢?初中数学啦。

到这里举两个例子复习一下:

1.输入数据是32x32x3,用了10个5x5的滤波器,步长为1,填充2圈,那么输出的尺寸是多少?这层的参数数量有多少个?

又因为使用了10个滤波器,那么可以知道输出的尺寸是32x32x10 参数数量主要是滤波器的权重和偏置。一个滤波器的话就是5*5*3+1=76个,因为有10个滤波器,那么一共有10*76=760个.

上面都是正方形的,现在来总结和通用化一些公式:

最后,再回到那个很有名的动图来:

详细地分析一下这个动图的运作过程。

首先可以得到输入(没有zero padding的原始数据)为W=5(宽度),H=5(高度),D=3(深度),意味着我需要深度为3的滤波器,至于滤波器宽高自己定义。图上来说,滤波器的宽高都是3,即F=3,深度为3(可以看到图上w0和w1都有3个分量)。而且有2个滤波器,即K=2K=2意味着我输出的深度为2(可以看到output volume有2个分量)。加了一圈的0,意味着p=1,一次移动两格,意味着s=2 那么通过这些信息,我们已经能够手算出输出的尺寸了,

知道尺寸了,现在来看具体其中的数值是怎么得到的。

首先看最开始的那一下:

第一个滤波器的不同深度的分量和输入数据相应深度的分量分别做卷积操作。 具体来说就是:

对于x[:,:,0] 的那一小块和w0[:,:,0]做卷积:即 (0*1)+(0*0)+(0*0)+(0*1)+(1*0)+(2*0)+(0*-1)+(2*0)+(0*1)=0 对于x[:,:,1] 的那一小块和w0[:,:,1]做卷积:即 (0*1)+(0*-1)+(0*1)+(0*-1)+(1*-1)+(1*0)+(0*-1)+(2*0)+(1*1)=0 对于x[:,:,2] 的那一小块和w0[:,:,2]做卷积:即 (0*1)+(0*-1)+(0*-1)+(0*1)+(0*1)+(1*1)+(0*0)+(1*-1)+(1*0)=0 最后结果为0+0+0+1=1

然后其他的每移动一个步长,都这么计算一次,得到一个结果。

02

池化层(Pooling layer)

前面已经贴过两张图片,池化层的作用就是减少feature map的空间尺寸,达到减少参数进一步达到控制过拟合的作用。

池化层并不会对于feature map的深度有影响。还是会保持原来的深度。

现在常用的pooling 操作有max pooling(最大值pooling)或者average pooling(平均值pooling)等等,以max pooling为例

上图中,pooling的尺寸是2x2,步长为2,你可以看到就是在四个格子里面选择最大的值,然后所有的组合起来,大小明显减小了。

average pooling和max pooling的不同就是前者是求均值,后者求最大值。

然后给出一组公式:

Ⅲ. Ⅳ.