本教程将使用Keras构建一个简单的的卷积神经网络(Convolutional Neural Network,CNN)来对手写数字进行识别。使用的数据集为MNIST数据集,一个包含手写数字图像的经典数据集。
0. 环境设置
确保你已经安装了所需的库,可以通过以下方式安装:
pip install keras conda install matplotlib conda install numpy
1. 数据准备
首先,我们需要加载MNIST数据集,该数据集包含60,000个训练图像和10,000个测试图像。
# numberCNNtrain.py
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.utils import to_categorical
# 加载数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 数据预处理
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32') / 255
# 将标签转换为one-hot编码
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
如果这一行出现了报错的话。
(x_train, y_train), (x_test, y_test) = mnist.load_data()
报错信息如下:Exception: URL fetch failure on https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz: None -- [WinError 10054] 远程主机强迫关闭了一个现有的连接。
说明你连接不上googleapis。不过可以直接将数据集下载,并将mnist.npz文件保存到 C:\Users\Administrator.keras\datasets目录下。这里提供一个网盘链接可以下载mnist.npz数据集。
2. 构建CNN模型
接下来,我们构建一个简单的CNN模型。该模型包含两个卷积层(Conv2D),两个最大池化层(MaxPooling2D),以及两个全连接层(Dense)。
# numberCNNtrain.py
# 构建CNN模型
model = Sequential()
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, kernel_size=(5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))
卷积核个数(Filters):
较小的卷积核个数: 导致模型较少的参数和更快的训练速度,但降低模型的表达能力。
较大的卷积核个数: 增加模型的表达能力,但会增加模型的参数数量和训练时间。
卷积核尺寸(Kernel Size):
小尺寸的卷积核(如3x3): 通常用于较浅的层,可以捕捉更局部的特征。
大尺寸的卷积核(如5x5或7x7): 通常用于较深的层,可以捕捉更全局的特征。
3. 编译和训练模型
在构建模型后,我们需要编译它,并通过训练数据对其进行训练。
# numberCNNtrain.py
# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train, batch_size=128, epochs=5, validation_data=(x_test, y_test))
关于优化器、损失函数、评估指标等,可以进一步查阅Keras文档以了解更多可用参数和配置。
关于超参数:
①batch_size(批量大小): 定义每次迭代中用于更新模型权重的样本数量。较大的批量大小可能会加快训练速度,但也可能导致内存不足。较小的批量大小可以提高模型的泛化性,但训练可能变慢。
②epochs(训练轮数): 定义整个训练数据集被迭代的次数。增加 epochs 可以提高模型的性能,但也可能导致过拟合。
4. 评估和保存模型
训练完成后,我们对模型进行评估,并将其保存到文件中。
# numberCNNtrain.py
# 评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)
# 保存模型
model.save('mnist_cnn_model.h5')
开始运行!运行结束后,会生成mnist_cnn_model.h5,这个就是我们训练的模型。
——————分割线——————
5. 模型预测和可视化
现在,我们可以使用训练好的模型mnist_cnn_model.h5进行预测并可视化结果。
# numberCNNpredict.py
import numpy as np
from keras.datasets import mnist
from keras.models import load_model
import matplotlib.pyplot as plt
# 加载模型
model = load_model('mnist_cnn_model.h5')
# 加载测试数据集
(_, _), (x_test, y_test) = mnist.load_data()
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32') / 255
# 使用模型进行预测
predictions = model.predict(x_test)
# 获取预测的标签
predicted_labels = np.argmax(predictions, axis=1)
# 可视化预测结果
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(x_test[i].reshape(28, 28), cmap=plt.cm.binary)
plt.xlabel(f'Predicted: {predicted_labels[i]}')
plt.show()
可视化: