keras实现卷积神经网络(持续更新)

CNN简介

卷积神经网络的原理十分简单,就是模仿生物的视觉。1959 年,Hubel 和 Wiesel 通过实验实验表明,生物的视觉处理是从简单的形状开始的,比如边缘、直线、曲线。凭借这一发现,Hubel 和 Wiesel 获得了1981 年的诺贝尔生理学或医学奖。
卷积神经网络在逐层学习过程中,也模拟着这个过程,第一层学习比较低层的图片结构,第二层学习依据第一层的结果学习高一级的特征,这样最后一层依据前一层学到的高级特征就能完成我们的学习任务。



比如识别动物,第一层可能学到了简单的线条,第二层学到了轮廓,倒数第几层学到了瞳孔微表情嘴形等细节,最后一层识别出了这是一只狮子。


卷积层 Convolution Layer

计算机中读取图片,图片是通过像素矩阵标识的。下图表述了像素矩阵的概念,每一个像素具有一个数值(0-255),代表图片在该信道像素点位置的大小。



信道可以理解为颜色。常用的 RGB 信道分别代表红绿蓝三种。通过把三个信道的像素矩阵叠加起来,就可以组成色彩斑斓的图片了。


在计算机中,图片是一个 的三维矩阵,其中 是矩阵的高度, 是矩阵的宽度, 是矩阵的深度。基于这样的数据结构,可以进行卷积运算。

卷积核 Convolution Kernel

接下来,我们首先需要了解卷积核的概念。如下图所示,我们现在有一个图像矩阵,同时定义了一个卷积核(权值矩阵)。


其中,卷积核的作用就是从输入矩阵(图像)中提取一定的特征:

简单来讲,我们将卷积核沿着图像矩阵的左上角开始移动,不断运算得到右边的矩阵。卷积计算的过程非常简单,就是乘法和加法的运算。例如当把卷积核置于图像矩阵的左上角时执行的运算为:
通过不断平移卷积核,同时与输入矩阵进行卷积操作,就可以得到卷积后矩阵。理解卷积的过程,最简单的就是把卷积核看作是一片滤镜,原矩阵通过滤镜之后就得到了新的特征矩阵。下图是一张图片通过不同卷积核做卷积操作后的结果,可以明显察觉到不同的卷积核可以分解出原图片不同层次的特征。

所以卷积核能够帮助分解图片特征并运用到机器学习的过程中,这将会对提升准确率有极大帮助。

卷积步长 Stride

对于一些很大的图片,在对图片卷积时,每次只移动一步运算效率会很低下,同时分解得到的特征也很容易冗余。于是,可以引入一个超参数能对每一次移动的步数进行调节,我们把它称之为卷积步长 Stride。
下面通过一组动图来查看不同卷积步长 Stride 的移动效果:
当卷积步长为 1 时,也就是和上面相同的移动过程:


此时,输出矩阵大小为:
如果将卷积步长设为 2,就是下面的效果:

可以发现,当 Stride=2 横向移动以及纵向移动时,每一步都跳过了一个单元格。也就是从移动 1 步变成了 2 步。
此时,输出矩阵大小为(向下取整):

边距扩展 Padding

步长解决了卷积效率低的问题,但又造成了新的问题:随着步长的增大,卷积输出的矩阵将持续变小。但是,在构建网络的时候我们往往希望输出矩阵的大小为指定大小,而不完全由卷积步长的变换而左右。于是,就有了 Padding 的操作。
一旦确定了原矩阵的大小和步长的大小,得到的卷积矩阵大小将是确定的。假如我们希望卷积得到的矩阵大小变大,在不改变卷积核大小和步长的前提下,唯一的方法就是调整原矩阵的大小。此时,我们可以通过对原矩阵进行 Padding 操作(扩大边距)达到目的。Padding 比较常见的操作是在输入矩阵最外围补上一圈 0 之后,再参与卷积运算。这样就可以调整输出矩阵的大小。

常见的 Padding 方式:

  • Arbitrary Padding:在输入图像周围填充 0,使输出矩阵尺寸大于输入尺寸。例如,下图对 的输入矩阵外围补上 2 圈 0 后,与 的卷积核做卷积运算,最终得到 的输出矩阵的过程。

此时,输出矩阵大小为:

  • Half Padding:也叫 Same Padding,它希望得到的输出矩阵尺寸与输入尺寸一致。下图即为我们对 的输入矩阵外围补上一圈 0 后,与 的卷积核做卷积运算,最终依然得到 的输出矩阵的过程。
  • Full Padding:卷积核从输入矩阵左角第一个方块开始,依次移动到右下角的最后一个方块。


Padding并没有特定的规则形式,可以使用 Padding 和 Stride 结合在一起的一些卷积形式,甚至可以自定义 Padding 和 Stride 的规则。

高维多卷积核过程

前面介绍了矩阵通过单个卷积核的过程,可以用来处理 1 维的像素矩阵如黑白图片。但对于 RGB 通道的彩色图片,将会形成 3 维的像素矩阵,此时需要通过多卷积核处理高维矩阵。

在卷积神经网络设计上有一个重要原则,对于一个 的三维矩阵,卷积核也是一个三维 的矩阵(通常 ,且常取 1,3,5,7 这样的数)。尤其需要注意的是,一定要保证输入矩阵大小与卷积核大小在第三个维度上值相等。

这样,我们在第三个维度上对相同深度的输入矩阵与卷积核做如上的卷积运算时,最后叠加所有深度的值得到一个二维的输出矩阵。也就是说,对 的输入矩阵与 的卷积核,我们如果做一个 , 的卷积操作,那么将会得到一个 的二维矩阵。

那么如何保证输出矩阵依然是一个三维矩阵呢?其实,只需要每一层都由多个卷积核来实现操作就行了,最后把得到的所有二维矩阵叠起来,就得到了一个 , 为卷积核的个数的输出矩阵。

整个过程可以由下图更直观地表示,一个 的输入矩阵被两个 的卷积核执行 , 卷积后,得到了 的输出矩阵:

池化层 Pooling Layer

池化操作是降采样操作过程。图片是一个非常大的训练数据,想达到很好的训练性能,只有卷积层是不够的。池化层通过降采样的方式,在不影响图像质量的情况下,压缩图片,达到减少训练参数的目的。
需要注意的是,往往在几个卷积层之后我们就会引入池化层,池化层没有需要学习的参数,且池化层在每一个深度上独立完成,就是说池化后图像的纵深保持不变。下面介绍两种常用的池化方式。

最大值池化

对于池化操作,我们需要界定一个过滤器和步长。最大值池化,取输入矩阵在过滤器大小上矩阵块的最大值作为输出矩阵对应位置输出。如下图:


平均值池化

除了最大值池化,另一个常用的池化方法是平均值池化。这是取输入矩阵在过滤器大小上矩阵块的平均值作为输出矩阵对应位置输出。如下图:


你可能感兴趣的:(keras实现卷积神经网络(持续更新))