深度学习之卷积神经网络CNN及tensorflow代码实现示例

时间:2024-05-19 13:44:57

卷积神经网络简介

卷积神经网络(convolutional neural network,CNN)最初是用来解决图像识别等问题设计的,随着计算机的发展,现在CNN的应用已经非常广泛了,在自然语言处理(NLP)、医药发现、文本处理等等中都有应用。这里我们着重分析CNN在图像处理上的应用。

在早期图像处理识别研究中,最大的问题是如何组织特征,这是因为图像数据不像其他类型的数据可以通过人工理解来提取特征。在图像中,我们很难根据人为理解提取出有效的特征。在深度学习广泛应用之前,我们必须借助SIFT、HoG等特征提取算法结合SVM等机器学习算法进行图像处理识别。

CNN作为一个深度学习架构被提出的最初诉求,是降低对图像数据预处理的要求,以及避免复杂的特征工程。CNN可以直接使用图像作为输入,减少了许多特征提取的手续。CNN的最大特点在于卷积的权值共享结构,大幅度的减少神经网络的参数,同时防治了过拟合

CNN的提出

CNN概念最早来自感受野(Receptive Field),科学家对猫的视觉皮层细胞研究发现,每一个视觉神经元只会处理一小块区域的视野图像,即感受野

深度学习之卷积神经网络CNN及tensorflow代码实现示例

后来,提出神经认识机(Neocognitron)概念,神经认识机包含两类神经元,用来抽取特征的S-cells,还有用来抗形变的C-cells。S-cells对应CNN中的卷积滤波操作,而C-cells则对应**函数、最大池化等操作

深度学习之卷积神经网络CNN及tensorflow代码实现示例

所以说吧,最厉害的计算机还是大脑.

CNN的壮大

在最近的时间里,CNN最先是在ImageNet上大放光彩,随后被大众熟知,一直到现在成为图像处理的利器。先说说ImageNet.

ImageNet是一个基于WordNet(一个大型语义库)的大型图像数据库。在ImageNet中,将近1500万图片被关联到WordNet的大约20000个名词同义词集上,可以被认为是分类问题的一个类别。ImageNet每年都会举办图像识别相关的竞赛(ILSCVRC)。

深度学习之卷积神经网络CNN及tensorflow代码实现示例

深度学习之卷积神经网络CNN及tensorflow代码实现示例

先总体上对CNN有一个了解,下面该细致的剖析CNN的每个部分




卷积神经网络结构

学习CNN的结构之前,可以先到点这里 这个可视化应用上看看CNN的执行流程。
深度学习之卷积神经网络CNN及tensorflow代码实现示例

看完后,我们来对比一下CNN与传统神经网络的区别。下图显示了全连接神经网络的结构和CNN的结构对比

深度学习之卷积神经网络CNN及tensorflow代码实现示例
深度学习之卷积神经网络CNN及tensorflow代码实现示例
深度学习之卷积神经网络CNN及tensorflow代码实现示例

可以看到,CNN相对全连接神经网络所使用的权值参数大大减少了

卷积神经网络的常见网络结构

常见的架构图如下:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

从一个实际的图片类型识别角度来看:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

总结下来, 一般来说,一个卷积神经网络主要由以下结构组成:

  • 输入层
    输入层是整个神经网络的输入,一般代表的是图片的像素矩阵(一般为三维矩阵,即像素x像素x通道)

  • 卷积层
    卷积层试图从输入层中抽象出更高的特征。

  • 池化层
    保留最显著的特征,提升模型的畸变容忍能力。

  • 全连接层
    图像中被抽象成了信息含量更高的特征在经过神经网络完成后续分类等任务。

  • 输出层
    一般是使用softmax输出概率值或者分类结果。

在CNN中使用的输入层、输出层、全连接层在前面章节已经介绍过了,下面重点介绍卷积层、池化层。

卷积

再说卷积层之前,我们先谈谈什么的卷积。

信号处理中的卷积

说到卷积,我这个学工科的,最先想到的就是信号处理里面的”线性卷积”、”圆周卷积”,这些怪东西里面的卷积都出自同一个公式。公式如下:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

我们可能对这个公式的计算忘得差不多了,但是我们要记得信号处理中的卷积作用:一个函数(f)在另一个函数上(f)的加权叠加。下面我们来对比图像处理中的卷积。

