此页面由 Cloud Translation API 翻译。
Switch to English

基本分类:对服装图像进行分类

在TensorFlow.org上查看 在GitHub上查看源代码 下载笔记本

本指南训练了一个神经网络模型来对衣服的图像进行分类,例如运动鞋和衬衫。如果您不了解所有细节,也可以;这是完整的TensorFlow程序的快速概述,详细内容随您进行。

本指南使用tf.keras (高级API)在TensorFlow中构建和训练模型。

 # 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__)
 
2.3.0

导入Fashion MNIST数据集

 fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
 
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
8192/5148 [===============================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 0s 0us/step

加载数据集将返回四个NumPy数组:

  • train_imagestrain_labels数组是训练集 ,即模型用来学习的数据。
  • 针对测试集test_imagestest_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']
 

探索数据

在训练模型之前,让我们探索数据集的格式。下图显示了训练集中有60,000张图像,每张图像表示为28 x 28像素:

 train_images.shape
 
(60000, 28, 28)

同样,训练集中有60,000个标签:

 len(train_labels)
 
60000

每个标签都是0到9之间的整数:

 train_labels
 
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)

测试集中有10,000张图像。同样,每个图像都表示为28 x 28像素:

 test_images.shape
 
(10000, 28, 28)

测试集包含10,000个图像标签:

 len(test_labels)
 
10000

预处理数据

在训练网络之前,必须对数据进行预处理。如果检查训练集中的第一张图像,您将看到像素值落在0到255的范围内:

 plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
 

png

将这些值缩放到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()
 

png

建立模型

建立神经网络需要配置模型的各层,然后编译模型。

设置图层

神经网络的基本组成部分是 。图层从输入到其中的数据中提取表示。希望这些表示对于当前的问题有意义。

深度学习的大部分内容是将简单的层链接在一起。大多数层(例如tf.keras.layers.Dense )具有在训练期间学习的参数。

 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个类之一。

编译模型

在准备训练模型之前,还需要进行一些其他设置。这些是在模型的编译步骤中添加的:

  • 损失函数 -衡量训练期间模型的准确性。您希望最小化此功能,以在正确的方向上“引导”模型。
  • 优化器 -这是基于模型看到的数据及其损失函数来更新模型的方式。
  • 指标 -用于监视培训和测试步骤。以下示例使用precision ,即正确分类的图像比例。
 model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
 

训练模型

训练神经网络模型需要执行以下步骤:

  1. 将训练数据输入模型。在此示例中,训练数据在train_imagestrain_labels数组中。
  2. 该模型学习关联图像和标签。
  3. 您要求模型对测试集进行预测(在此示例中为test_images数组)。
  4. 验证预测是否与test_labels数组中的标签匹配。

喂模型

要开始训练,请调用model.fit方法,之所以这么称呼是因为它使模型“适合”训练数据:

 model.fit(train_images, train_labels, epochs=10)
 
Epoch 1/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.4973 - accuracy: 0.8255
Epoch 2/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.3743 - accuracy: 0.8639
Epoch 3/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.3345 - accuracy: 0.8782
Epoch 4/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.3128 - accuracy: 0.8860
Epoch 5/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2937 - accuracy: 0.8925
Epoch 6/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2815 - accuracy: 0.8961
Epoch 7/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2673 - accuracy: 0.9012
Epoch 8/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2573 - accuracy: 0.9038
Epoch 9/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2470 - accuracy: 0.9077
Epoch 10/10
1875/1875 [==============================] - 2s 1ms/step - loss: 0.2393 - accuracy: 0.9113

<tensorflow.python.keras.callbacks.History at 0x7f5ca987cf60>

模型训练时,会显示损失和准确性指标。该模型在训练数据上达到约0.91(或91%)的精度。

评估准确性

接下来,比较模型在测试数据集上的表现:

 test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)
 
313/313 - 0s - loss: 0.3272 - accuracy: 0.8841

