龙空技术网

机器学习: 卷积神经网络 (CNN)

昌华量化 218

前言:

此时各位老铁们对“cnn等于ann”大概比较着重,同学们都需要分析一些“cnn等于ann”的相关知识。那么小编也在网摘上网罗了一些关于“cnn等于ann””的相关内容,希望同学们能喜欢,朋友们快快来了解一下吧!

卷积神经网络模型(CNN Model)

传统的人工神经网络(Artificial Neural Network)在图像处理中面临的主要问题是:

- 处理的数据量太大,导致成本很高,效率很低

- 参数太多,并且存在过度拟合

- 图像在数字化的过程中很难保留原有的特征,导致图像处理的准确率不高

卷积神经网络模拟人类的视觉原理,对观察到的物体进行逐层抽象来进行认知。如下图所示,底层的特征是从原始的像素中抽取的边缘信息;往上一层,通过对底层信息的组合得到物体的一些相应特征(比如零部件的信息);到最上层,不同的高级特征组合成图像,使人准确识别物体。

卷积神经网络简称 CNN,模拟人类的视觉模型,利用卷积 (convolution),池化 (pooling) 和 全连接层 (fully connecting) 技术专注于繁杂信息中的最重要部分,从而减少了参数的数量,使模型更快收敛到最优解。

CNN 网络结构

以下是一个简单的CNN结构。从图中可以看到CNN 不同于普通 ANN 的组成部分:卷积(Convolution),池化(Pooling),全连接层 (fully connected)。

卷积(Convolution)

Convolution 是一个线性变换。可以被视作一个过滤器(filter)。这个过滤器作用在输入特征值的每一个(部分重合的)子集,其结果是特征值的映射(feature map)。

将 convolution 引入深度学习的一个好处,是这个过滤器的值本身可以被看做是网络的权重的一部分,从而其最优值是在模型训练过程中由算法来决定的。

以下是 convolution 的一个简单例子。其中 filter 就是 convolution 的具体实现;它作用在 input feature 的每一个子集,也就是图中的 input;当 filter 扫描整个 input feature,并且作用在 input feature 的所有重叠子集之后,产生的映射集合就是 feature map。

以下是卷积的动图示例,底层是维度为 4x4 的输入数据,作用一个 3x3 的卷积之后,结果是 2x2 的图像。

换个角度来理解卷积,可以把卷理解为使用一个过滤器来过滤图像的各个小区域,从而得到这些小区域的特征值。

在具体应用中,往往有多个卷积,即,每个卷积代表了一种图像模式。图像上有多种底层纹理模式,也就是我们用多种基础模式就能描绘出一副图像。如果某个图像块与此卷积核卷积出的值大,则认为此图像块十分接近于此卷积。

通过卷积的过滤提取出图片中局部的特征,和人类视觉的特征提取过程类似。

池化(Pooling)

池化的主要作用是降低数据的维度。池化也可以理解为是个采样过程。经过卷积作用,图像可能仍然很大,特别是当卷积比较小的时候。这时候,池化的作用相比卷积可以更有效的降低数据维度,并且可以有效避免过度拟合。

下图是池化的例子。左边的矩阵是 convolution 的结果,也就是 feature map。对 feature map 中的信息抽取压缩的过程就是池化。在例子中,对每一个 featue map 中的2x2的矩阵抽取最大值。第一个矩阵的最大值是 max(1,1,5,6)=6。依此类推。

全连接层 (fully connected)

原始图像经过卷积和池化,数据维度大大降低,主要特征信息被抽取。作为 CNN 的最后一步,数据输入到全连接层。

值得注意的是,典型的 CNN 可能包含多层结构,例如上图 CNN 的结构中,卷积和池化较低使用,最后有两层全连接层。

CNN 应用

CNN 主要应用在以下领域:

- 图像分类、检索、识别

- 目标定位检测:比如汽车自动驾驶,医疗

- 目标分割:图像前景和背景进行像素级的区分,视频加工

- 人脸和人体识别

CNN 程序实现

以 keras 为例,在导入 CNN 软件包以后,常被调用的函数是 Sequential(),Conv2D() 和 MaxPooling2D()。

软件包调用

以下是常被调用的软件包:

>>> from keras.models import Sequential>>> from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

常用函数

其中,函数 Sequential() 被用于初始化一个 CNN 模型。

Conv2D() 用于构建卷积层,从输入的高维数组中提取特征。卷积层的每个过滤器相当于一个神经元,是一个特征映射,用于提取某个特征。过滤器的数量决定了卷积层的输出深度,即输出特征个数。因此,图片等高维数据经过卷积层处理以后,深度都会增加。

keras 中调用 Conv2D() 的标准形式为:

>>> Conv2D(filters, kernel_size, strides, padding, activation=‘relu’, input_shape)

其中的参数释义:

- filters:过滤器或者卷积核的数目,等于数据经过卷积处理以后的输出维度

