文章目录

  • 1. 环境配置及数据集准备
  • 2. 创建一个 tf.data.Dataset
  • 3. 选择模型类型
  • 4. 使用keras创建模型
  • 5. 训练模型
    • 5.1 定义损失和梯度函数
    • 5.2 创建优化器
    • 5.3 训练循环
    • 5.4 建立测试数据集
    • 5.5 根据测试数据集评估模型
    • 5.6 使用经过训练的模型进行预测

1. 环境配置及数据集准备

import os
import matplotlib.pyplot as plt
import tensorflow as tf# 默认情况下,TensorFlow 用 eager execution 来实时评估操作, 返回具体值而不是建立一个稍后执行的计算图。
# print("TensorFlow version: {} ".format(tf.__version__))  # TensorFlow version: 2.6.2
# print("Eager execution: {} " .format(tf.executing_eagerly()))  # Eager execution: True

**我们将根据鸢尾花花萼和花瓣的长度和宽度对其进行分类。鸢尾属约有 300 个品种,但我们的程序将仅对下列三个品种进行分类:山鸢尾、维吉尼亚鸢尾、变色鸢尾。**我们导入和解析训练数据集,下载别人已创建了一个包含有花萼和花瓣的测量值的120 株鸢尾花的数据集。

使用 tf.keras.utils.get_file 函数下载训练数据集文件。该函数的作用主要是直接从URL下载资源:fname: 文件名。如果指定了绝对路径,那么文件将会保存到那个路径。origin: 文件的原始 URL。

train_dataset_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_training.csv"
# 使用 tf.keras.utils.get_file 函数下载训练数据集文件。该函数会返回下载文件的文件路径:
train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url), origin=train_dataset_url)
print("Local copy of the dataset file: {}".format(train_dataset_fp))


数据集 iris_training.csv 是一个纯文本文件,其中存储了逗号分隔值 (CSV) 格式的表格式数据。我们在控制台使用 head -n5 命令查看前 5 个条目:

我们可以从该数据集视图中注意到以下信息:

**第一行是表头,其中包含数据集信息:**数据集共有 120 个样本。每个样本都有四个特征和一个标签名称,标签名称有三种可能。
后面的行是数据记录,每个样本各占一行。其中前四个字段是特征:这四个字段代表的是样本的特点。在此数据集中,这些字段存储的是代表花卉测量值的浮点数。最后一列是标签,即我们想要预测的值。对于此数据集,该值为 0、1 或 2 中的某个整数值(每个值分别对应一个花卉名称)。

我们用代码表示出来:

# 花萼长度、花萼宽度、花瓣长度、花瓣宽度
column_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']feature_names = column_names[:-1]
label_name = column_names[-1]print("Features: {}".format(feature_names))  # Features: ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
print("Label: {}".format(label_name))  # Label: species

每个标签都分别与一个字符串名称(例如 “setosa” )相关联,但机器学习通常依赖于数字值。标签编号会映射到一个指定的表示法,例如0代表山鸢尾、1代表变色鸢尾、2代表维吉尼亚鸢尾

class_names = ['Iris setosa', 'Iris versicolor', 'Iris virginica']

2. 创建一个 tf.data.Dataset

由于数据集是 CSV 格式的文本文件,请使用 make_csv_dataset 函数将数据解析为合适的格式。由于此函数为训练模型生成数据,默认行为是对数据进行随机处理 (shuffle=True, shuffle_buffer_size=10000),并且无限期重复数据集(num_epochs=None)。 我们还设置了 batch_size 参数:

batch_size = 32train_dataset = tf.data.experimental.make_csv_dataset(train_dataset_fp,batch_size,column_names=column_names,label_name=label_name,num_epochs=None
)

make_csv_dataset 返回一个(features, label) 对构建的 tf.data.Dataset ,其中 features 是一个字典: {'feature_name': value}
这些 Dataset 对象是可迭代的。 我们来看看下面的一些特征:

features, labels = next(iter(train_dataset))
print("features:", features)
print("labels:", labels)


注意到具有相似特征的样本会归为一组,即分为一批。更改 batch_size 可以设置存储在这些特征数组中的样本数。
绘制该批次中的几个特征后,就会开始看到一些集群现象:

