在前面我们讨论了神经网络初步,学习了神经网络中最基础的部分:全连接层,并且实现了搭建两层全连接实现图片分类的问题,达到了50%左右的正确率,全连接层的主要思想是构建出一个映射函数,使得前一层的所有输入,都对于该层的输出产生相应的贡献,换句话说,是前一层的所有输入都参与到我们神经元的映射函数中进行计算,最终得到具体的分数向量或是对下一层新的输入。在全连接层之间,我们引入了非线性的激活函数进行约束,使最终的结果能够实现非线性的功能,一共有若干种激活函数,例如ReLU,Leaky ReLU,Tanh,Sigmoid等等,其用途和具体的作用参见https://www.cnblogs.com/Lbmttw/p/16858127.html这篇博客,相对而言说的比较明白。
今天在这里我们需要讨论的是卷积神经网络(Convolutional Neural Network)也是在各方面具有极高的用途的一个深度学习的框架。值得注意的是,在2012年,一举拿下ImageNet图像分类的桂冠的方法是AlexNet,其思想内核就是CNN!也自从CNN加入到具体的分类任务中之后,我们对于图片分类问题的准确率变得越来越高。
(该图为AlexNet的具体模型图)
CNN之所以起名叫做卷积神经网络,是因为其神经网络结构中带有卷积层;在数学中两个函数的卷积,本质上是先将一个函数翻转,然后不断的滑动并叠加。在我们卷积神经网络中,也是同样的操作。卷积层通过卷积核不断的在输入的数据上滑动,并且计算当前位置的权重值,最后进行叠加。在具体介绍卷积层之前,我们先来说一下卷积神经网络具体都由哪些结构构成:输入---卷积---激活函数---池化---卷积....---全连接---...---最终输出层。我们神经网络中的卷积,与全连接层一样,可以进行多次操作,但是需要注意的是,我们每次操作过后,都需要加一个激活函数或者叫非线性层,这个与前篇博客我们所述的神经网络计算模型高度与人体神经元仿真是相一致的。
我们先从输入层介绍:输入是一幅图像,我们经过处理后得到的是一个n*n*3的numpy数组,其中n是该图片的分辨率,也就是像素点的个数。在全连接层中,我们将这个三维的numpy数组转化为了二维的numpy数组,这么做显然可以方便我们后续的映射过程,但是相应的,破坏了原本numpy数组中每个像素点的相对位置,将三维的numpy数组硬生生reshape或者stretch成一个二维的数组,显然破坏了原本的结构,这对于我们提取图像的特征显然是不利的。而我们卷积层对于输入的数据就没有这步操作,保持了原本的空间结构的稳定性,显然,在这里,就要明显优于全连接神经网络了。
然后是卷积层,在上面我们也讨论过,卷积层中的卷积定义与数学上的卷积极为相似,通过卷积核不断的在输入的数据上滑动,每次计算出相应位置的权重并叠加。卷积层的参数由一组可学习的卷积核(Filter)组成,每一个这种Filter在空间上的尺寸都很小,但是它必须要在深度上与输入数据保证同型,例如原本的数据规模为32*32*3,其中3为RGB颜色空间的通道数,那么我们的Filter的尺寸就必须为n*m*3,n和m可以由我们指定,但是第三维度必须为3。在我们Filter不断的在输入数据上滑动的过程中,我们需要计算对应位置的点积,最终则会产生一个二维的激活图;在这个图中,每个位置对应的数字可以看做Filter在对应位置的相应,或者换句话说,卷积层在不断的提取对应位置的特征。当然,需要注意的一点是,我们卷积层中可以有很多个独立的Filter,这些Filter都具有独立的参数,或者换句话说有着独立的映射关系,每一个Filter所产生的二维激活图将会在深度方向不断叠加产生最终的输出层,也就是输出层的深度(第三维度)就是Filter的数量。
下面我们来考虑一下池化层,卷积神经网络重要的层级之一,池化层(Pooling)所起到的主要作用是对输入样本进行downsamping,起到减少参数,缩小数据规模,防止过拟合。池化层同样也需要有相应尺寸大小的Filter,尺寸大小可以由我们自由指定;我们最常用的池化Filter是2×2的Filter,池化Filter的规模以及每次池化的步长决定了缩小数据规模的程度,例如我们刚才所说2×2的Filter,在步长为2的情况下就可以缩小75%的数据规模;假设原本是4×4×n的输入数据,那么在经过池化层后,就变成了2×2×n的输出数据,显然,这缩小了75%的参数。当然,在每个Filter内部也依旧有对应的映射关系,和卷积层一样,我们的池化层Filter也需要同对应位置的输入数据进行运算,不过不同的是,一般而言池化层的映射关系往往由我们直接指定,而不是通过数据不断的更新迭代。常见的pooling有Max Pooling,Average Pooling等。在这里我们用Max Pooling举例子:
如上图所示,在这里,我们是采用了2×2的Filter,步长(stride)为2,并且Filter内部是取最大值的关系,在上图的左侧,体现的是经过池化层之前以及之后的数据规模,在右侧,体现的是max Pooling所做的操作,即在对应位置取最大值。我们从上面的例子不难看出,池化层也是对我们的数据进行局部采样,得到局部的特征。池化层很显然,也有相应的问题,舍弃了部分的数据可能导致我们的模型欠拟合等问题,但是这些都是可以通过训练轮数的增加等解决的问题。
【争议】目前对于池化层,很多人不太喜欢这个层级,认为池化层完全可以舍弃,只使用重复的卷积层构成整个卷积神经网络。他们建议偶尔在卷积层中使用更大的stride以完全替代池化层的作用(将在下面代码部分详述卷积层的stride)
然后就是全连接层,对于全连接层,前面一层所有的神经元都需要参与到后续的计算中,将所有的数据层数统一归一到一起,形成一个分数矩阵/分数向量,然后便于我们根据分数去进行判断。这个全连接层与前面神经网络初步https://www.cnblogs.com/Lbmttw/p/16858127.html这篇博客中说的很清楚,在这里就不赘述了。
以上便是卷积神经网络的一些基本的层次结构,值得注意的是,无论什么神经网络到最后的目的都很简单,就是要将损失最小化,计算loss的目的也即不断优化我们的映射关系,使得我们的神经网络能够更加逼近真实场景/做出最优的判断,在非图像分类任务中,例如图像生成等,可能损失就需要我们重新定义,但是总的来说,神经网络亦或是深度学习的基本思想便是将某个场景建模为可学习的网络结构,通过不断优化我们人为规定的损失使得网络能够更加优秀的执行我们的任务。下面是代码部分;将从几个方面分别去介绍,一个是目前的深度学习框架(keras),另一个则是完完全全将每一个步骤都实际的写出来。下面则是对于具体代码的分析:
标签:Convolutional,池化层,Network,Neural,卷积,Filter,神经网络,我们,输入 From: https://www.cnblogs.com/Lbmttw/p/16953158.html