学习教材是tensorflow官网上的新手教程
为了让自己有更深的印象和理解,将自己的学习笔记记录
基础分类:对于衣服的图片分类
本指南训练了一个神经网络模型来对衣服的图像进行分类,例如运动鞋和衬衫。
本指南使用tf.keras在TensorFlow中构建和训练模型。
from __future__ import absolute_import, division, print_function, unicode_literals
//这句话的作用就是将新版本的特性引进当前版本中,也就是说我们可以在当前版本使用新版本的一些特性。就是说比如现在是python2.0的版本,有了from __future__ import之后就能使用最新版本的Python的一些特新,后面跟的absolute_import, division, print_function, unicode_literals,这些就是新的特性
# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras
//导入tensorflow模块,导入keras模块
# Helper libraries
import numpy as np
import matplotlib.pyplot as plt
//导入numpy模块,导入 matplotlib.pyplot模块
print(tf.__version__)//输出当前tenssorflow的版本号
上面代码块的结果:
Fashion MNIST旨在替代经典MNIST数据集,通常被用作计算机视觉机器学习程序的“ Hello,World”。 MNIST数据集包含手写数字(0、1、2等)的图像,格式与您将在此处使用的衣服的格式相同。
本指南将Fashion MNIST用于多种用途,因为它比常规MNIST更具挑战性。 这两个数据集都相对较小,用于验证算法是否按预期工作。 它们是测试和调试代码的良好起点。
在这里,使用60,000张图像来训练网络,使用10,000张图像来评估网络学习对图像进行分类的准确度。 您可以直接从TensorFlow访问Fashion MNIST。 直接从TensorFlow导入和加载Fashion MNIST数据,如下:
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
加载数据集将返回四个NumPy数组:
train_images和train_labels数组是训练集,即模型用来学习的数据。
针对测试集,test_images和test_labels数组对模型进行测试。
图像是28x28 NumPy数组,像素值范围是0到255。标签是整数数组,范围是0到9。这些对应于图像表示的衣服类别:
每个图像都映射到一个标签。 由于类名不包含在数据集中,因此将它们存储在此处以供以后在绘制图像时使用,如下:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat','Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
探索数据:
在训练模型之前,让我们探索数据集的格式。 下图显示了训练集中有60,000张图像,每个图像表示为28 x 28像素:
print(train_images.shape)
print(len(train_labels))
print(train_labels)
结果:
测试集中有10,000张图像。 同样,每个图像都表示为28 x 28像素:
print(test_images.shape)
print(len(test_labels))
结果:
预处理数据:
在训练网络之前,必须对数据进行预处理。 如果检查训练集中的第一张图像,您将看到像素值落在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))//指定其宽和高为10个单位
for i in range(25)://i从0到24开始循环
plt.subplot(5,5,i+1)//代表图像有5*5个子图,然后对应的是第i+1个个数。
plt.xticks([])//x刻度设置为空
plt.yticks([])//y刻度设置为空
plt.grid(False)//设置为网格不显示
plt.imshow(train_images[i], cmap=plt.cm.binary)//将图片i转换为黑白图像
plt.xlabel(class_names[train_labels[i]])//每个子图的x刻度标签设置为类名
plt.show()//显示以上设置
如图:
建立模型;
建立神经网络需要配置模型的各层,然后编译模型。
设置层
神经网络的基本构建模块是层。在层里面精炼输入数据的表达,希望当前表达对问题是有意义的。
深度学习的大部分内容是将简单的层链接在一起。 大多数图层(例如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层序列组成。 这些是紧密连接或完全连接的神经层。 第一密集层具有128个节点(或神经元)。 第二层(也是最后一层)返回长度为10的logits数组。每个节点包含一个得分,该得分指示当前图像属于10个类之一。
编译模型
在准备训练模型之前,需要进行一些其他设置。 这些是在模型的编译步骤中添加的:
损失函数-衡量训练过程中模型的准确性。 您希望最小化此功能,以在正确的方向上“引导”模型。
优化器-这是基于模型看到的数据及其损失函数来更新模型的方式。
指标-用于监视培训和测试步骤。 以下示例的准确性(正确分类的图像的得分)
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
模型流程的设置:
optimizer=‘adam’,//Adam:(adaptive moment estimation)是对RMSProp优化器的更新.利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率.
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),//分类交叉熵损失函数
metrics=[‘accuracy’]//准确率
训练模型
训练神经网络模型需要执行以下步骤:
将训练数据输入模型。 在此示例中,训练数据在train_images和train_labels数组中。
该模型学习关联图像和标签。
您要求模型对测试集进行预测(在本示例中为test_images数组)。
验证预测是否与test_labels数组中的标签匹配。
输入数据
要开始训练,请调用model.fit方法,之所以这么称呼是因为它使模型适应训练数据:
model.fit(train_images, train_labels, epochs=10)
结果
Train on 60000 samples
Epoch 1/10
60000/60000 [==============================] - 4s 63us/sample - loss: 0.4992 - accuracy: 0.8245
Epoch 2/10
60000/60000 [==============================] - 3s 56us/sample - loss: 0.3768 - accuracy: 0.8641
Epoch 3/10
60000/60000 [==============================] - 3s 55us/sample - loss: 0.3388 - accuracy: 0.8753
Epoch 4/10
60000/60000 [==============================] - 3s 54us/sample - loss: 0.3141 - accuracy: 0.8845
Epoch 5/10
60000/60000 [==============================] - 3s 54us/sample - loss: 0.2945 - accuracy: 0.8915
Epoch 6/10
60000/60000 [==============================] - 3s 54us/sample - loss: 0.2807 - accuracy: 0.8964
Epoch 7/10
60000/60000 [==============================] - 3s 55us/sample - loss: 0.2668 - accuracy: 0.9015
Epoch 8/10
60000/60000 [==============================] - 3s 54us/sample - loss: 0.2571 - accuracy: 0.9037
Epoch 9/10
60000/60000 [==============================] - 3s 54us/sample - loss: 0.2488 - accuracy: 0.9067
Epoch 10/10
60000/60000 [==============================] - 3s 54us/sample - loss: 0.2391 - accuracy: 0.9101
<tensorflow.python.keras.callbacks.History at 0x7f84fe677940>
模型训练时,会显示损失和准确性指标。 该模型在训练数据上达到约0.91(或91%)的精度。
评估准确性
接下来,比较模型在测试数据集上的表现:
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
结果:
10000/10000 - 1s - loss: 0.3401 - accuracy: 0.8826
Test accuracy: 0.8826
事实证明,测试数据集的准确性略低于训练数据集的准确性。 训练准确性和测试准确性之间的差距代表过度拟合。 当机器学习模型在新的,以前看不见的输入上的表现比训练数据上的表现差时,就会发生过度拟合。 过度拟合的模型“存储”训练数据集中的噪声和细节,从而对新数据的模型性能产生负面影响。 有关更多信息,请参见以下内容:
证明过度拟合
防止过度拟合的策略
做预测
通过训练模型,您可以使用它来预测某些图像。 模型的线性输出。 附加一个softmax层,以将logit值转换为更容易解释的概率。
probability_model = tf.keras.Sequential([model,
tf.keras.layers.Softmax()])//堆叠模型,在原模型的基础之下,后面加上一个softmax层
predictions = probability_model.predict(test_images)//预测每个图像的标签用变量承接
在这里,模型已经预测了测试集中每个图像的标签。 让我们看一下第一个预测:
predictions[0]
结果
预测是10个数字组成的数组。 它们代表模型对图像对应于10种不同服装中的每一种的概率。 您可以看到哪个标签的置信度最高:
np.argmax(predictions[0])//返回最大值的索引
因此,该模型最有概率该图像是脚踝靴或class_names [9]。 检查测试标签表明此分类是正确的:
test_labels[0]
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)//设置x轴的值
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))//设置x轴的值为0到9
plt.yticks([])//y轴设置为空
thisplot = plt.bar(range(10), predictions_array, color="#777777")//设置柱形图
plt.ylim([0, 1])//设置y轴的范围为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))//设置图的大小为宽为6,高为3
plt.subplot(1,2,1)//设置子图有1行2列,索引为第1个
plot_image(i, predictions[i], test_labels, test_images)//绘图函数
plt.subplot(1,2,2)//设置子图有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()
和上图一样,不一样的是,这个是第12副图片
结果
让我们绘制一些带有预测的图像。 请注意,即使概率非常大,该模型也可能是错误的。
#绘制前X张测试图像,它们的预测标签和真实标签。
#将正确的预测颜色设置为蓝色,将不正确的预测颜色设置为红色。
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols//图片为15张
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)//子图个数为30个,注意索引的设置,就是第几个的位置
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()//显示以上设置
结果
使用训练模型
最后,使用经过训练的模型对单个图像进行预测。
#从测试数据集中获取图像。
img = test_images[1]
print(img.shape)
结果
tf.keras模型经过优化,可以一次对一批或一组示例进行预测。 因此,即使您使用的是单个图像,也需要将其添加到列表中:
# 将图像添加到batch中
img = (np.expand_dims(img,0))
print(img.shape)
现在开始预测
predictions_single = probability_model.predict(img)
print(predictions_single)
plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)
np.argmax(predictions_single[0])//返回预测的最大值的索引值