【深度学习】 基于tensorflow框架的卷积神经网络CNN实现手写数字图片识别案例

前言

CNN(卷积神经网络)在图片识别领域有着广泛的应用,其中一个经典案例是使用MNIST数据集进行手写数字识别。

MNIST数据集构成如下:

  • 训练集:由来自250个不同人手写的数字构成,其中一半是高中学生的手写体,另一半来自人口普查局(the Census Bureau)的工作人员。训练集通常用于训练CNN模型,以学习如何识别手写数字。
  • 测试集:测试集也是由同样比例的手写数字数据构成,用于评估训练好的CNN模型的性能。

 文件说明

这里基于TensorFlow框架构建CNN模型来识别手写数字图片。

CNN模型构建

通过datasets库加载数据集,对加载的数据集进行归一化处理,并将数据集中的一小部分可视化。

由于MNIST数据集中的图像是灰度图像,每个像素的取值范围为0到255,其中0表示黑色,255表示白色。通过将每个像素值除以255,可以将其缩放到0到1之间的范围。这样做的目的是确保输入数据的数值范围一致,使模型更容易学习和处理。

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

# 加载MNIST数据集并归一化图像数据
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
train_images = train_images / 255.0
test_images = test_images / 255.0

# 可视化数据集中的一些示例图像
plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5, 5, i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(train_labels[i])
plt.show()

可以看到数据集加载如下:

接下来使用models.Sequential()容器构建CNN模型。该模型的结构如下:

  • 第一层是一个卷积层(Conv2D),具有32个 3x3 的过滤器,激活函数为 ReLU。输入形状为 (28, 28, 1)。
  • 第二层是一个最大池化层(MaxPooling2D),使用 2x2 的窗口进行池化。
  • 第三层是另一个卷积层(Conv2D),具有64个 3x3 的过滤器,激活函数为 ReLU。
  • 第四层是另一个最大池化层(MaxPooling2D),使用 2x2 的窗口进行池化。
  • 第五层是一个展平层(Flatten),将输出展平为一个1维向量。
  • 第六层是一个全连接层(Dense),具有64个神经元,激活函数为 ReLU。
  • 第七层是一个输出层(Dense),具有10个神经元,对应于10个数字类别,没有使用激活函数。

这个网络结构采用了交替的卷积层和池化层,以提取图像特征并逐渐减小特征图的大小。然后通过展平操作将特征图转换为1维向量,并通过全连接层进行分类。最后一层是一个具有10个神经元的输出层,用于预测输入图像的类别。

代码如下:

# 构建CNN模型
model = models.Sequential()

# 添加第一个卷积层(32个3x3的过滤器)
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))

# 添加第一个Max Pooling层(2x2窗口)
model.add(layers.MaxPooling2D((2, 2)))

# 添加第二个卷积层(64个3x3的过滤器)
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

# 添加第二个Max Pooling层(2x2窗口)
model.add(layers.MaxPooling2D((2, 2)))

# 将输出展平为1维向量
model.add(layers.Flatten())

# 添加全连接层(64个神经元)
model.add(layers.Dense(64, activation='relu'))

# 添加输出层(10个神经元,对应10个数字类别)
model.add(layers.Dense(10))

通过model.summary()输出模型摘要信息如下:

接下来编译模型并进行训练,训练代码和训练过程如下:

# 编译模型并训练
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

history = model.fit(train_images[..., tf.newaxis], train_labels, epochs=10,
                    validation_data=(test_images[..., tf.newaxis], test_labels))

 训练器默认使用 Adam 优化器,除此之外,我们还可以使用别的优化算法进行优化,如下:

# 导入优化器
from tensorflow.keras.optimizers import SGD

# 创建一个自定义优化器
optimizer = SGD(learning_rate=0.01, momentum=0.9)

# 编译模型并指定损失函数和优化器
model.compile(optimizer=optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

从训练过程中其实可以看到,准确率可能会有降低的可能性。在测试集上评估模型的性能如下:

# 评估模型在测试集上的性能
test_loss, test_acc = model.evaluate(test_images[..., tf.newaxis], test_labels, verbose=2)
print('Test accuracy:', test_acc)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值