import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
# 载入并准备好 MNIST 数据集
mnist = tf.keras.datasets.mnist
# 训练集和测试集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 查看训练集数据 60000个训练图像 每个图像由 28 x 28 的像素表示
print(x_train.shape)
print(y_train.shape)
print(len(x_train))
# 查看测试集数据 10000个测试图像 每个图像由 28 x 28 的像素表示
print(x_test.shape)
print(y_test.shape)
print(len(x_test))
# 查看训练集中第一个图像 像素值处于 0 到 255 之间
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.figure()
plt.imshow(x_train[0])
plt.colorbar()
plt.grid(False)
plt.show()
# 数据预处理 将这些值缩小至 0 到 1 之间,然后将其馈送到神经网络模型
# 为此,将这些值除以 255 以相同的方式对训练集和测试集进行预处理
x_train, x_test = x_train / 255.0, x_test / 255.0
# 验证数据格式是否正确 显示训练集中前25个图像,图像下方对应的数字
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_train[i])
plt.xlabel(y_train[i])
plt.show()
layer1 tf.keras.layers.Flatten 将图像格式从二维数组(28 x 28 像素)转换成一维数组(28 x 28 = 784 像素)。
将该层视为图像中未堆叠的像素行并将其排列起来。该层没有要学习的参数,它只会重新格式化数据。
Layer2 层有 128个神经元,这128个神经元会和 Layer1 中 728 个神经元相互连接,共将产生 728 * 128 =93184 权重(weights)各自不同的连接 。
Layer1 中神经元的输出将与连接到 layer2 的权重值进行加权求和,得到的结果会被带入 relu 函数,最终输出一个新的值作为 Layer2 中神经元的输出。
relu作为激活函数
layer3 使用 Dropout 随机丢弃 20% 神经元,防止过度拟合。
layer4 有 10 个神经元,并使用 softmax作为激活函数,这 10个神经元的输出就是最终结的结果.
# 构建模型 设置层
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation="relu"),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:
损失函数 - 用于测量模型在训练期间的准确率。您会希望最小化此函数,以便将模型“引导”到正确的方向上。
优化器 - 决定模型如何根据其看到的数据和自身的损失函数进行更新。
**指标 ** -用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
训练神经网络模型需要执行以下步骤:
将训练数据馈送给模型。在本例中,训练数据位于 x_train 和 y_train 数组中。
模型学习将图像和标签关联起来。
要求模型对测试集(在本例中为 x_test 数组)进行预测。
验证预测是否与 y_test 数组中的标签相匹配。
# 训练验证模型 在模型训练期间,会显示损失和准确率指标
model.fit(x_train, y_train, epochs=5)
# 模型在测试数据集上的表现 注意过拟合问题
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print('\nTest accuracy:', test_acc)
# 预测测试集中每个图像的数字
predictions = model.predict(x_test)
# 查看第一个预测的结果 预测结果是一个包含 10 个数字的数组 它们代表模型对0-9数字的“置信度”
print(predictions[0])
# 可以看到哪个数字的置信度值最大
print(np.argmax(predictions[0]))
# 查看真实的结果
print(y_test[0])
模型经过训练后,可以使用它对一些图像进行预测。模型具有线性输出,即 logits,将 logits 转换成更容易理解的概率
# 绘制图表 查看模型的预测
def plot_image(i, predict_array, true_num, img):
predict_array, true_num, img = predict_array, true_num[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img)
predict_num = np.argmax(predict_array)
if predict_num == true_num:
color = 'blue'
else:
color = 'red'
# 图像下方标签
plt.xlabel("预测值:{} 置信度:{:2.0f}% 实际值:{}".format(predict_num, 100 * np.max(predict_array), true_num), color=color)
def plot_value_array(i, predict_array, true_num):
predict_array, true_num = predict_array, true_num[i]
plt.grid(False)
plt.xticks(range(10))
plt.yticks([])
thisplot = plt.bar(range(10), predict_array, color="#777777")
plt.ylim([0, 1])
predict_num = np.argmax(predict_array)
thisplot[predict_num].set_color('red')
thisplot[true_num].set_color('blue')
# 验证预测结果
# 看第0个图像、预测结果和预测数组。正确的预测标签为蓝色,错误的预测标签为红色。数字表示预测标签的百分比(总计为 100)
i = 0
plt.figure(figsize=(6, 3))
plt.subplot(1, 2, 1)
plot_image(i, predictions[i], y_test, x_test)
plt.subplot(1, 2, 2)
plot_value_array(i, predictions[i], y_test)
plt.show()
# 用模型的预测绘制几张图像 注意,即使置信度很高,模型也可能出错
num_rows = 10
num_cols = 6
num_images = num_rows * num_cols
plt.figure(figsize=(2 * 2 * num_cols, 2 * num_rows))
for item in range(num_images):
plt.subplot(num_rows, 2 * num_cols, 2 * item + 1)
plot_image(item, predictions[item], y_test, x_test)
plt.subplot(num_rows, 2 * num_cols, 2 * item + 2)
plot_value_array(item, predictions[item], y_test)
plt.title("模型预测和实际对比图")
plt.tight_layout()
plt.savefig('predict--true.png')
plt.show()
# 使用训练好的模型对单个图像进行预测
img = x_test[15]
print(img.shape)
# tf.keras 模型经过了优化,可同时对一个批或一组样本进行预测。因此,即便只使用一个图像,也需要将其添加到列表中
img = np.expand_dims(img, 0)
print(img.shape)
# 预测此图像中的数字
predict_single = model.predict(img)
print(predict_single)
# 绘图
plot_value_array(15, predict_single[0], y_test)
_ = plt.xticks(range(10), range(10), rotation=45)
plt.show()
print("predict:", np.argmax(predict_single[0]), " real:", y_test[15])