- kernel_size:指定卷积窗口的高和宽,是由单个整数或由两个整数构成的list/tuple。如为单个整数,则表示在各个空间维度的相同长度窗口

- strides:卷积步长, 默认为 1。单个整数或由两个整数构成的list/tuple。如为单个整数,则表示在各个空间维度的相同步长

- padding:卷积如何处理边缘。选项包括 ‘valid’ 和 ‘same’,默认为 ‘valid’。

"valid"表示不填充,即只进行有效的卷积,对边界数据不处理。例如,图像28*28,过滤器5*5,步长为5,最后三行三列舍弃,输出大小为:[(28-3-5)/5]+1=5,即输出图像是5*5的。

‘same’表示填充,当滑动步长大于1时:填充数=K-I%S(K:卷积核边长,I:输入图像边长,S:滑动步长),滑动步长为1时,填充数是卷积核边长减1。例如,5*5的图用3*3的核,步长为1时same填充之后是7*7代表保留边界处的卷积结果

- activation:激活函数,通常设为 relu。如果未指定任何值,则不应用任何激活函数。

- input_shape:输入层的高度,宽度和深度的元组。当卷积层作为模型第一层时,必须提供此参数,否则不需要

MaxPooling2D 用于构建最大池化层。如果说,卷积层通过过滤器从高维数据中提取特征,增加了输出的深度(特征数),那么,最大池化层的作用是降低输出维度(宽高)。在 CNN 架构中,最大池化层通常出现在卷积层后,后面接着下一个卷积层,交替出现,结果是,输入的高维数组,深度逐次增加,而维度逐次降低。最终,高维的空间信息,逐渐转换成 1 维的特征向量,然后连接全联接层或其他分类算法,得到模型输出。

MaxPooling2D() 的标准形式为:

>>> MaxPooling2D(pool_size, strides, padding)

其中的参数释义:

- pool_size:指定池化窗口高度和宽度的数字

- strides:垂直和水平 stride。如果不指定任何值,则 strides 默认为 pool_size

- padding:选项包括 valid 和 same。如果不指定任何值,则 padding 设为 valid

作为一个在卷积层后面添加最大池化层,降低卷积层的维度的例子,假设卷积层的大小是 (100, 100, 15),希望最大池化层的大小为 (50, 50, 15)。要实现这一点,可以在最大池化层中使用 2x2 窗口,stride 设为 2:

>>> MaxPooling2D(pool_size=2, strides=2)
关于 步幅(strides) 和 填充(padding)

padding 的例子

填充(padding)是指在输入高和宽的两侧填充元素(通常是0元素)。下图中,原输入是3x3的(即0,1,2,... 8)。我们在原输入高和宽的两侧分别添加了值为0的元素,使得输入高和宽从3变成了5,并导致输出高和宽由2增加到4。

strides 的例子

卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅(stride)。下图的例子中,在高上步幅为3、在宽(即水平方向)上步幅为2的二维互相关运算。

以下是一个同时具有 padding, strides 的卷积的动图。其中 strides 在高和宽上的步幅都是2。

CNN 建模流程

使用CNN 建立一个完整的模型,包括从读入数据,建立模型,训练模型,到预测新数据,一般包含以下几个主要步骤。完整的源代码请参考互动教程。

初始化 CNN 模型

以 keras 为例,加载用到的软件包:

>>> from keras.models import Sequential>>> from keras.layers import Dense, Conv2D, Flatten

其中Dense, Conv2D, Flatten 用于建立相应的网络层。下面的命令行初始化一个神经网络:

>>> model = Sequential()

模型初始化以后,建立层(layer)。首先建立两层 2 维的 convoluitonal layer:调用函数 Conv2D()。其中的输入参数为:

- 每一层的神经元数量。这里第一层有64个,第二层有32个;

- kernel_size: 是 convolution,也就是 filter 的尺寸。这里我们对每一个 3x3 pixel的正方形区域做变换,所以设为3;

- activation: 是在 convolution 变换之后使用的 activation function。这里 relu 是最常用的函数;

- input_shape: 输入图像的尺寸(28x28)和深度(1)。

>>> model.add(Conv2D(64, kernel_size=3, activation='relu', input_shape=(28,28,1)))>>> model.add(Conv2D(32, kernel_size=3, activation='relu'))

加上一层展开层,将两个convolution 之后的特征值转化为最后一层可以输入的类型

>>> model.add(Flatten())

最后一层输出层的类型是 dense,它有两个输入参数:

- 输出的维度:这里是10,因为我们的目标值是10维的向量;

- activation function 类型:softmax 将之前 dense layer 的输出作为输入,并转化为每一个预测的概率。最后的预测取概率最高的值;

>>> model.add(Dense(10, activation='softmax'))

模型编译

指定优化算法,损失函数,和模型精度的度量方式。

>>> model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

数据拟合

设置好的模型对训练数据训练,获得最优的模型。

>>> model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3)

预测新数据

训练好的模型对新数据预测目标值。

>>> model.predict(X_test[:4])

标签: #cnn等于ann