更多卷积的理解可以点这里

图像处理中的卷积

在学习图像处理课程时,接触到了图像卷积。图像处理中的许多操作我们都可以看做是卷积的应用,例如:高斯滤波、均值滤波、膨胀、腐蚀等.

图像处理中的卷积计算,会先定义一个卷积核,而这个卷积核就是定义一个滤波器,卷积核与输入信号做加权叠加得到输出.
也可以理解为二维变量的离散卷积,无论哪种卷积都离不开加权叠加的要义。

图像卷积示例如图:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

Kernel即定义的卷积核,Kernel与原图像(同等大小的区域)对应的加权叠加得到的值即为输出。

到这里,我们应该对卷积有了一个直观的认识了。

CNN内的卷积层处理和图像处理中的卷积非常相似,下面主要讲讲图像处理中的卷积类型与特点。

卷积的类型的参数

一个常见的卷积过程:

深度学习之卷积神经网络CNN及tensorflow代码实现示例

(蓝色为输入数据、阴影为卷积核、绿色为卷积输出)
输入尺寸大小为:4x4
滤波器尺寸大小为:3x3
输出尺寸大小为:2x2

在卷积过程中:有一个步长(stride)参数:步长即每次filter移动的间隔距离。这里stride=1;
如果难以理解stride的含义,看下一个例子。


下图为stride=2(横竖两个方向上)的卷积过程:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

输入尺寸大小为:4x4
滤波器尺寸大小为:3x3
输出尺寸大小为:2x2

从上两个例子可以看出,只要滤波器的尺寸不是1x1,那么输出尺寸必定会小于输入尺寸大小,而在实际的图片处理过程中,许多时候我们需要保持图像的大小不变,以便于图像的处理。为了保持输入和输出尺寸一致,同时也有卷积的效果。我们可以对输入图片的外圈做填充操作。

这里我们引入了另外一个参数:padding. zero-padding即在输入的外圈补零的圈数(这里为什么要补零,而不是其他数字:是因为数字零对卷积贡献为零,不会产生额外的偏差).

如果难以理解zero-padding的含义,看下一个例子。


下图为输入图像外圈补一圈零,即padding=1的卷积过程:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

输入尺寸大小为:5x5
滤波器尺寸大小为:3x3
输出尺寸大小为:5x5

可以看出输入和输出的尺寸大小一致


到这里,我们可以给出输入尺寸、输出尺寸、滤波器尺寸、stride和padding的关系:

输入图片的尺寸大小W1 x H1

卷积核(又称滤波器,以下都称滤波器)的大小F x F

输出图片的尺寸大小W2 x H2

stride:S padding:P

关系式如下:
W2
= (W1-F+2P)/S + 1
H2 = (H1-F+2P)/S + 1


除了上述的卷积类型,还有如下的卷积:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

深度学习之卷积神经网络CNN及tensorflow代码实现示例

更多卷积类型可参考点这里

讲完了各式各样的卷积类型,下面该回归主题,讲讲CNN里面的卷积层了

卷积层

在CNN中,每一个卷积层会直接接受图像像素级输入,每一个卷积操作只会处理一小块图像,经过卷积变换后再传到后面的网络,每一层卷积都会提取数据特征,再经过组合和抽象形成更高阶的特征

卷积层原理

下面剖析一个卷积层的原理:

  • 1.
    一张32x32x3的图片(大小为32x32的3通道图片),滤波器大小为5x5x3(滤波器的深度必须与输入层的深度相同).
    深度学习之卷积神经网络CNN及tensorflow代码实现示例

  • 2.
    卷积运算同样也是通过向量运算实现的,这里我们把滤波器的值甩成一列向量W.(W大小为75x1).
    同时从输入图片中取同样大小的输入数据X(X大小也为75x1),

    :ωTx+b.(bbias.)

    每一次卷积的输出是一个数值,所以输出层的深度变为1.

深度学习之卷积神经网络CNN及tensorflow代码实现示例

  • 3.
    一次完整的卷积过程后,得到一个28x28x1大小的输出图(这里又称为activation maps).

深度学习之卷积神经网络CNN及tensorflow代码实现示例