plt.scatter(features['petal_length'],  # 输入数据features['sepal_length'],  # 输入数据c=labels,  # 表示的是色彩或颜色序列cmap='viridis'  # Colormap,标量或者是一个colormap的名字: cmap="viridis":黄到蓝
)
plt.xlabel("Petal length")
plt.ylabel("Sepal lenght")
plt.show()


再看一下width的可视化:

补充:关于cmap的参数设置可以参考:https://blog.csdn.net/ztf312/article/details/102474190

要简化模型构建步骤,请创建一个函数以将特征字典重新打包为形状为 (batch_size, num_features) 的单个数组。此函数使用 tf.stack 方法,该方法从张量列表中获取值,并创建指定维度的组合张量:

def pack_features_vector(features, labels):"""Pack the features into a single array."""features = tf.stack(list(features.values()), axis=1)return features, labels

然后使用 tf.data.Dataset.map 方法将每个 (features,label) 对中的 features 打包到训练数据集中。那么,Dataset 的特征元素被构成了形如 (batch_size, num_features) 的数组。

train_dataset = train_dataset.map(pack_features_vector)
features, labels = next(iter(train_dataset))print(features[:5])
print("features shape: ", features.shape)  # (32, 4)

上述处理可以得到如下结果:

3. 选择模型类型

我们需要选择要进行训练的模型类型。模型具有许多类型,挑选合适的类型需要一定的经验。本教程使用神经网络来解决鸢尾花分类问题。**神经网络可以发现特征与标签之间的复杂关系。**神经网络是一个高度结构化的图,其中包含一个或多个隐含层。每个隐含层都包含一个或多个神经元。 神经网络有多种类别,该程序使用的是密集型神经网络,也称为全连接神经网络 : 一个层中的神经元将从上一层中的每个神经元获取输入连接。例如,图 2 显示了一个密集型神经网络,其中包含 1 个输入层、2 个隐藏层以及 1 个输出层:

当图 2 中的模型经过训练并获得无标签样本后,它会产生 3 个预测结果:相应鸢尾花属于指定品种的可能性。这种预测称为推理。对于该示例,输出预测结果的总和是 1.0。在图 2 中,该预测结果分解如下:山鸢尾为 0.02,变色鸢尾为 0.95,维吉尼亚鸢尾为 0.03。这意味着该模型预测某个无标签鸢尾花样本是变色鸢尾的概率为 95%。

4. 使用keras创建模型

tf.keras.Sequential 模型是层的线性堆叠。该模型的构造函数会采用一系列层实例;在本示例中,采用的是 2 个密集层(各自包含10个节点),以及 1 个输出层(包含 3 个代表标签预测的节点。第一个层的 input_shape 参数对应该数据集中的特征数量,它是一项必需参数:

model = tf.keras.Sequential([tf.keras.layers.Dense(10, activiation=tf.nn.relu, input_shape=(4,)),tf.keras.layers.Dense(10, activiation=tf.nn.relu),tf.keras.layers.Dense(3)
])

激活函数可决定层中每个节点的输出形式。 这些非线性关系很重要,如果没有它们,模型将等同于单个层。激活函数有很多种,但隐藏层通常使用 ReLU。

**隐藏层和神经元的理想数量取决于问题和数据集。**与机器学习的多个方面一样,选择最佳的神经网络形状需要一定的知识水平和实验基础。一般来说,增加隐藏层和神经元的数量通常会产生更强大的模型,而这需要更多数据才能有效地进行训练。

我们快速了解一下此模型如何处理一批特征:

predictions = model(features)
print(predictions[:5])

输出结果为:

在此示例中,每个样本针对每个类别返回一个 logit。要将这些对数转换为每个类别的概率,请使用 softmax 函数:

对每个类别执行tf.argmax运算可得出预测的类别索引:根据axis取值(axis=0时比较每一列的元素,将每一列最大元素所在的索引记录下来,最后输出每一列最大元素所在的索引数组;axis=1时比较每一行的元素……)的不同返回每行或者每列最大值的索引。不过,该模型尚未接受训练,因此这些预测并不理想。

print("Predictions: {}".format(tf.argmax(predictions, axis=1)))
print("     Labels: {}".format(labels))

输出结果为:

5. 训练模型

训练是一个机器学习阶段,==在此阶段中,模型会逐渐得到优化,也就是说,模型会了解数据集。==目标是充分了解训练数据集的结构,以便对未见过的数据进行预测。如果您从训练数据集中获得了过多的信息,预测便会仅适用于模型见过的数据,但是无法泛化。此问题被称之为过拟合—就好比将答案死记硬背下来,而不去理解问题的解决方式。
鸢尾花分类问题是监督式机器学习的一个示例: 模型通过包含标签的样本加以训练。 ==而在非监督式机器学习中,样本不包含标签。==相反,模型通常会在特征中发现一些规律。

5.1 定义损失和梯度函数

在训练和评估阶段,我们都需要计算模型的损失。 这样可以衡量模型的预测结果与预期标签有多大偏差,也就是说,模型的效果有多差。我们希望尽可能减小或优化这个值。
我们的模型会使用 tf.keras.losses.SparseCategoricalCrossentropy 函数计算其损失,此函数会接受模型的类别概率预测结果和预期标签,然后返回样本的平均损失。

# 本质上就是交叉熵函数。from_logits:True就是需要经过softmax进行概率化
loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)def loss(model, x, y, training):y_ = model(x, training=training)return loss_object(y_true=y, y_pred=y_)l = loss(model, features, labels, training=False)
print("Loss test: {}".format(l))

