⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计3077字,阅读大概需要3分钟
🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号:不懂开发的程序猿
个人网站:https://jerry-jy.co/
基于卷积神经网络的手写数字识别
- 基于卷积神经网络的手写数字识别
- 一、任务需求
- 二、任务目标
- 1、掌握神经网络的卷积操作
- 2、掌握卷积神经网络的分层
- 3、掌握卷积层的参数及配置
- 4、掌握池化层的参数及配置
- 三、任务环境
- 1、jupyter开发环境
- 2、python3.6
- 3、tensorflow2.4
- 四、任务实施过程
- (一)、数据集查看
- (二)、卷积神经网络构建
- (三)、卷积神经网络训练与评估
- 五、任务小结
基于卷积神经网络的手写数字识别
一、任务需求
我们这里要解决的问题是,将手写数字的灰度图像(28 像素×28 像素)划分到10个类别中(0~9)。我们将使用 MNIST 数据集,它是机器学习领域的一个经典数据集,这个数据集包含60000张训练图像和10000张测试图像,由美国国家标准与技术研究院在20世纪 80年代收集得到。我们先来看一个简单的卷积神经网络示例,即使用卷积神经网络对MNIST数字进行分类,这个任务我们在前面章节使用全连接网络做过。虽然本例中的卷积神经网络很简单,但其精度肯定会超过前面章节的全连接网络。
下列代码将会展示一个简单的卷积神经网络。它是 Conv2D 层和MaxPooling2D层的堆叠。
卷积神经网络接收形状为 (image_height, image_width, image_channels)的输入张量(不包括批量维度)。本例中设置卷积神经网络处理大小为 (28, 28, 1) 的输入张量,这正是 MNIST 图像的格式。我们向第一层传入参数 input_shape=(28, 28, 1) 来完成此设置。
二、任务目标
1、掌握神经网络的卷积操作
2、掌握卷积神经网络的分层
3、掌握卷积层的参数及配置
4、掌握池化层的参数及配置
三、任务环境
1、jupyter开发环境
2、python3.6
3、tensorflow2.4
四、任务实施过程
(一)、数据集查看
1、导入相关类库,划分训练集和测试集
import tensorflow.keras
from tensorflow.keras.datasets import mnist
from matplotlib import pyplot as plt
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
#train_images 和 train_labels 组成了训练集(training set),模型将从这些数据中进行学习。
#然后在测试集(test set,即 test_images 和 test_labels)上对模型进行测试。
train_images 和 train_labels 组成了训练集(training set),模型将从这些数据中进行学习。然后在测试集(test set,即 test_images 和 test_labels)上对模型进行测试。
图像被编码为 Numpy 数组,而标签是数字数组,取值范围为 0~9。图像和标签一一对应。
2、可视化训练集输入特征的第一个元素
plt.imshow(train_images[0]) # 绘制图片
plt.show()
3、查看训练数据的特征维度和标签数量
train_images.shape
len(train_labels)
4、查看训练数据的标签
train_labels
5、查看测试数据的特征维度和标签数量
len(test_labels)
6、查看测试数据的标签
test_labels
(二)、卷积神经网络构建
接下来的工作流程如下:
首先,将训练数据(train_images 和 train_labels)输入神经网络;
其次,网络学习将图像和标签关联在一起;
最后,网络对 test_images 生成预测, 查看网络模型的指标。
1、我们来构建网络。
from tensorflow.keras import layers
from tensorflow.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'))
2、查看目前卷积神经网络的架构。
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 3, 3, 64) 36928
=================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0
_________________________________________________________________
可以看到,每个 Conv2D 层和 MaxPooling2D 层的输出都是一个形状为 (height, width,channels) 的 3D 张量。宽度和高度两个维度的尺寸通常会随着网络加深而变小。通道数量由传入 Conv2D 层的第一个参数所控制(32 或 64)。
3、下一步是将最后的输出张量[大小为 (3, 3, 64)]输入到一个密集连接分类器网络中, 即 Dense 层的堆叠。这些分类器可以处理 1D 向量,而当前的输出是 3D 张量。 首先,我们需要将 3D 输出展平为 1D,然后在上面添加几个 Dense 层。
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
4、我们将进行 10 类别分类,最后一层使用带 10 个输出的 softmax 激活。现在网络的架构如下。
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 3, 3, 64) 36928
_________________________________________________________________
flatten (Flatten) (None, 576) 0
_________________________________________________________________
dense (Dense) (None, 64) 36928
_________________________________________________________________
dense_1 (Dense) (None, 10) 650
=================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0
_________________________________________________________________
在进入两个 Dense 层之前,形状 (3, 3, 64) 的输出被展平为形状 (576,) 的 向量。
(三)、卷积神经网络训练与评估
1、我们在 MNIST 数字图像上训练这个卷积神经网络。
from tensorflow.keras.utils import to_categorical
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'])
history=model.fit(train_images, train_labels, epochs=5, batch_size=64)
训练过程中显示了两个数字:一个是网络在训练数据上的损失(loss),另一个是网络在训练数据上的精度(acc)。
我们很快就在训练数据上达到了 0.994(99.4%)的精度。
2、现在我们来检查一下模型在测试集上的性能。
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('test_acc:', test_acc)
全连接网络的测试精度为 97.8%,但这个简单卷积神经网络的测试精度达到了99.4%,我们将错误率降低了 68%(相对比例)。
五、任务小结
本任务通过卷积神经网络完成了我们在以前章节做过的手写数字识别实验。我们可以看到使用卷积神经网络后,相对于
全连接的神经网络精度提高、错误率降低。展现了卷积神经网络的强大威力。通过本任务需要掌握卷积神经网络的模型构建过程、卷积神经网络的分层结构和测试过程。
–end–