TensorFlow2.x 实践之对服装图像进行分类

举报
一颗小树x 发表于 2020/12/03 01:15:56 2020/12/03
3.7k+ 0 0
【摘要】 前言 基于TensorFlow2.x的框架,使用PYthon编程语言,实现对服装图像进行分类。   思路流程: 导入 Fashion MNIST数据集探索数据预处理数据建立模型(搭建神经网络结构、编译模型)训练模型(把数据输入模型、评估准确性、作出预测、验证预测)  使用训练有素的模型   一、Fashion MNIST数据集 Fashion MNIST数据集包括...

前言

基于TensorFlow2.x的框架,使用PYthon编程语言,实现对服装图像进行分类。

思路流程:

  1. 导入 Fashion MNIST数据
  2. 集探索数据
  3. 预处理数据
  4. 建立模型(搭建神经网络结构、编译模型)
  5. 训练模型(把数据输入模型、评估准确性、作出预测、验证预测)  
  6. 使用训练有素的模型

一、Fashion MNIST数据集

Fashion MNIST数据集包括一些运动鞋和衬衫等衣物;我们从下图中先看一下:

给不同类别的 运动鞋和衬衫等衣物,进行索引分类;每个图像都映射到一个标签。

不同的类别,对应其索引,先把它们存储在此处以供以后在绘制图像时使用:


      class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
                     'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
  
 

二、探索数据

在训练模型之前,我们可以探索数据集的格式。比如:训练集中有60,000张图像,每个图像表示为28 x 28像素。训练集中有60,000个标签;每个标签都是0到9之间的整数。

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

探索数据代码:

运行结果:

3、预处理数据

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


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

查看第一张图像(像素值落在0到255),运行结果:

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

运行结果:可以看到 训练集中的前25张图像

四、建立模型

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

1)搭建神经网络结构

神经网络的基本组成部分是图 。图层(神经网络的结构)将输入到图层中的数据进行提取特征。

深度学习的大部分内容是将简单的层链接在一起。大多数层(例如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个类之一。

2)编译模型

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

  • 损失函数 -衡量训练期间模型的准确性。希望最小化此功能,以在正确的方向上“引导”模型。
  • 优化器 -这是基于模型看到的数据及其损失函数来更新模型的方式。
  • 指标 -用于监视培训和测试步骤。以下示例使用precision ,即正确分类的图像比例。

      model.compile(optimizer='adam',
                    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                    metrics=['accuracy'])
  
 

五、训练模型

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

  1. 将训练数据输入模型。在此示例中,训练数据在train_imagestrain_labels数组中。
  2. 训练过程中该模型会学习关联图像和标签。(找到正确的对应关系,比如a图片,对应a标签,而不是对应c标签)
  3. 使用训练好后的模型对测试集进行预测。(在本示例中为test_images数组)
  4. 验证预测是否与test_labels数组中的标签匹配。

1)把数据输入模型进行训练

要开始训练,请调用model.fit方法:

model.fit(train_images, train_labels, epochs=10)
 

这里训练过程中会迭代10次;

第1次训练:

第2次训练:

..........................3、4、5、6、7、8、9...................训练

第10次训练:


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

2)评估准确性

比较模型在测试数据集上的表现:


      test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
      print('\nTest accuracy:', test_acc)
  
 

运行结果: 

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

解决方案:请参见以下内容:(有兴趣可以看一下)

3)作出预测

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


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

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

predictions[0]
 

运行结果:

预测是由10个数字组成的数组。它们代表模型对图像对应于10种不同服装中的每一种的“置信度”。可以看到哪个标签的置信度最高: np.argmax(predictions[0])

输出是 9

因此,模型最有把握认为该图像是短靴/脚踝靴(class_names[9] );检查测试标签表明此分类是正确的:test_labels[0]

输出也是 9

4)验证预测

通过训练模型,可以使用它来预测某些图像。让我们看一下第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()
  
 

运行结果:  

绘制一些带有预测的图像:


      # 绘制一些带有预测的图像
      # 绘制前X张测试图像,它们的预测标签和真实标签。
      # 将正确的预测颜色设置为蓝色,将不正确的预测颜色设置为红色。
      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()
  
 

六、使用训练有素的模型

使用经过训练的模型对单个图像进行预测;先挑一张图片,比如test_images[0],它是这样的:

它是短靴/脚踝靴,对应标签是9。下面使用模型进行预测:


      # 【6 使用训练有素的模型】
      # 使用经过训练的模型对单个图像进行预测。
      # 从测试数据集中获取图像。
      img = test_images[0]
      # 将图像添加到唯一的批处理
      img = (np.expand_dims(img,0))
      # 为该图像预测正确的标签:
      predictions_single = probability_model.predict(img)
      print("输出每一个标签的把握:", predictions_single)  # 一共10个标签,索引从0,1,2到9
      plot_value_array(1, predictions_single[0], test_labels)
      _ = plt.xticks(range(10), class_names, rotation=45)
      # keras.Model.predict返回一个列表列表-数据批次中每个图像的一个列表。批量获取我们(仅)图像的预测
      print("模型预测的结果:", np.argmax(predictions_single[0]))
  
 