如果我们有6个5x5的滤波器,会得到一个6个28x28x1的输出图,那么叠加到一起就得到28x28x**6**的输出层
深度学习之卷积神经网络CNN及tensorflow代码实现示例

  • 4.
    多个卷积层之间连接一起(多层之间又经过了**函数),从低层的特征抽象到高层的特征.
    (这里其实有一个问题:就是多个卷积层直接连接,图像的尺寸会迅速下降,这不是我们想要的,在这里我们可以前面提到的zero-padding来维持输入输出尺寸一致)
    深度学习之卷积神经网络CNN及tensorflow代码实现示例

实际图片处理过程如下:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

到这里,我们讲完的卷积层的运算原理.

卷积层算法

这里我们重点讲解一下输入与输出的尺寸运算,直接引用了cs231n的课件如下:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

卷积层特点

一般卷积神经网络由多个卷积层构成,每个卷积层中通常会进行如下几个操作。

  1. 图像通过多个不同的卷积核的滤波,并添加偏置(bias),提取局部特征,每一个卷积核会映射出一个新的2D图像
  2. 将前面卷积核的滤波输出结果,进行非线性的**函数处理
  3. 对**函数的结构再进行池化操作(即降采样,后面会详细讲解),目前一般使用最大池化,保留最大特征,提示模型的畸变容忍能力

这几个步骤构成了常见的卷积层,当然也可以再加上LRN(Local Response Normalization,局部响应归一化层),还有Batch Normalization等.

权值共享

每一个卷积层中使用的过滤器参数是相同的,这就是卷积核的权值共享,这是CNN的一个非常重要的性质。

  • 从直观上理解,共享卷积核可以使得图像上的内容不受位置的影响,这提高了模型对平移的容忍性,这大大的提高了模型提取特征的能力
  • 从网络结构上来说,共享每一个卷积层的卷积核,可以大大减少网络的参数,这不仅可以降低计算的复杂度,而且还能减少因为连接过多导致的严重过拟合,从而提高了模型的泛化能力

权值共享与传统的全连接的区别如下图:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

多卷积核

在每一个卷积层中,会使用多个卷积核运算,这是因为每一个卷积核滤波得到的图像就是一类特征的映射,我们提供越多的卷积核,能提供多个方向上的图像特征,可以从图像中抽象出有效而丰富的高阶特征
深度学习之卷积神经网络CNN及tensorflow代码实现示例


池化层

在通过卷积层获得输入的特征时,我们需要做的利用这么特征继续做分类运算。但是针对多个卷积核下的输出特征,依旧会面临着超庞大的参数运算,为了解决这个问题,我们依旧需要减少参数量。这里我们琢磨下,在使用卷积层时,是因为卷积运算可以有效的从输入中提取特征,我们可以对特征做再统计。这一再统计既要能够反映原输入的特征,又要能够降低数据量,我们很自然的想到了取平均值、最大值。这也是池化操作。

池化层原理

从CNN的总体结构上来看,在卷积层之间往往会加入一个池化层(pooling layer).池化层可以非常有效地缩小图片的尺寸。从而减少最后全连接层的参数,在加快计算速度的同时也防止了过拟合的产生。

池化层前向传播过程类似于卷积层的操作一样,也是通过移动一个类似滤波器的结构完成的,不同于卷积层的是,池化层的滤波器计算不是加权求和,而且求区域内的极大值或者平均值。

  1. 使用最多的是最大值操作的池化层,又称最大池化层(max pooling),计算图像区域内最大值,提取纹理效果较好.
    深度学习之卷积神经网络CNN及tensorflow代码实现示例

  2. 使用平均值操作的池化层,又称平均池化层(mean pooling),计算图像区域的平均值,保留背景更好
    深度学习之卷积神经网络CNN及tensorflow代码实现示例

  3. 随机池化(Stochastic-pooling),介于两者之间,通过对像素点按照数值大小赋予概率,再按照概率进行亚采样
    深度学习之卷积神经网络CNN及tensorflow代码实现示例

池化层算法

这里我们重点讲解一下输入与输出的尺寸运算,还是引用了cs231n的课件如下:
深度学习之卷积神经网络CNN及tensorflow代码实现示例

池化层特点

池化单元的平移不变性

这类似于卷积层的平移不变性。

显著减少参数数量

降采样进一步降低了输出参数量,并赋予模型对轻度形变的容忍性,提高了模型的泛化能力


代码实现:步骤:
1.