首个tensorflow程序

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

原文地址
参考教程

注:纯粹的模仿,只是了解大概,具体深入的尚还不是很清楚。

#忽略因为下面问题而造成的提示: CPU支持AVX AVX2(可以加速CPU计算)但安装的TensorFlow 版本不支持

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#使用的是tf.keras,它是一种用于在Tensorflow中构建和训练模型的高阶API

import tensorflow as tf
from tensorflow import keras

#相关库

import numpy as np
import matplotlib.pyplot as plt
print("tensorflow版本:",tf.__version__)

输出:

tensorflow版本: 2.0.0

导入Fashion MNIST 数据集

此数据集包含10个类别的70,000个灰度图像,图像显示了低分辨率(28 x 28像素)的单个衣​​物

图1 Fashion MNIST在这里插入图片描述

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

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

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

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,这些对应于图像表示的衣服类别

标签 类别
T恤/上衣
裤子
套衫
裙子
外套
凉鞋
衬衫
运动鞋
包包
裸靴

每个图像都映射到一个标签。由于类名不包含在数据集中,因此将它们存储在此处以供以后在绘制图像时使用:

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

探索数据

#训练集中有60,000张图像,每张图像表示为28 x 28像素:

print("训练集图像shape:",train_images.shape)
训练集图像shape: (60000, 28, 28)

#训练集中有60,000个标签

print("训练集标签数量:",len(train_labels))
训练集标签数量: 60000

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

print("训练集标签:",train_labels)
训练集标签: [9 0 0 ... 3 0 5]

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

print("测试集图像shape:",test_images.shape)
测试集图像shape: (10000, 28, 28)

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

print("测试集标签数量:",len(test_labels))
测试集标签数量: 10000

预处理数据

#检查训练集中的第一张图像,看到像素值落在0到255的范围内:

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

图2

#在将它们输入神经网络模型之前,将这些值缩放到0到1的范围。为此,将值除以255。以相同的方式预处理训练集和测试集非常重要:

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

图3

建立模型

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

设置层

#神经网络的基本构造块是层,层从馈送到其中的数据中提取representations.这些representations有助于解决手头问题。

#Most of deep learning consists of chaining together simple layers.
#Most layers, such as tf.keras.layers.Dense, have parameters that are learned during training.

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将图像的格式从二维数组(28 x 28像素)转换为一维数组(28 * 28 = 784像素)。Think of this layer as unstacking rows of pixels in the image and lining them up.该层没有要学习的参数;它只改动数据的格式。

在扁平化像素之后,网络由tf.keras.layers.Dense两层序列组成。这些是紧密连接或全连接神经层。第一个Dense层有128个节点(或神经元)。
第二个Dense层(也是最后一层)是一个有10个节点的softmax层,该层返回一个具有10个概率得分的数组,这些得分的总和总和为1。每个节点都包含一个得分,表示当前图像属于10个类别中某一个的概率。

编译模型

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

#损失函数-衡量训练期间模型的准确性。希望最小化该函数,以“引导”模型朝着正确的方向优化。
#优化器-基于模型看到的数据及其损失函数来更新模型的方式。
#指标-用于监控训练和测试步骤。以下示例使用accuracy,即正确分类的图像比例。

