2022-02-09
本文也在自建博客地址发布。
本文翻译自英文教程。
本文档介绍了编程环境,并向您展示了如何使用它来解决虹膜分类问题。
先决条件
在使用本文档中的示例代码之前,您需要执行以下操作:
获取示例代码
按照以下步骤获取我们将在整个过程中使用的示例代码
通过输入以下命令克隆存储库:
git clone https://github.com/tensorflow/models
转到本文档中使用的示例所在目录
cd models/samples/core/get_started/
本文档中描述的程序是 .py。该程序使用 .py 来获取训练数据。
运行程序
像运行代码一样运行 TF 程序。例如:
python premade_estimator.py
程序应该对测试集进行预测,然后输出一些训练日志。例如,下面输出中的第一行显示模型感觉测试集中第一个示例的可能性为 99.6%。由于这个例子在测试集中,这实际上是一个很好的预测。
...
Prediction is "Setosa" (99.6%), expected "Setosa"
Prediction is "Versicolor" (99.8%), expected "Versicolor"
Prediction is "Virginica" (97.9%), expected "Virginica"
如果程序产生错误但没有输出答案,请回答以下问题:
编程栈
在深入了解程序本身的细节之前,让我们看一下编程环境。如下图所示,提供了一个由多个 API 层组成的编程栈:
我们强烈建议使用以下 API 编写程序:
虹膜的分类:概述
本文档中的示例程序构建并测试了一个模型,该模型根据萼片和花瓣大小将鸢尾花分为三个不同的物种。
从左到右,Iris (by, CC BY-SA 3.0), Iris (by, CC BY-SA 3.0) 和 Iris (by, Frank, CC BY -SA 2.0)。
数据集
鸢尾花数据集包含四个特征和一个标签。这四个特征确定了单个虹膜的以下植物学特征:
我们的模型将此特征表示为数值数据。
该标签用于识别矢车菊的类型,必须是以下 3 种之一:
我们的模型将标签作为 int32 分类数据。
下表显示了数据集中的三个示例:
萼片宽度 萼片长度 花瓣宽度 花瓣长度 种类(标签)
5.1
3.3
1.7
0.5
0()
5.0
2.3
3.3
1.0
1()
6.4
2.8
5.6
2.2
2()
算法
该程序训练具有以下拓扑的深度神经网络分类器模型:
下图说明了特征、隐藏层和预测(未显示隐藏层中的所有节点):
推理
在未标记的案例上运行经过训练的模型会产生三个预测,即这朵花是给定虹膜物种的可能性。这些输出预测的总和将为 1.0。例如,对未标记示例的预测可能如下所示:
前面的预测表明,给定的未标记示例有 95% 的可能性是 Iras。
() 编程概述
是完整模型的中间表示。它处理初始化、记录、保存和恢复以及许多其他功能的细节,以便您可以专注于您的模型。更多详情,请参阅。
是从 tf. 派生的泛型类。提供了一系列定制的评估器(例如)来实现常用的 ML 算法。除此之外,您还可以编写自己的自定义估算器。我们建议第一次使用外部的。在获得外部专业知识后,我们建议您通过创建自己的自定义来优化您的模型。
要遵循外部创作程序,您必须执行以下任务:
让我们看看这个任务是如何进行虹膜分类的。
创建一个输入函数(输入)
您必须创建输入函数来为训练、评估和预测提供数据。
输入函数 ( input ) 是一个返回 tf.data 的函数。输出二元组的对象:
label – 包含所有样本的标签字段
为了演示输入函数的格式,这里有一个简单的实现:
def input_evaluation_set():
features = {'SepalLength': np.array([6.4, 5.0]),
'SepalWidth': np.array([2.8, 2.3]),
'PetalLength': np.array([5.6, 3.3]),
'PetalWidth': np.array([2.2, 1.0])}
labels = np.array([2, 1])
return features, labels
您的输入可能会产生您喜欢的任何形式的函数字典和标签列表。但是,我们建议使用可以解析各种数据的 API。概括地说, API 由以下类组成:
这里每个成员如下:
API 为您处理许多常见情况。例如,使用 API,您可以轻松地从大量文件中并行读取记录并将它们合并到单个流中。
在这种情况下,为简单起见,我们将使用加载数据并从该内存数据构建输入管道。
以下是该程序中用于训练的输入,该函数在 .py 中可用:
def train_input_fn(features, labels, batch_size):
"""An input function for training"""
# Convert the inputs to a Dataset.
dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
# Shuffle, repeat, and batch the examples.
return dataset.shuffle(1000).repeat().batch(batch_size)
定义特征列
特征列 ( ) 是描述模型如何使用特征字典中的原始输入数据的对象。构建模型时,您传递一个特征列列表,描述您希望模型使用的每个特征。tf。模块提供了许多用于向模型表示数据的选项。
对于 iris,4 个原始特征是数字类型,因此我们将构建一个特征列列表来告诉模型将四个特征中的每一个表示为 32 位浮点值。因此,创建特征列的代码是:
# Feature columns describe how to use the input.
my_feature_columns=[]
for key in train_x,keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
特征列可能比我们在这里展示的要复杂得多。稍后我们将在入门指南中详细讨论功能列。
现在我们已经描述了我们希望模型如何表示原始特征,我们可以重建它。
实例化一个
虹膜问题是一个经典的分类问题。幸运的是,提供了几个预设分类器,包括:
对于虹膜问题,tf.. 看起来是最好的选择。下面是我们如何实例化它:
# Build a DNN with 2 hidden layers and 10 nodes in each hidden layer.
classifier = tf.estimator.DNNClassifier(
feature_columns=my_feature_columns,
# Two hidden layers of 10 nodes each.
hidden_units=[10, 10],
# The model must choose between 3 classes.
n_classes=3)
训练、评估和预测
现在我们有了一个对象,我们可以调用方法来执行以下操作:
训练模型
通过调用训练方法训练模型如下:
# Train the Model.
classifier.train(
input_fn=lambda:iris_data.train_input_fn(train_x, train_y, args.batch_size),
steps=args.train_steps)
这里我们使用一个表达式来捕获调用中包含的参数,它还提供了一个没有参数的输入函数,正如预期的那样。参数steps告诉模式在一些训练步骤后停止训练。
评估训练好的模型
现在模型已经训练好了,我们可以得到一些关于它的性能的统计数据。以下代码块评估训练模型在测试数据上的准确性:
# Evaluate the model.
eval_result = classifier.evaluate(
input_fn=lambda:iris_data.eval_input_fn(test_x, test_y, args.batch_size))
print('nTest set accuracy: {accuracy:0.3f}n'.format(**eval_result))
与我们的训练调用不同,我们没有传递 steps 参数来评估。我们只对数据做了一个 epoch。
运行此代码会产生以下输出(或类似输出):
Test set accuracy: 0.967
从经过训练的模型进行预测(推理)
我们现在有一个训练有素的模型,可以产生良好的评估结果。我们现在可以使用经过训练的模型从一些未标记的检测中预测虹膜的种类。与训练和评估一样,我们使用单个函数调用来进行预测:
# Generate predictions from the model
expected = ['Setosa', 'Versicolor', 'Virginica']
predict_x = {
'SepalLength': [5.1, 5.9, 6.9],
'SepalWidth': [3.3, 3.0, 3.1],
'PetalLength': [1.7, 4.2, 5.4],
'PetalWidth': [0.5, 1.5, 2.1],
}
predictions = classifier.predict(
input_fn=lambda:iris_data.eval_input_fn(predict_x,
batch_size=args.batch_size))
该方法返回一个迭代,它为每个示例生成一个预测字典。以下代码重现了一些预测及其概率:
for pred_dict, expec in zip(predictions, expected):
template = ('nPrediction is "{}" ({:.1f}%), expected "{}"')
class_id = pred_dict['class_ids'][0]
probability = pred_dict['probabilities'][class_id]
print(template.format(iris_data.SPECIES[class_id],
100 * probability, expec))
运行里面的代码会产生如下输出:
...
Prediction is "Setosa" (99.6%), expected "Setosa"
Prediction is "Versicolor" (99.8%), expected "Versicolor"
Prediction is "Virginica" (97.9%), expected "Virginica"
总结
预建估计器是快速创建标准模型的有效方法。
现在您已经开始编程,您可以参考以下资料:
源代码
这个示例代码总结到这里,直接复制运行即可(环境保证没问题)。
import pandas as pd
import tensorflow as tf
import argparse
TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv"
TEST_URL = "http://download.tensorflow.org/data/iris_test.csv"
CSV_COLUMN_NAMES = ['SepalLength', 'SepalWidth',
'PetalLength', 'PetalWidth', 'Species']
SPECIES = ['Setosa', 'Versicolor', 'Virginica']
parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=100, type=int, help='batch size')
parser.add_argument('--train_steps', default=1000, type=int,
help='number of training steps')
def load_data(y_name='Species'):
train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL)
train = pd.read_csv(train_path, names=CSV_COLUMN_NAMES, header=0)
train_x, train_y = train, train.pop(y_name)
test = pd.read_csv(test_path, names=CSV_COLUMN_NAMES, header=0)
test_x, test_y = test, test.pop(y_name)
return (train_x, train_y),(test_x, test_y)
def train_input_fn(features, labels, batch_size):
# 将输入转化为Dataset数据
dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
# shuffle, repeat, and batch
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
return dataset
def eval_input_fn(features, labels, batch_size):
features = dict(features)
if labels is None:
inputs = features
else:
inputs = (features, labels)
dataset = tf.data.Dataset.from_tensor_slices(inputs)
assert batch_size is not None, "batch_size must not be None"
dataset = dataset.batch(batch_size)
return dataset
def main(argv):
args = parser.parse_args(argv[1:])
# 获取数据,返回的数据都是pandas.DataFrame类型
(train_x, train_y), (test_x, test_y) = load_data()
# 说明特征列,告诉模型如何处理输入
my_feature_columns=[]
for key in train_x.keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
# 创建评估器Estimator
classifier = tf.estimator.DNNClassifier(
feature_columns=my_feature_columns,
hidden_units=[10, 10],
n_classes=3)
# 训练模型,
classifier.train(
input_fn=lambda:train_input_fn(train_x, train_y,
args.batch_size),
steps=args.train_steps)
# 评估模型
eval_result = classifier.evaluate(
input_fn=lambda:eval_input_fn(test_x, test_y,
args.batch_size))
print('nTest set accuracy: {accuracy:0.3f}n'.format(**eval_result))
# 从模型生成预测
expected = ['Setosa', 'Versicolor', 'Virginica']
predict_x = {
'SepalLength': [5.1, 5.9, 6.9],
'SepalWidth': [3.3, 3.0, 3.1],
'PetalLength': [1.7, 4.2, 5.4],
'PetalWidth': [0.5, 1.5, 2.1],
}
predictions = classifier.predict(
input_fn=lambda:eval_input_fn(predict_x,
labels=None,
batch_size=args.batch_size))
template = ('nPrediciton is "{}" ({:.1f}%), expected "{}"')
for pred_dict, expec in zip(predictions, expected):
class_id = pred_dict['class_ids'][0]
probability = pred_dict['probabilities'][class_id]
print(template.format(SPECIES[class_id],100*probability, expec))
if __name__ == '__main__':
tf.logging.set_verbosity(tf.logging.INFO)
tf.app.run(main)
分类:
技术要点:
相关文章:
暂无评论内容