运行结果:

我们可以看到有99.6%的把握认为是标签9,预测正确了,能分辨出是短靴/脚踝靴(标签是9)。

七、源代码:


      # 本程序基于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
      # 查看当前tensorflow版本
      print("当前tensorflow版本", tf.__version__)
      # 【1 导入Fashion MNIST数据集】
      '''
      加载数据集将返回四个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 短靴/脚踝靴
      '''
      fashion_mnist = keras.datasets.fashion_mnist
      (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
      # 每个图像都映射到一个标签
      class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
      'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
      # 【2 探索数据】
      # 在训练模型之前,让我们探索数据集的格式。下图显示了训练集中有60,000张图像,每个图像表示为28 x 28像素
      print("训练集总图片数:", train_images.shape)
      # 训练集中有60,000个标签
      print("训练集中标签数:", len(train_labels))
      # 每个标签都是0到9之间的整数
      print("标签取值:", train_labels)
      # 测试集中有10,000张图像。同样,每个图像都表示为28 x 28像素
      print("测试集总图片数:", test_images.shape)
      # 测试集包含10,000个图像标签
      print("测试集标签数:", len(test_labels))
      # 【3 预处理数据】
      # 在训练网络之前,必须对数据进行预处理。如果检查训练集中的第一张图像,将看到像素值落在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()
      # 【4 建立模型】
      # 建立神经网络需要配置模型的各层,然后编译模型
      # 搭建神经网络结构 神经网络的基本组成部分是层 。图层(神经网络结构)从输入到其中的数据中提取表示
      # 深度学习的大部分内容是将简单的层链接在一起。大多数层(例如tf.keras.layers.Dense )具有在训练期间学习的参数。
      model = keras.Sequential([
       keras.layers.Flatten(input_shape=(28, 28)),
       keras.layers.Dense(128, activation='relu'),
       keras.layers.Dense(10)
      ])
      '''
      编译模型
      在准备训练模型之前,需要进行一些其他设置。这些是在模型的编译步骤中添加的:
      损失函数 -衡量训练期间模型的准确性。您希望最小化此功能,以在正确的方向上“引导”模型。
      优化器 -这是基于模型看到的数据及其损失函数来更新模型的方式。
      指标 -用于监视培训和测试步骤。以下示例使用precision ,即正确分类的图像比例。
      '''
      model.compile(optimizer='adam',
       loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
       metrics=['accuracy'])
      # 【5 训练模型】
      '''
      训练神经网络模型需要执行以下步骤:
      1.将训练数据输入模型。在此示例中,训练数据在train_images和train_labels数组中。
      2.该模型学习关联图像和标签。
      3.要求模型对测试集进行预测(在本示例中为test_images数组)。
      4.验证预测是否与test_labels数组中的标签匹配。
      '''
      # 要开始训练,请调用model.fit方法,之所以这么称呼是因为它使模型“适合”训练数据:
      model.fit(train_images, train_labels, epochs=10)
      # 比较模型在测试数据集上的表现
      test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
      print('\nTest accuracy:', test_acc)
      # 作出预测 通过训练模型,您可以使用它来预测某些图像。模型的线性输出logits 。附加一个softmax层,以将logit转换为更容易解释的概率。
      probability_model = tf.keras.Sequential([model,  tf.keras.layers.Softmax()])
      predictions = probability_model.predict(test_images)
      print(predictions[0])
      print(np.argmax(predictions[0]))
      print(test_labels[0])
      # 以图形方式查看完整的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()
      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()
      # 绘制一些带有预测的图像
      # 绘制前X张测试图像,它们的预测标签和真实标签。
      # 将正确的预测颜色设置为蓝色,将不正确的预测颜色设置为红色。
      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()
      # 【6 使用训练有素的模型】
      # 使用经过训练的模型对单个图像进行预测。
      # 从测试数据集中获取图像。
      img = test_images[0]
      # 将图像添加到唯一的批处理
      img = (np.expand_dims(img,0))
      # 为该图像预测正确的标签:
      predictions_single = probability_model.predict(img)
      print("输出每一个标签的把握:", predictions_single)  # 一共10个标签,索引从0,1,2到9
      plot_value_array(1, predictions_single[0], test_labels)
      _ = plt.xticks(range(10), class_names, rotation=45)
      # keras.Model.predict返回一个列表列表-数据批次中每个图像的一个列表。批量获取我们(仅)图像的预测
      print("模型预测的结果:", np.argmax(predictions_single[0]))
  
 

希望对你有帮助;

本文参考:

Tensorflow 官网:https://www.tensorflow.org/

文章来源: guo-pu.blog.csdn.net,作者:一颗小树x,版权归原作者所有,如需转载,请联系作者。

原文链接:guo-pu.blog.csdn.net/article/details/108496516

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。