使用tf.GradientTape的前后关系来计算梯度以优化你的模型。GradientTape 可以理解为“梯度流记录磁带”。
GradientTape 的详细解释参考:https://zhuanlan.zhihu.com/p/102207302

def grad(model, inputs, targets):with tf.GradientTape() as tape:loss_value = loss(model, inputs, targets, training=True)return loss_value, tape.gradient(loss_value, model.trainable_variables)

5.2 创建优化器

优化器会将计算出的梯度应用于模型的变量,以使 loss 函数最小化。您可以将损失函数想象为一个曲面(如下图的优化算法在三维空间中随时间推移而变化的可视化效果),==我们希望通过到处走动找到该曲面的最低点。==梯度指向最高速上升的方向,因此我们将沿相反的方向向下移动。我们以迭代方式计算每个批次的损失和梯度,以在训练过程中调整模型。模型会逐渐找到权重和偏差的最佳组合,从而将损失降至最低。损失越低,模型的预测效果就越好。

TensorFlow有许多可用于训练的优化算法。此模型使用的是 tf.train.GradientDescentOptimizer , 它可以实现随机梯度下降法(SGD)learning_rate 被用于设置每次迭代(向下行走)的步长。 这是一个超参数 ,我们通常需要调整此参数以获得更好的结果。

我们来设置优化器:

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

我们将使用它来计算单个优化步骤:

loss_value, grads = grad(model, features, labels)
print("Step: {}, Initial Loss: {}".format(optimizer.iterations.numpy(),loss_value.numpy()))
optimizer.apply_gradients(zip(grads, model.trainable_variables))
print("Step: {},         Loss: {}".format(optimizer.iterations.numpy(),loss(model, features, labels, training=True).numpy()))

运行结果为:

5.3 训练循环

一切准备就绪后,就可以开始训练模型了!训练循环会将数据集样本馈送到模型中,以帮助模型做出更好的预测。以下代码块可设置这些训练步骤:

  1. 迭代每个周期。通过一次数据集即为一个周期。
  2. 在一个周期中,遍历训练 Dataset 中的每个样本,并获取样本的特征(x)和标签(y)。
  3. 根据样本的特征进行预测,并比较预测结果和标签。衡量预测结果的不准确性,并使用所得的值计算模型的损失和梯度。
  4. 使用 optimizer 更新模型的变量。
  5. 跟踪一些统计信息以进行可视化。
  6. 对每个周期重复执行以上步骤。

num_epochs 变量是遍历数据集集合的次数。与直觉恰恰相反的是,训练模型的时间越长,并不能保证模型就越好。num_epochs 是一个可以调整的超参数。选择正确的次数通常需要一定的经验和实验基础。

