import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
print(tf.__version__)
在这里,使用60,000张图像来训练网络,使用10,000张图像来评估网络学习对图像进行分类的准确度。您可以直接从TensorFlow访问Fashion MNIST。从TensorFlow导入和加载Fashion MNIST数据:
fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels) = fashion_mnist.load_data()
加载数据集将返回四个NumPy数组:
图像是28x28 NumPy数组,像素值范围是0到255。标签是整数数组,范围是0到9。这些对应于图像表示的衣服类别:
# 设置类别标签
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
在训练网络之前,必须对数据进行预处理。如果检查训练集中的第一张图像,你将看到像素值落在0到255之间:
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]])
plt.show()
运行结果:
设置图层
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28,28)),
keras.layers.Dense(128,activation="relu"),
keras.layers.Dense(10)
])
该网络的第一层tf.keras.layers.Flatten将图像格式从二维数组(28 x 28像素)转换为一维数组(28 * 28 = 784像素)。可以将这一层看作是堆叠图像中的像素行并将它们排成一行。该层没有学习参数。它只会重新格式化数据。
像素展平后,网络由tf.keras.layers.Dense两层序列组成。这些是紧密连接或完全连接的神经层。第一Dense层有128个节点(或神经元)。第二层(也是最后一层)返回长度为10的logits数组。每个节点包含一个概率,该概率指示当前图像属于10个类之一。
在准备训练模型之前,需要进行一些其他设置。这些是在模型的编译步骤中添加的:
model.compile(optimizer="adam",
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=["accuracy"])
训练神经网络模型需要执行以下步骤:
喂数据
model.fit(train_images,train_labels,epochs=10)
训练过程:
Train on 60000 samples
Epoch 1/10
60000/60000 [==============================] - 6s 106us/sample - loss: 0.4955 - accuracy: 0.8250
Epoch 2/10
60000/60000 [==============================] - 6s 100us/sample - loss: 0.3727 - accuracy: 0.8659
Epoch 3/10
60000/60000 [==============================] - 6s 104us/sample - loss: 0.3357 - accuracy: 0.8782
Epoch 4/10
60000/60000 [==============================] - 5s 91us/sample - loss: 0.3105 - accuracy: 0.8857
Epoch 5/10
60000/60000 [==============================] - 6s 93us/sample - loss: 0.2939 - accuracy: 0.8927
Epoch 6/10
60000/60000 [==============================] - 6s 95us/sample - loss: 0.2783 - accuracy: 0.8972
Epoch 7/10
60000/60000 [==============================] - 6s 94us/sample - loss: 0.2669 - accuracy: 0.9015
Epoch 8/10
60000/60000 [==============================] - 6s 92us/sample - loss: 0.2539 - accuracy: 0.9054
Epoch 9/10
60000/60000 [==============================] - 6s 94us/sample - loss: 0.2464 - accuracy: 0.9080
Epoch 10/10
60000/60000 [==============================] - 6s 96us/sample - loss: 0.2365 - accuracy: 0.9109
在测试集评估模型
test_loss, test_acc = model.evaluate(test_images,test_labels,verbose=2)
print('\nTest accuracy:', test_acc)
输出结果:
10000/10000 - 1s - loss: 0.3356 - accuracy: 0.8835
Test accuracy: 0.8835
使用模型进行预测
通过训练模型,您可以使用它来预测某些图像。模型的线性输出logits。附加一个softmax层,以将logit转换为更容易解释的概率。
probability_model = tf.keras.Sequential([model,
tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)
在这里,模型已经预测了测试集中每个图像的标签。让我们看一下第一个预测:
predictions[0]
输出结果:
array([8.9765700e-07, 1.4239186e-08, 1.4312335e-10, 8.7942272e-11,
1.1608365e-07, 1.7986147e-05, 2.1622704e-07, 3.4401587e-03,
5.0773050e-08, 9.9654061e-01], dtype=float32)
预测是10个数字组成的数组。它们代表模型对图像对应于10种不同服装中的每一种的“信心”。您可以看到哪个标签的置信度最高:
np.argmax(predictions[0])
输出结果:
9
因此,模型最有信心该图像是Ankle boot或class_names[9]。检查测试标签表明此分类是正确的:
以图形方式查看完整的10个类预测。
def plot_image(i,predictions_array,true_label,img):
predictions_array,true_label,img = predictions_array,true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img,cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
predictions_array, true_label = predictions_array, true_label[i]
plt.grid(False)
plt.xticks(range(10))
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
通过训练模型,您可以使用它来预测某些图像。
让我们看一下第0张图像,预测和预测数组。正确的预测标签为蓝色,错误的预测标签为红色。该数字给出了预测标签的百分比(满分为100)。
i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i,predictions[i],test_labels,test_images)
plt.subplot(1,2,2)
plot_value_array(i,predictions[i],test_labels)
plt.show()
输出结果:
i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i], test_labels)
plt.show()
让我们绘制一组带有预测的图像。请注意,即使在测试集上准确率非常高,该模型也可能会出现一些错误预测。
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols,2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(num_rows, 2*num_cols, 2*i+2)
plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()
最后,使用经过训练的模型对单个图像进行预测。
img = test_images[1]
print(img.shape)
tf.keras对模型进行了优化,可以一次对一批或一组示例进行预测。因此,即使您使用的是单个图像,也需要将其添加到列表中:
# 将要预测的图片添加到一个批处理中
img = (np.expand_dims(img,0))
print(img.shape)
现在,为该图像预测标签:
predictions_single = probability_model.predict(img)
print(predictions_single)
输出结果:
[[2.4490997e-05 6.0981421e-11 9.9608302e-01 4.3779869e-09 3.2670987e-03 1.2866379e-10 6.2503462e-04 2.3379884e-20 3.6047734e-07 1.4104551e-12]]
plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)
输出结果:
查看图片的分类:
np.argmax(predictions_single[0])
输出结果:
2