使用 TensorFlow 构建计算机视觉模型

使用 TensorFlow 构建计算机视觉模型

关于此 Codelab

subject上次更新时间:6月 29, 2021
account_circleLaurence Moroney 编写

1. 准备工作

在此 Codelab 中,您将创建一个计算机视觉模型,该模型可使用 TensorFlow 识别衣服。

前提条件

  • 具备丰富的 Python 知识
  • 基本编程技能

学习内容

在此 Codelab 中,您将:

  • 训练神经网络识别衣物
  • 完成一系列练习,引导您测试不同的广告联盟层

构建内容

  • 用于识别衣着物品的神经网络

所需条件

如果您从未使用 TensorFlow 创建过计算机视觉神经网络,则可以使用包含所有必需依赖项的基于浏览器的 Colaboratory 环境。您可以在 Colab 中运行,查看其余 Codelab 的代码。

否则,您将用于训练模型的主要语言是 Python,因此您需要安装这种语言。此外,您还需要 TensorFlow 和 NumPy 库。您可以点击此处详细了解并安装 TensorFlow。在此处安装 NumPy。

2. 开始编码

首先,请浏览可执行的 Colab 笔记本

首先导入 TensorFlow。

import tensorflow as tf
print(tf.__version__)

您将训练神经网络从名为 Fashion MNIST 的通用数据集中识别服饰商品。包含 10 个不同类别的 70000 件服装。每件衣服都是 28x28 的灰度图片。您可在此处查看一些示例:

cab89ecf27462a95.png

与数据集关联的标签如下:

标签

说明

0

T 恤/上衣

1

裤装

2

套衫

3

礼服

4

Coat

5

凉鞋

6

Shirt

7

运动鞋

8

9

脚踝启动

tf.keras.datasets API 中提供了 Fashion MNIST 数据。按如下方式加载:

mnist = tf.keras.datasets.fashion_mnist

对该对象调用 load_data 可为您提供两组列表:training 值和 testing 值,它们表示显示服装商品及其标签的图形。

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

这些值是什么样子的?要查看输出训练图片和训练标签,您可以对数组中的不同索引进行实验。

import matplotlib.pyplot as plt
plt
.imshow(training_images[0])
print(training_labels[0])
print(training_images[0])

0 的数据输出如下所示:

2da84dc57109b11a.png

您会注意到,所有的值都是 0 到 255 之间的整数。在训练神经网络时,更容易将所有值视为介于 0 和 1 之间,该过程称为“归一化”。幸运的是,Python 提供了一种简单的方法来对列表进行归一化,而不会进行循环。

training_images  = training_images / 255.0
test_images
= test_images / 255.0

您可能还需要查看 42,这是与索引 0 的启动不同的启动。

现在,您可能想知道为什么需要两个数据集:训练和测试。

我们的想法是有一组数据用于训练,另一组模型尚未遇到,以查看其对值的分类效果。毕竟,完成后,您便需要将该模型与以前未见过的数据结合使用!此外,如果不使用单独的测试数据,您将面临网络只记住其训练数据而没有泛化知识的风险。

3. 设计模型

现在设计模型。您将有 3 个图层。逐一了解这些图层,探索不同图层类型以及每个图层使用的参数。

model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), 
                                    tf
.keras.layers.Dense(128, activation=tf.nn.relu),
                                    tf
.keras.layers.Dense(10, activation=tf.nn.softmax)])
  • Sequential 定义神经网络中的层序列。
  • Flatten 接受一个正方形,然后将其转换为一维向量。
  • Dense 会添加一个神经元层。
  • Activation 函数会告知每个神经元层应执行的操作。选项有很多,但暂时使用下面这些选项:
  • Relu 有效地表示如果 X 大于 0,则返回 X,否则返回 0。它只将 0 或更大的值传递给网络中的下一层。
  • Softmax 采用一组值,并有效地选择最大的值。例如,如果最后一层的输出类似于 [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05],那么它无需对最大值进行排序,即返回 [0,0,0,0,1,0,0,0,0]。

4. 编译和训练模型

定义模型后,下一步是构建模型。创建模型,首先使用 optimizerloss 函数对其进行编译,然后使用训练数据和标签对其进行训练。目标是让模型弄清训练数据与其训练标签之间的关系。之后,您希望模型看到与训练数据类似的数据,然后预测这些数据应该是什么样子。

请注意使用 metrics= 作为参数,该参数通过根据已知答案(标签)检查预测结果来让 TensorFlow 报告训练的准确性。

model.compile(optimizer = tf.keras.optimizers.Adam(),
              loss
= 'sparse_categorical_crossentropy',
              metrics
=['accuracy'])

model
.fit(training_images, training_labels, epochs=5)

执行 model.fit 时,您会看到损失和准确率:

Epoch 1/5
60000/60000 [=======] - 6s 101us/sample - loss: 0.4964 - acc: 0.8247
Epoch 2/5
60000/60000 [=======] - 5s 86us/sample - loss: 0.3720 - acc: 0.8656
Epoch 3/5
60000/60000 [=======] - 5s 85us/sample - loss: 0.3335 - acc: 0.8780
Epoch 4/5
60000/60000 [=======] - 6s 103us/sample - loss: 0.3134 - acc: 0.8844
Epoch 5/5
60000/60000 [=======] - 6s 94us/sample - loss: 0.2931 - acc: 0.8926

模型完成训练后,您将在最后一个周期结束时看到准确率值。例如 0.8926(如上所示)。这表示神经网络对训练数据进行分类的准确率约为 89%。换言之,他们发现图像和标签之间的模式匹配是 89% 有效。不错,但考虑到它只训练了 5 个周期,并且很快就完成了。

5. 测试模型

该模型将如何处理未见过的数据?这就是您设置测试集的原因。您调用 model.evaluate 并传入两组数据,并报告每组的损失。快来试试吧:

model.evaluate(test_images, test_labels)

输出如下所示:

10000/10000 [=====] - 1s 56us/sample - loss: 0.3365 - acc: 0.8789
[0.33648381242752073, 0.8789]

该示例返回的准确率为 0.8789,这意味着准确度约为 88%。(值可能略有不同。)

不出所料,模型在使用未知数据时的准确性,低于使用训练时所用的数据。随着您对 TensorFlow 的了解增多,您也会设法加以完善。

如需进一步了解,请尝试下一步中的练习。

6. 探索练习

练习 1

对于第一个练习,请运行以下代码:

classifications = model.predict(test_images)
print(classifications[0])

它会为每个测试图片创建一组分类,然后输出分类中的第一个条目。运行后的输出结果为数字列表。您认为这是为什么,这些数字代表什么?

尝试运行 print(test_labels[0]),您将获得 9。这是否有助于您了解列表呈现的样子?

模型的输出是一个包含 10 个数字的列表。这些数字是被分类的值是对应标签的概率。例如,列表中的第一个值是服装属于类别 0 的概率,下一个值是 1。请注意,除了一个之外,它们的概率都非常低。此外,由于 Softmax,列表中的所有概率加起来为 1.0。

该列表和标签从 0 开始,因此使用 9 标记的脚靴表示这是 10 个类中的 10 个。第 10 个元素具有最高值的列表表示神经网络预测它正在分类的项很可能是脚靴。

练习 2

查看模型中的层。使用 512 个神经元对密集层使用不同的值进行实验。

损失和训练时间有什么不同结果?您为什么这么认为?

例如,如果您增加 1024 个神经元,则必须进行更多计算,这会减缓这一过程。但在本例中,由于模型更准确的情况,它们产生了很好的影响。但这并不意味着越多越好。您可以非常快地达到收益递减的定律。

练习 3

如果移除 Flatten() 层,会发生什么情况。您为什么这么认为?

您会收到与数据形状相关的错误。错误的详情现在可能看起来不太清楚,但根据此经验法则,您网络中第一层的形状应该与数据相同。现在,您的数据是 28x28 的图像,而 28 个包含 28 个神经元的层是不可行的,因此将这 2828 个层拆分为一个 784x1 更有意义。

不要编写所有代码,而是在开头添加 Flatten() 层。稍后将数组加载到模型中时,系统会自动为您拆分这些数组。

练习 4

考虑最终(输出)层。为什么其中有 10 个?如果金额不是 10,会发生什么?

尝试使用 5 训练网络。一旦发现意外值,您将立即收到错误。另一条经验法则:最后一层的神经元数量应与您要分类的类别的数量一致。在这种情况下,数字为 0 到 9,因此有 10 个,因此最后一个层应包含 10 个神经元。

练习 5

考虑网络中其他层的影响。如果您在 512 层和 10 层之间再添加一个层,会发生什么情况?

这些数据相对简单,不会产生任何重大影响。对于更复杂的数据,通常需要额外的层。

练习 6

在训练之前,对数据进行归一化,从 0 到 255 的值到 0 到 1 的值。移除该域名会产生什么影响?下面是试用代码的完整代码(请注意,对数据进行规范化的两行会被注释掉)。

为什么您认为会有不同的结果?Stack Overflow 上提供了很好的答案。

import tensorflow as tf
print(tf.__version__)
mnist
= tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
#training_images=training_images/255.0
#test_images=test_images/255.0
model
= tf.keras.models.Sequential([
  tf
.keras.layers.Flatten(),
  tf
.keras.layers.Dense(512, activation=tf.nn.relu),
  tf
.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model
.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
model
.fit(training_images, training_labels, epochs=5)
model
.evaluate(test_images, test_labels)
classifications
= model.predict(test_images)
print(classifications[0])
print(test_labels[0])

7. 探索回调

之前,在训练额外的周期时,您遇到了损失可能会变化的问题。您可能要花一些时间才能等待训练完成,或者您可能认为如果达到期望的值(例如 95% 的准确率)可以停止训练,那就很好了。如果达到 3 个周期之后,达到此周期的必要程度,为什么不继续等待呢?

和其他任何程序一样,您可以实现回调!查看实际用例:

import tensorflow as tf

class myCallback(tf.keras.callbacks.Callback):
 
def on_epoch_end(self, epoch, logs={}):
   
if(logs.get('accuracy')>0.95):
     
print("\nReached 95% accuracy so cancelling training!")
     
self.model.stop_training = True

callbacks
= myCallback()
mnist
= tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images
=training_images/255.0
test_images
=test_images/255.0
model
= tf.keras.models.Sequential([
  tf
.keras.layers.Flatten(),
  tf
.keras.layers.Dense(512, activation=tf.nn.relu),
  tf
.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model
.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model
.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])

8. 恭喜

您已构建自己的第一个计算机视觉模型!如需了解如何增强计算机视觉模型,请继续构建卷积并执行池化