## Note: Rerunning this cell uses the same model variables# Keep results for plotting
train_loss_results = []
train_accuracy_results = []num_epochs = 201for epoch in range(num_epochs):epoch_loss_avg = tf.keras.metrics.Mean()epoch_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()# Training loop - using batches of 32for x, y in train_dataset:# Optimize the modelloss_value, grads = grad(model, x, y)optimizer.apply_gradients(zip(grads, model.trainable_variables))# Track progressepoch_loss_avg.update_state(loss_value)  # Add current batch loss# Compare predicted label to actual label# training=True is needed only if there are layers with different# behavior during training versus inference (e.g. Dropout).epoch_accuracy.update_state(y, model(x, training=True))# End epochtrain_loss_results.append(epoch_loss_avg.result())train_accuracy_results.append(epoch_accuracy.result())if epoch % 50 == 0:print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch, epoch_loss_avg.result(),  epoch_accuracy.result()))

可视化损失函数随时间推移而变化的情况:
虽然输出模型的训练过程有帮助,但查看这一过程往往更有帮助。 TensorBoard 是与 TensorFlow 封装在一起的出色可视化工具,不过我们可以使用 matplotlib 模块创建基本图表。我们可以看到,损失函数随着epoch的增加而减少,准确率随着epoch的增加而增加。

fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')axes[0].set_ylabel("Loss", fontsize=14)
axes[0].plot(train_loss_results)axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epoch", fontsize=14)
axes[1].plot(train_accuracy_results)
plt.show()

5.4 建立测试数据集

评估模型与训练模型相似。最大的区别在于,样本来自一个单独的测试集,而不是训练集。为了公正地评估模型的效果,用于评估模型的样本务必与用于训练模型的样本不同。

测试 Dataset 的建立与训练 Dataset 相似。下载 CSV 文本文件并解析相应的值,然后对数据稍加随机化处理:

test_url = "https://storage.googleapis.com/download.tensorflow.org/data/iris_test.csv"
test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url), origin=test_url)test_dataset = tf.data.experimental.make_csv_dataset(test_fp,batch_size,column_names=column_names,label_name='species',num_epochs=1,shuffle=False)test_dataset = test_dataset.map(pack_features_vector)

5.5 根据测试数据集评估模型

与训练阶段不同,模型仅评估测试数据的一个周期。在以下代码单元格中,我们会遍历测试集中的每个样本,然后将模型的预测结果与实际标签进行比较。这是为了衡量模型在整个测试集中的准确率。

test_accuracy = tf.keras.metrics.Accuracy()for (x, y) in test_dataset:# training=False is needed only if there are layers with different# behavior during training versus inference (e.g. Dropout).logits = model(x, training=False)prediction = tf.argmax(logits, axis=1, output_type=tf.int32)test_accuracy(prediction, y)print("Test set accuracy: {:.3%}".format(test_accuracy.result()))

5.6 使用经过训练的模型进行预测

我们已经训练了一个模型并“证明”它是有效的,但在对鸢尾花品种进行分类方面,这还不够。现在,我们使用经过训练的模型对 无标签样本(即包含特征但不包含标签的样本)进行一些预测。

在现实生活中,无标签样本可能来自很多不同的来源,包括应用、CSV 文件和数据 Feed。暂时我们将手动提供三个无标签样本以预测其标签。回想一下,标签编号会映射到一个指定的表示法:0(山鸢尾)、1(变色鸢尾)、2(维吉尼亚鸢尾)。

predict_dataset = tf.convert_to_tensor([[5.1, 3.3, 1.7, 0.5,],[5.9, 3.0, 4.2, 1.5,],[6.9, 3.1, 5.4, 2.1]
])# training=False is needed only if there are layers with different
# behavior during training versus inference (e.g. Dropout).
predictions = model(predict_dataset, training=False)for i, logits in enumerate(predictions):class_idx = tf.argmax(logits).numpy()p = tf.nn.softmax(logits)[class_idx]name = class_names[class_idx]print("Example {} prediction: {} ({:4.1f}%)".format(i, name, 100*p))

