使用TensorFlow可以大大简化模型训练的代码量,仅用几行代码就可以训练一个模型,效果也相当不错。
本教程属于TensorFlow的入门级教程,使用TensorFlow训练模型,以使用模型对服饰图片进行分类。本教程使用命令行操作效果更好。
导入所需要的包
TensorFlow是必要的深度学习框架,keras是一种用于在 TensorFlow 中构建和训练模型的高阶 API。numpy与matplotlib一个是python科学计算的常用库,一个是python绘图的常用库,这是必须了解的。
# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras
# Helper libraries
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)
导入 Fashion MNIST 数据集
Fashion MNIST 数据集中包含 70000 张灰度图像,涵盖 10 个类别。以下图像显示了单件服饰在较低分辨率(28x28 像素)下的效果:
Fashion MNIST 的作用是成为经典 MNIST 数据集的简易替换,后者通常用作计算机视觉机器学习程序的“Hello, World”入门数据集。我们将使用 60000 张图像训练网络,并使用 10000 张图像评估经过学习的网络分类图像的准确率。
加载数据,在命令行输入以下代码:
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
加载数据集会返回 4 个 NumPy 数组:
train_images
和train_labels
数组是训练集,即模型用于学习的数据。- 测试集
test_images
和test_labels
数组用于测试模型。
图像为 28x28 的 NumPy 数组,像素值介于 0 到 255 之间。标签是整数数组,介于 0 到 9 之间。这些标签对应于图像代表的服饰所属的类别:
标签 | 类别 |
---|---|
0 | T 恤衫/上衣 |
1 | 裤子 |
2 | 套衫 |
3 | 裙子 |
4 | 外套 |
5 | 凉鞋 |
6 | 衬衫 |
7 | 运动鞋 |
8 | 包包 |
9 | 踝靴 |
每张图像都映射到一个标签。由于数据集中不包含类别名称,因此将它们存储在此处,以便稍后在绘制图像表时使用:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
探索数据
我们先探索数据集的格式,然后再训练模型。以下内容显示训练集中有 60000 张图像,每张图像都表示为 28x28 像素:
查看训练数据集形状:
train_images.shape
查看训练数据集长度 :
len(train_labels)
查看测试数据集形状与长度:
test_images.shape
len(test_labels)
预处理数据
必须先对数据进行预处理,然后再训练网络。
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
我们将这些值缩小到 0 到 1 之间,然后将其馈送到神经网络模型。为此,将图像组件的数据类型从整数转换为浮点数,然后除以 255。以下是预处理图像的函数:
务必要以相同的方式对训练集和测试集进行预处理:
train_images = train_images / 255.0
test_images = test_images / 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(train_images[i], cmap=plt.cm.binary)
plt.xlabel(class_names[train_labels[i]])
构建模型
构建神经网络需要先配置模型的层,然后再编译模型。
设置层
神经网络的基本构造块是层。层从馈送到其中的数据中提取表示结果。希望这些表示结果有助于解决手头问题。
大部分深度学习都会把简单的层连在一起。大部分层(例如 tf.keras.layers.Dense
)都具有在训练期间要学习的参数。
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
该网络中的第一层 tf.keras.layers.Flatten
将图像格式从二维数组(28x28 像素)转换成一维数组(28 * 28 = 784 像素)。可以将该层视为图像中像素未堆叠的行,并排列这些行。该层没有要学习的参数;它只改动数据的格式。
在扁平化像素之后,该网络包含两个 tf.keras.layers.Dense
层的序列。这些层是密集连接或全连接神经层。第一个 Dense
层具有 128 个节点(或神经元)。第二个(也是最后一个)层是具有 10 个节点的 softmax 层,该层会返回一个具有 10 个概率得分的数组,这些得分的总和为 1。每个节点包含一个得分,表示当前图像属于 10 个类别中某一个的概率。
编译模型
模型还需要再进行几项设置才可以开始训练。这些设置会添加到模型的编译步骤:
- 损失函数 - 衡量模型在训练期间的准确率。我们希望尽可能缩小该函数,以“引导”模型朝着正确的方向优化。
- 优化器 - 根据模型看到的数据及其损失函数更新模型的方式。
- 指标 - 用于监控训练和测试步骤。以下示例使用准确率,即图像被正确分类的比例。
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
训练模型
训练神经网络模型需要执行以下步骤:
- 将训练数据馈送到模型中,在本示例中为
train_images
和train_labels
数组。 - 模型学习将图像与标签相关联。
- 我们要求模型对测试集进行预测,在本示例中为
test_images
数组。我们会验证预测结果是否与test_labels
数组中的标签一致。
要开始训练,请调用 model.fit
方法,使模型与训练数据“拟合”:
model.fit(train_images, train_labels, epochs=5)
在模型训练期间,系统会显示损失和准确率指标。该模型在训练数据上的准确率达到 0.88(即 88%)。
尝试增加学习次数,在次数为10次时,准确率到0.91左右。
评估准确率
接下来,比较一下模型在测试数据集上的表现:
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)
结果表明,模型在测试数据集上的准确率略低于在训练数据集上的准确率。训练准确率和测试准确率之间的这种差异表示出现过拟合。如果机器学习模型在新数据上的表现不如在训练数据上的表现,就表示出现过拟合。
做出预测
模型经过训练后,我们可以使用它对一些图像进行预测。
predictions = model.predict(test_images)
在本示例中,模型已经预测了测试集中每张图像的标签。我们来看看第一个预测:
predictions[0]
预测结果是一个具有 10 个数字的数组。这些数字说明模型对于图像对应于 10 种不同服饰中每一个服饰的“置信度”。我们可以看到哪个标签的置信度值最大:
np.argmax(predictions[0])