深度学习--训练一个简单的卷积神经网路

前言

对于卷积神经网络,需要强调的是,卷积神经网络是在将数据输密集连接分类器网络(即 Dense 层的堆叠)前的一个数据变换网络,一次卷积操作是一种数据变换的形式,是一种将大数据量转化为小数据量的操作。(但是卷积神经网络是多次卷积操作,可能过滤器(filter)数量多,数据量可能会变多,但最终经过整个卷积网路的数据量是减小的。)卷积神经网络在计算机视觉任务上很成功。

一个卷积神经网络一般是卷积(Conv2D)层和池化(MaxPooling2D)层的堆叠,最后用一个全连接层(Flatten)将输出数据展平为一维向量。

一、卷积操作

1.一次卷积操作

一次卷积操作会将大数据量转化为小数据量,它是如何操作的呢,是如何将数据量变小的呢?
先形象一点的说一下卷积操作:就像在你面前地面有一副平躺着的1000×1000m的图像,你现在要看清图中画了什么,但是我们目所能及的视野就只有3×3m的视野,那怎么看清这整张图像呢,那就是每3×3的看,但你又不能把所有特征都记住,所以记住每一小块的一些有用特征,缩小到一个像素,再把它们按位置拼接起来,就能大致知道这幅图是画了什么。

卷积操作是卷积核执行的,卷积核就会把你能看到的视野缩小到一个像素,卷积核的大小代表要缩小范围。如下图,在一个5×5的输入特征图中,用一个3×3的卷积核,步幅为1进行卷积,红色方框内的9个像素点就会缩小到一个像素点,如下图1,然后卷积核就根据步幅为1向右移动一个像素再次卷积,如蓝色方框内就缩小到2号像素点,以此类推最终该5×5的图像会被缩小为图象中阴影部分的3×3图像。
在这里插入图片描述

2.整个卷积操作过程

一次卷积操作是这样子,那多次卷积操作呢,就像你在多次的慢慢将图像缩小,直到能在视野范围内看清出图像画了什么。
如下图表示多次卷积操作过程:
f表示卷积核的大小,s表示卷积核的移动步辐,filter是过滤器数量决定输出有多少通道。
卷积神经网络接收形状为 (image_height, image_width, image_channels)的输入张量(不包括批量维度即批量序号)。
图中有三次卷积操作,输入是一个(39×39×3)的三通道的图像,因为输入图像是3通道,所以卷积核也是3通道的,通过步幅为1,核大小为3×3的卷积操作后,图像大小会变成(37×37),同时该层卷积层有10个filter,图像会输出10个通道,所以经过该层后的输出数据形状为(37×37×10),接着就把该输出放入第二层进行卷积,直到卷积神经网络最后一层输出。
在这里插入图片描述
一般卷积神经网络的最后的输出张量会输入到一个密集连接分类器网络中, 即 Dense 层的堆叠,但是这些分类器可以处理 1D 向量,而卷积神经网络输出是 3D 张量。 所以输入分类器之前需要将 3D 输出展平为 1D。

3.卷积层相对全连接层的特点:

a. 卷积层(Conv2D)一层学到的是局部特征,但逐渐的拼接可以看到全局特征;而全连接层(Dense)一层学到的是全局的特征,数据量大时会有很大的计算量。
b. 卷积神经网络具有平移不变性,(平移不变性:在图像中某个地方学到的模式可以在任何地方识别这个模式),这使得卷积神经网络在处理图像时可以高效利用数据。形象点说就像卷积神经网络在某个位置学到了左耳就能判断另外一个位置的右耳;而全连接网络知道左耳是耳朵,右耳就判断不了,只能重新学习右耳。
c. 卷积神经网络还可以学到模式的空间层次结构,第一个卷积层将学习较小的局部模式(边缘),第二个卷积层将学习由第一层特征组成的更大模式,以此类推,卷积神经网络可以有效地学习越来越复杂,越来越抽象的视觉概念。(边缘->眼睛->猫)

二、池化操作

一个卷积神经网络一般不是只包括卷积层,还会包括一些池化层,为什么要做池化操作呢?
为什么要做池化操作
卷积过程中通道数量会比较大,即参数过多,模型过复杂,这会导致要计算的数据量很大,而且容易出现过拟合,因此,池化操作就是为了:
1.降维,减少运算量
2.避免过拟合,及提高范化能力
最常用的池化操作时最大池化运算,最大池化通常使用2×2的窗口和步幅2,将特征图下采样2倍,这样得到数据量将减小一赔,大大减低了需要处理的特征图的元素个数。

三、实战训练一个卷积神经网络

1.构建一个卷积神经网络:

from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

每个 Conv2D 层和 MaxPooling2D 层的输出都是一个形状为 (height, width,channels) 的 3D 张量。宽度和高度两个维度的尺寸通常会随着网络加深而变小。通道数量由传入 Conv2D 层的第一个参数所控制(32 或 64)。第二个参数(3,3)代表卷积或者池化的窗口大小。
看一下目前卷积神经网络的架构。
在这里插入图片描述

2.连接密集连接分类器网络

将最后的输出张量[大小为 (3, 3, 64)]输入到一个密集连接分类器网络中, 需要用layers.Flatten(全连接层)先将 3D 输出展平为 1D,然后在上面添加俩个 Dense 层(即密集连接分类器网络)。

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

完整的神经网络架构如下:
在进入两个 Dense 层之前,形状 (3, 3, 64) 的输出被展平为形状 (576,) 的 向量。
在这里插入图片描述

3.在mnnist数据集上训练这个卷积神经网络

#导入数据并向量化
from keras.datasets import mnist
from keras.utils import to_categorical
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

对上边构建的模型编译并将在数据集上训练模型

model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5, batch_size=64)

在这里插入图片描述
得到模型在训练集上的精度为99.43%
在测试数据上对模型进行评估。

test_loss, test_acc = model.evaluate(test_images, test_labels)
test_acc
0.99150000000000005

可以看到这个简单卷积神经网络的测试精度达到了99.15%。可以对比上一个在密集连接网络上训练mnist数据集的结果,可以发现在测试集上的测试精度为 97.8%,对比卷积神经网络将错误率降低了 68%(相对比例)。可以说是相当不错!

posted @ 2022-04-20 15:46  mariow  阅读(196)  评论(0编辑  收藏  举报