03-鸢尾花分类问题(120个样本的实验)相关推荐

  1. HBU-NNDL 实验五 前馈神经网络(3)鸢尾花分类

    目录 深入研究鸢尾花数据集 4.5 实践:基于前馈神经网络完成鸢尾花分类 4.5.1 小批量梯度下降法 4.5.1.1 数据分组 4.5.2 数据处理 4.5.2.2 用DataLoader进行封装 ...

  2. 神经网络与深度学习(五)前馈神经网络(3)鸢尾花分类

    目录 4.5实践:基于前馈神经网络完成鸢尾花分类 深入研究鸢尾花数据集 4.5.1 小批量梯度下降法 4.5.1.1 数据分组 4.5.2 数据处理 4.5.2.2 用DataLoader进行封装 4 ...

  3. 猿创征文|深度学习基于前馈神经网络完成鸢尾花分类

    大家我是猿童学!这次给大家带来的是基于前馈神经网络完成鸢尾花分类! 在本实验中,我们使用的损失函数为交叉熵损失:优化器为随机梯度下降法:评价指标为准确率. 一.小批量梯度下降法 在梯度下降法中,目标函 ...

  4. KNN算法(附鸢尾花分类实现)

    ​ 1.k近邻算法 k近邻学习(K-Nearest Neighbor,简称KNN)学习是一种常用的监督学习方法,其工作机制非常简单:给定测试样本,基于某种距离度量找出训练集中与其距离最近的k个样本,然 ...

  5. 深度学习分类步骤——鸢尾花分类

    1.数据集的介绍 以鸢尾花数据集为例,共有150组,每组包括花萼长.花萼宽.花瓣长.花瓣宽4个输入特征.同时给出了这一组特征对应的鸢尾花的类别.类别包括狗尾草鸢尾.杂色鸢尾以及弗吉尼亚鸢尾,分别用0, ...

  6. Python机器学习日记2:鸢尾花分类(持续更新)

    Python机器学习日记2:鸢尾花分类 一.书目与章节 二. 前言 1. 什么是机器学习 2. 熟悉任务和数据 3. 本文软件版本 4. scikit-learn参考资料 三. 问题类型 四. 鸢尾花 ...

  7. 深度学习 第3章线性分类 实验四 pytorch实现 Softmax回归 鸢尾花分类任务 下篇

    目录: 第3章 线性分类 3.3 实践:基于Softmax回归完成鸢尾花分类任务 3.3.1 数据处理 3.3.1.1 数据集介绍 3.3.1.2 数据清洗 1. 缺失值分析 2. 异常值处理 3.3 ...

  8. 机器学习项目实践——鸢尾花分类

    基于SVM算法实现鸢尾花分类 摘要:支持向量机,因其英文名为support vector machine,故一般简称SVM,通俗来讲,它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分 ...

  9. adaboost算法java代码_04-04 AdaBoost算法代码(鸢尾花分类)

    [TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/p ...

最新文章

  1. html辅助方法引入验证类后怎么写,Html辅助方法
  2. 错误:Subquery returns more than 1 row 表示子查询返回了多行数据
  3. 必备快速定位排查问题命令
  4. Microsoft SQL Server 2019开发版安装配置教程
  5. 【转】Linux如何在系统启动时自动加载模块
  6. 学习Spring Boot:(二十一)使用 EhCache 实现数据缓存
  7. 正则化、归一化含义解析(一)
  8. Spring-扫描/jar/读取Classpath下的文件资源
  9. Python获取路径中的文件名
  10. 教育部 计算机类专业代码,全国本科专业代码查询
  11. breakall lisp文件_cad中pl线画的粗线转线框后,能转到su里封面么,求解
  12. 单片机STM32入门——(2)按键控制
  13. 供应链金融系统建设的具体实施步骤
  14. Verilog语言基础语法
  15. 这几天心里颇不宁静,采的不是信号,而是寂寞
  16. Material doesn‘t have a texture property ‘_MainTex
  17. 业务系统如何集成工作流引擎?
  18. 大牛耗时一年最佳总结,让你的app体验更丝滑!震撼来袭免费下载!
  19. 1044 mysql_Mysql的常见几种错误:1045,1044
  20. Java JVM参数调优配置

热门文章

  1. 更新日志 - fir.im Jenkins Gradle 插件上线
  2. 非线性规划:实例与matlab应用
  3. 自考大专计算机专业英语翻译,大专英语自考(上册)课文翻译及习题答案(138页)-原创力文档...
  4. Gbox开源:比RN和WebView更轻的高性能动态化业务容器,你掌握了多少
  5. RecyclerView+自定义IndexBar实现自定义带索引的通讯录
  6. 【物理应用】Matlab实现两端固支梁热力耦合的有限元分析
  7. HTML让背景图片铺满整个图片
  8. 计算机音乐夜空,星空音乐在线点播系统
  9. 一个简单的app爬虫:对近期热播剧《三十而已》进行知乎app关键词搜索
  10. 如何使用 FFmpeg 进行视频转码:字幕