model.compile(optimizer=tf.compat.v1.train.AdamOptimizer(),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

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

1.将训练数据馈送到模型中,在本示例中为 train_images 和 train_labels 数组。
2.模型学习将图像与标签相关联。
3.要求模型对测试集进行预测,在本示例中为 test_images 数组。
会验证预测结果是否与 test_labels 数组中的标签一致。

#开始训练,调用该model.fit方法,该方法使模型“适合”训练数据:

model.fit(train_images, train_labels, epochs=10)
Train on 60000 samples
Epoch 1/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.4917 - accuracy: 0.8266
Epoch 2/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.3744 - accuracy: 0.8648
Epoch 3/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.3373 - accuracy: 0.8764
Epoch 4/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.3130 - accuracy: 0.8858
Epoch 5/10
60000/60000 [==============================] - 4s 63us/sample - loss: 0.2921 - accuracy: 0.8921
Epoch 6/10
60000/60000 [==============================] - 4s 62us/sample - loss: 0.2777 - accuracy: 0.8972
Epoch 7/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.2661 - accuracy: 0.9014
Epoch 8/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.2552 - accuracy: 0.9054
Epoch 9/10
60000/60000 [==============================] - 4s 65us/sample - loss: 0.2452 - accuracy: 0.9076
Epoch 10/10
60000/60000 [==============================] - 4s 64us/sample - loss: 0.2377 - accuracy: 0.9103

在模型训练期间,系统会显示损失和准确率指标。该模型在训练数据上的准确率达到 0.88(即 88%)。

评估准确率

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

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

print('Test accuracy:', test_acc)
10000/10000 [==============================] - 0s 35us/sample - loss: 0.3401 - accuracy: 0.8774
Test accuracy: 0.8774

#结果表明,模型在测试数据集上的准确率略低于在训练数据集上的准确率。
#训练准确率和测试准确率之间的这种差异表示出现过拟合。
#如果机器学习模型在新数据上的表现不如在训练数据上的表现,就表示出现过拟合。

作出预测

#模型经过训练后,我们可以使用它对一些图像进行预测:

predictions = model.predict(test_images)

#在本示例中,模型已经预测了测试集中每张图像的标签。下面是第一个预测:

print("第一个预测的预测结果:","\n",predictions[0])

#预测结果是一个具有10个数字的数组。
#这些数字说明模型对于图像对应于10种不同服饰中每一个服饰的“置信度”。

第一个预测的预测结果: 
 [8.1516376e-08 8.8641650e-11 3.1418537e-09 3.8512254e-10 2.0814486e-09
 2.2385828e-05 9.3556906e-08 5.7493565e-03 3.0871156e-08 9.9422812e-01]

#查看置信度值最大的标签:

print(“置信度最大的标签:”,np.argmax(predictions[0]))

置信度最大的标签: 9

#因此,模型非常确信这张图像是踝靴或属于 class_names[9]。

#检查测试标签以查看该预测是否正确:

print("测试标签验证:",test_labels[0])
测试标签验证: 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()

图3

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

图4

此处注明:此处并不是每一次都能得到正确结果,前几次都是错误的结果

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

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

图5

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

#Grab an image from the test dataset.

img = test_images[1]

print("测试图像shape:",img.shape)
测试图像shape: (28, 28)

#tf.keras对模型进行了优化,可以一次对一批或一批示例进行预测。
#因此,即使使用的是单个图像,也需要将其添加到列表中:
#Add the image to a batch where it’s the only member.

img = (np.expand_dims(img,0))

print("测试图像shape:",img.shape)

#为该图像预测正确的标签:

predictions_single = model.predict(img)

print("预测结果:","\n",predictions_single)

#model.predict返回列表列表-每个列表对应批次数据中的每张图像表。

预测结果: 
 [[2.8153701e-04 1.5624144e-11 9.9855953e-01 9.1284494e-11 1.0759905e-03
  1.6381140e-12 8.3001272e-05 1.8032102e-17 8.4487223e-10 1.1698882e-12]]
测试图像shape: (1, 28, 28)
plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)
plt.show()

图6

#(仅)获取批次数据中相应图像的预测结果:

print("预测结果:",np.argmax(predictions_single[0]))

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

写在最后

1.文中部分注释为英文,是因为有部分翻译不是很明确;
2.本文所有运行结果为同一次运行结果,不同次运行,结果有差异;
3.代码虽然全部运行成功,但还有尚有很多不清楚的地方,后面再继续学习。

2019.10.06 12:20

猜你喜欢

转载自blog.csdn.net/weixin_45700507/article/details/102057892