卷积神经网络(Convolutional Neural Network,CNN)是一种常用于图像识别、语音识别和自然语言处理等领域的神经网络模型。在本文中,我们将介绍如何用 Python 实现一个简单的卷积神经网络,来对手写数字进行分类。
1. 数据集准备
我们将使用 MNIST 数据集,这是一个由手写数字图片组成的经典数据集。在 Python 中,可以通过 tf.keras.datasets.mnist
模块来加载 MNIST 数据集。
import tensorflow as tf
# 加载 MNIST 数据集
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# 将像素值归一化到 0~1 之间
x_train, x_test = x_train / 255.0, x_test / 255.0
2. 搭建卷积神经网络模型
我们将会使用 Keras 来搭建卷积神经网络模型。在 Keras 中,可以通过 tf.keras.Sequential
类来创建序列模型。我们将在模型中使用 2 个卷积层和 2 个池化层,最后接上一个全连接层和一个输出层,来对手写数字进行分类。
# 创建一个序列模型
model = tf.keras.Sequential([
# 第一层卷积层,32 个 3x3 的卷积核,激活函数为 relu
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
# 第一层池化层,2x2 窗口大小
tf.keras.layers.MaxPooling2D((2, 2)),
# 第二层卷积层,64 个 3x3 的卷积核,激活函数为 relu
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
# 第二层池化层,2x2 窗口大小
tf.keras.layers.MaxPooling2D((2, 2)),
# 将特征张量展开成一维向量
tf.keras.layers.Flatten(),
# 全连接层,128 个神经元,激活函数为 relu
tf.keras.layers.Dense(128, activation='relu'),
# 输出层,10 个神经元,激活函数为 softmax
tf.keras.layers.Dense(10, activation='softmax')
])
3. 编译模型并训练
在训练之前,我们需要先编译模型,为模型指定损失函数、优化器和评估指标。我们将使用交叉熵作为损失函数,Adam 作为优化器,并评估模型的精度(accuracy)指标。
# 编译模型
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 训练模型
model.fit(x_train[..., tf.newaxis], y_train, epochs=5,
validation_data=(x_test[..., tf.newaxis], y_test))
4. 模型评估与预测
训练完成后,我们可以使用测试集来评估模型的性能。
# 评估模型
model.evaluate(x_test[..., tf.newaxis], y_test, verbose=2)
此外,我们还可以使用模型来进行预测,对新的手写数字进行分类。
# 对手写数字进行分类
import numpy as np
from PIL import Image
# 加载一个手写数字图片
image = Image.open('test.png').convert('L')
image = image.resize((28, 28))
image_arr = np.array(image)
# 对图片进行归一化
image_arr = image_arr / 255.0
# 对图片进行预处理,增加一个维度
input_data = image_arr.reshape(1, 28, 28, 1)
# 进行预测
prediction = model.predict(input_data)
print('预测结果为:', np.argmax(prediction))
至此,我们已经成功实现并训练了一个简单的卷积神经网络模型,用于手写数字的分类。