Test accuracy: 0.8841000199317932

事实证明,测试数据集的准确性略低于训练数据集的准确性。训练准确性和测试准确性之间的差距代表过度拟合 。当机器学习模型在新的,以前看不见的输入上的表现比训练数据上的表现差时,就会发生过度拟合。过度拟合的模型“记忆”训练数据集中的噪声和细节,从而对新数据的模型性能产生负面影响。有关更多信息,请参见以下内容:

作出预测

训练好模型后,您可以使用它来预测某些图像。模型的线性输出logits 。附加一个softmax层,以将logit转换为更容易解释的概率。

 probability_model = tf.keras.Sequential([model, 
                                         tf.keras.layers.Softmax()])
 
 predictions = probability_model.predict(test_images)
 

在这里,模型已经预测了测试集中每个图像的标签。让我们看一下第一个预测:

 predictions[0]
 
array([2.5733272e-07, 1.3352397e-09, 3.0229703e-09, 2.1916051e-09,
       9.3775823e-09, 1.2524406e-03, 3.0483918e-07, 6.3156984e-03,
       3.5332143e-08, 9.9243128e-01], dtype=float32)

预测是10个数字组成的数组。它们代表模型对图像对应于10种不同服装中的每一种的“信心”。您可以看到哪个标签的置信度最高:

 np.argmax(predictions[0])
 
9

因此,模型最有信心该图像是脚踝靴或class_names[9] 。检查测试标签表明此分类是正确的:

 test_labels[0]
 
9

使用图表查看完整的10个类预测。

 def plot_image(i, predictions_array, true_label, img):
  true_label, img = 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):
  true_label = 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()
 

png

 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()
 

png

让我们绘制一些带有预测的图像。请注意,即使非常自信,该模型也可能是错误的。

 # Plot the first X test images, their predicted labels, and the true labels.
# Color correct predictions in blue and incorrect predictions in red.
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()
 

png

使用训练有素的模型

最后,使用经过训练的模型对单个图像进行预测。

 # Grab an image from the test dataset.
img = test_images[1]

print(img.shape)
 
(28, 28)

tf.keras模型经过优化,可以一次对一批或一组示例进行预测。因此,即使您使用的是单个图像,也需要将其添加到列表中:

 # Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))

print(img.shape)
 
(1, 28, 28)

现在,为该图像预测正确的标签:

 predictions_single = probability_model.predict(img)

print(predictions_single)
 
[[2.9163108e-05 7.2068375e-14 9.9900764e-01 1.8123520e-09 8.1888458e-04
  4.9270381e-13 1.4437248e-04 5.5026169e-19 3.3279272e-11 1.1571502e-16]]

 plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)
 

png

keras.Model.predict返回一个列表列表-数据批次中每个图像的一个列表。批量获取我们(仅)图像的预测:

 np.argmax(predictions_single[0])
 
2

该模型将按预期预测标签。

 
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
 

本指南使用Fashion MNIST数据集,其中包含10个类别的70,000个灰度图像。图像显示了低分辨率(28 x 28像素)的单个衣​​物,如下所示:

时尚MNIST精灵
图1. Fashion-MNIST示例 (由Zalando,MIT许可)。

Fashion MNIST旨在替代经典MNIST数据集,通常被用作计算机视觉机器学习程序的“ Hello,World”。 MNIST数据集包含手写数字(0、1、2等)的图像,格式与您将在此处使用的衣服的格式相同。

本指南将Fashion MNIST用于多种用途,并且因为它比常规MNIST更具挑战性。两个数据集都相对较小,用于验证算法是否按预期工作。它们是测试和调试代码的良好起点。

在这里,使用60,000张图像来训练网络,使用10,000张图像来评估网络学习对图像进行分类的准确度。您可以直接从TensorFlow访问Fashion MNIST。直接从TensorFlow导入和加载Fashion MNIST数据: