之前的课程我们熟悉了用TensorFlow对简单数据进行线性预测,现在我们尝试利用新模型对图片完成分类预测。我们开始吧。请问下图片中你看到了几只鞋? image.png 2只对吗?你是怎么知道它们是鞋子的? 想象一下,如果一个人他从未见过鞋子,我们怎样教会他识别鞋子?尽管高跟鞋和平底鞋外表很不一样,但它们都是鞋子,有共同的特征。 也许他会认为:红色的就是鞋子,因为他看到的就这两只,还都是红色的。当然并非如此简单,但你是怎么知道它们是鞋子的。因为你在生活中见到过许多鞋子。 image.png 而你也明白了鞋子的特质,所以遵循这样的逻辑,如果我们向计算机展示很多鞋子,那么它就能够学会识别鞋子。大量优秀的数据能够为计算机提供“长见识”的机会。接下来我们将训练一个能够识别图片分类的神经网络模型,过程中我们使用Fashion-MNIST数据集。

# 1.Fashion-MNIST 数据集

Fashion-MNIST是由德国电商平台(Zalando)发布的数据集。数据集中包含了10个类别的图像,分别是:T恤、牛仔裤、套衫、裙子、外套、凉鞋、衬衫、运动鞋、包、短靴。 image.png 他有70000张图片,分属10个类别,每个类别有7000张图片,也就是说我们可以让计算机学习7000张鞋子,我们希望它在观察7000只鞋子之后可以认出一张它没有见过的鞋子。 Fashion MNIST中的图片像素为28*28的灰度图,非常的小。图片小也有好处,需要计算的参数相应减少,计算机处理速度也更快。 image.png 这里看到的是一双鞋子,接下来我们一起来学习一段代码,看看如何基于这些资料图片让计算机学习的,从而让计算机具备辨识能力。还记得编写代码的大体环节吗,数据准备、模型构建、优化器和损失函数选择、训练模型、评估模型。让我们开始吧。

# 1.1代码讲解:

# 1.1.1数据准备

导入必要的包:

import tensorflow as tf
from tensorflow import keras
1
2

Fashion MNIST 是内置于TensoFlow的,所以很容易用这样的代码来加载。

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
1
2

训练图组包含60000张图片,像是这样的灰度图片。 image.png 剩下的10000张图片是测试图组,可以用来检测神经网络的表现,标签是用来指定图片类别的数字,本案例中,09表示短靴。为什么使用数字“09”标注标签,而非“短靴”呢? 有两个原因,第一是:计算机更擅长处理数字。第二是:避免出现其他方面的偏见,比如语言偏见,而使用数字,则可以避免这样的问题。进行神经网络的设计时,要优先考虑输入和输出值,这里我们可以看到检测图片的神经网络比之前的要复杂一些。

# 1.1.2构造模型

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)
])
1
2
3
4
5

在第一层的网络中,我们的输入形状是28*28,这里的形状就是图片的长度和宽度。

keras.layers.Flatten(input_shape=(28, 28))
1

最后一层是10,是数据集中各种类别的代号,数据集总共有10类,这里就是10 。

keras.layers.Dense(10, activation=tf.nn.softmax),
1

所以神经网络有点像滤波器(过滤装置),输入一组28*28像素的图片后,输出10个类别的判断结果。那这个128的数字是做什么用的呢?

keras.layers.Dense(128, activation=tf.nn.relu),
1

我们可以这样想象,神经网络中有128个函数,每个函数都有自己的参数。 image.png 我们给这些函数进行一个编号,f0,f1…f127 ,我们想的是当鞋子的像素一一带入这128个函数后,这些函数的组合最终输出一个标签值,在这个样例中,我们希望它输出09 。为了得到这个结果,计算机必须要搞清楚这128个函数的具体参数,之后才能计算各个图片的标签。这里的逻辑是,一旦计算机搞清楚了这些参数,那它就能够认出不同的10个类别的事物了。 这里设置了神经网络的优化器和损失函数。

model.compile(optimizer=tf.train.AdamOptimizer(),
			loss='sparse_categorical_crossentropy')
1
2

神经网络会对这些参数随机地初始化一些数值,损失函数会衡量结果精准与否。然后通过优化函数,各个函数会产生新的参数,去检查是否还有进步空间。你可能对这些函数感到好奇,它们叫做激活函数。

keras.layers.Dense(128, activation=tf.nn.relu),
  
keras.layers.Dense(10, activation=tf.nn.softmax)
1
2
3

第一个激活函数, activation=tf.nn.relu 在128层函数的这层,叫RelU,也叫线性整流函数,它的左右就是当函数值大于零时,把数值传递下去,函数值小于零时丢弃(赋值为零)。 image.png 所以当函数值为负数时就把该数值筛选剔除。第二个激活函数Softmax函数: image.png 它能够挑出一组数值中的最大值,这个神经网络中有10个项目,代表着一张图片属于某一个类别的概率大小。 所以如此看来,上示图片属于09号类别的概率分值最高,而09代表的是靴子,因此与其说是搜出最大值,softmax在此的作用是将该项目设为1,其它设为0。 image.png 所以我们要做的就是找出数值1。 image.png 接下来的训练非常简单,我们将训练图像与训练标签相匹配。

# 1.1.3训练、评估模型

model.fit(train_images, train_labels, epochs=5)
1

这次我们只训练5遍,还记得之前我们还有1万张图片和对应的标签没有用于训练吗?这些是模型“还没见过”的图像。所以可以用来测试模型的效能,测试方法就是将图像传递给评估方法,就像这样:

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

# 1.1.4模型预测

最后我们可以用 model.predict 来预测新图像:

predictions = model.predict(my_images)
1

这就是电脑查看和识别图像的一套方法,赶紧去试试吧!

# 1.2完整代码

import tensorflow as tf
from tensorflow import keras

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

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

model.compile(optimizer=tf.train.AdamOptimizer(),
              loss='sparse_categorical_crossentropy')

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

predictions = model.predict(test_images)
print(predictions[0])		#打印网络预测结果
print(test_labels[0])		#打印答案(标签label)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2.拓展阅读

# 2.1为什么要使用激活函数?

答:为了对网络模型提供非线性。 追问:为什么网络模型需要具备非线性分类的能力? 答:因为线性分类是用直线进行分类,而现实的问题往往是非线性的。 image.png

更新于: 12/30/2021, 2:39:56 AM