import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import time
导入一些包。ensorFlow用于构建和训练神经网络,matplotlib用于绘图,numpy用于数学运算,time用于获取当前时间
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print(nowtime)
打印分隔线,并获取当前时间的字符串表示,然后打印出来。
# 初始化
plt.rcParams['font.sans-serif'] = ['SimHei']
设置matplotlib的字体参数,以便在图表中显示中文。
# 加载数据
mnist = tf.keras.datasets.mnist
(train_x, train_y), (test_x, test_y) = mnist.load_data()
print('\n train_x:%s, train_y:%s, test_x:%s, test_y:%s' % (train_x.shape, train_y.shape, test_x.shape, test_y.shape))
结合自己的理解,
- 第一个元组
(train_x, train_y)
包含训练集的数据和标签。 - 第二个元组
(test_x, test_y)
包含测试集的数据和标签。 train_x
和test_x
是图像数据,每个图像是一个28x28像素的灰度图像,被展平成一个包含784个元素(28*28)的一维数组。train_y
和test_y
是对应的标签数据,是一个整数数组,表示图像中手写数字的类别(0到9)
train_x.shape
通常返回(60000, 28, 28)
,表示训练集包含60000个图像,每个图像是28x28像素。train_y.shape
返回(60000,)
,表示训练集有60000个标签。test_x.shape
通常返回(10000, 28, 28)
,表示测试集包含10000个图像,每个图像是28x28像素。test_y.shape
返回(10000,)
,表示测试集有10000个标签# 数据预处理 # X_train = train_x.reshape((60000,28*28))#改变后的 reshape为((60000,784)) # Y_train = train_y.reshape((60000,28*28)) #后面采用tf.keras.layers.Flatten()改变数组形状 X_train, X_test = tf.cast(train_x / 255.0, tf.float32), tf.cast(test_x / 255.0, tf.float32) # 归一化 y_train, y_test = tf.cast(train_y, tf.int16), tf.cast(test_y, tf.int16)
-
reshape((60000, 28*28))
:reshape
是NumPy中的一个函数,用于改变数组的形状而不改变其数据。在这里,它将每个28x28的二维图像展平成一个包含784个元素(28*28)的一维数组。这样做的目的是为了将图像数据输入到机器学习模型中,因为大多数模型(尤其是早期的模型)期望输入数据是一维的。 -
X_train
:这是转换后的一维训练图像数据,形状变为(60000, 784)
,其中60000是样本数量,784是每个样本的像素值数量。
# 建立模型
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
print('\n', model.summary()) # 查看网络结构和参数信息
构建一个序贯模型,包含一个Flatten层将图像展平,一个128个神经元的全连接层使用ReLU激活函数,以及一个10个神经元的全连接层使用softmax激活函数,用于输出预测概率。
# 配置模型训练方法
# adam算法参数采用keras默认的公开参数,损失函数采用稀疏交叉熵损失函数,准确率采用稀疏分类准确率函数
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['sparse_categorical_accuracy'])
配置模型的训练参数,使用adam优化器,损失函数为稀疏分类交叉熵,评估指标为准确率。
# 训练模型
# 批量训练大小为64,迭代5次,测试集比例0.2(48000条训练集数据,12000条测试集数据)
print('--------------')
nowtime = time.strftime('%Y-%m-%d %H:%M:%S')
print('训练前时刻:' + str(nowtime))
history = model.fit(X_train, y_train, batch_size=64, epochs=5, validation_split=0.2)
-
validation_split=0.2
:这个参数指定了从训练数据中分割出一部分作为验证集的比例。在这里,20%的训练数据将被用作验证集。验证集用于在每个epoch结束后评估模型的性能,以便监控模型在未见过的数据上的表现,并帮助防止过拟合。
# 评估模型
model.evaluate(X_test, y_test, verbose=2) # 每次迭代输出一条记录,来评价该模型是否有比较好的泛化能力
# 结果可视化
print(history.history)
loss = history.history['loss'] # 训练集损失
val_loss = history.history['val_loss'] # 测试集损失
acc = history.history['sparse_categorical_accuracy'] # 训练集准确率
val_acc = history.history['val_sparse_categorical_accuracy'] # 测试集准确率
plt.figure(figsize=(10, 3))
# 使用模型
plt.figure()
for i in range(10):
num = np.random.randint(1, 10000)
plt.subplot(2, 5, i + 1)
plt.axis('off')
plt.imshow(test_x[num], cmap='gray')
demo = tf.reshape(X_test[num], (1, 28, 28))
y_pred = np.argmax(model.predict(demo))
plt.title('标签值:' + str(test_y[num]) + '\n预测值:' + str(y_pred))
# plt.ion() #打开交互式操作模式
plt.show()
# plt.pause(5)
# plt.close()