tensorflow学习笔记(1):使用入门

详细教程:https://www.tensorflow.org/get_started/premade_estimators
我们强烈建议使用下列 API 编写 TensorFlow 程序:

  • Estimator API:代表一个完整的模型。Estimator API 提供一些方法来训练模型、判断模型的准确率并生成预测。

  • Dataset API:构建数据输入管道。Dataset API 提供一些方法来加载和操作数据,并将数据馈送到您的模型中。Dataset API 与 Estimator API 合作无间。

##1. Estimator API

  • Estimator 是 TensorFlow 对完整模型的高级表示。它会处理初始化、日志记录、保存和恢复等细节部分,并具有很多其他功能,以便您可以专注于模型。

  • Estimator 是从 tf.estimator.Estimator 衍生而来的任何类。TensorFlow 提供一组预创建的 Estimator(例如 LinearRegressor)来实现常见的机器学习算法。除此之外,您可以编写自己的自定义 Estimator。

要根据预创建的 Estimator 编写 TensorFlow 程序,您必须执行下列任务:

  • 创建一个或多个输入函数。
  • 定义模型的特征列。
  • 实例化 Estimator,指定特征列和各种超参数。
  • 在 Estimator 对象上调用一个或多个方法,传递适当的输入函数作为数据的来源。

###1.1 创建输入函数

您必须创建输入函数来提供用于训练、评估和预测的数据。

输入函数是返回 tf.data.Dataset 对象的函数,此对象会输出下列含有两个元素的元组:

  • features - Python 字典,其中:
    每个键都是特征的名称。
    每个值都是包含此特征所有值的数组。
  • 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
    
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)) #tf.data.Dataset 对象,包含特征和类标

    # Shuffle, repeat, and batch the examples.
    return dataset.shuffle(1000).repeat().batch(batch_size)

###1.2 定义特征列

  • 特征列是一个对象,用于说明模型应该如何使用特征字典中的原始输入数据。

  • 特征列视为原始数据和 Estimator 之间的媒介。特征列内容丰富,使您可以将各种原始数据转换为 Estimator 可以使用的格式,从而可以轻松地进行实验。

# 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.feature_column 模块的函数。

# Defaults to a tf.float32 scalar.
numeric_feature_column = tf.feature_column.numeric_column(key="SepalLength")

# Represent a tf.float64 scalar.
numeric_feature_column = tf.feature_column.numeric_column(key="SepalLength",
 dtype=tf.float64)

# Represent a 10-element vector in which each cell contains a tf.float32.
vector_feature_column = tf.feature_column.numeric_column(key="Bowling",
                                                         shape=10)

# Represent a 10x5 matrix in which each cell contains a tf.float32.
matrix_feature_column = tf.feature_column.numeric_column(key="MyMatrix",
                                                         shape=[10,5])

###1.3 实例化estimator
TensorFlow 提供了几个预创建的分类器 Estimator,其中包括:

  • tf.estimator.DNNClassifier:适用于执行多类别分类的深度模型。
  • tf.estimator.DNNLinearCombinedClassifier:适用于宽度和深度模型。 - -
  • tf.estimator.LinearClassifier:适用于基于线性模型的分类器。
# 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)

###1.4 训练、评估、预测

  • 训练模型
#Train the Model.
classifier.train(
    input_fn=lambda:iris_data.train_input_fn(train_x, train_y, args.batch_size),
    steps=args.train_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))
  • 使用经过训练的模型进行预测。
# 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))

##2. Dataset API

tf.data 模块包含一系列类,可让您轻松地加载数据、操作数据并通过管道将数据传送到模型中。本文档通过两个简单的示例来介绍该 API:

  • 从 Numpy 数组中读取内存中的数据。

  • 从 csv 文件中读取行。
    ###2.1 从 Numpy 数组中读取内存中的数据
    ####2.1.1 参数

    • features:包含原始输入特征的 {‘feature_name’:array} 字典(或 DataFrame)。
    • labels:包含每个样本的标签的数组。
    • batch_size:表示所需批次大小的整数。
- import iris_data

# Fetch the data
train, test = iris_data.load_data()
features, labels = train

#然后,我们使用类似以下内容的行将此数据传递给了输入函数:

batch_size=100
iris_data.train_input_fn(features, labels, batch_size)

####2.1.2 切片
在最简单的情况下,tf.data.Dataset.from_tensor_slices 函数接受一个数组并返回表示该数组切片的 tf.data.Dataset。例如,一个包含 mnist 训练数据的数组的形状为 (60000, 28, 28)。将该数组传递给 from_tensor_slices,会返回一个包含 60000 个切片的 Dataset 对象,其中每个切片都是一个 28x28 的图像。

返回此 Dataset 的代码如下所示:

train, test = tf.keras.datasets.mnist.load_data()
mnist_x, mnist_y = train

mnist_ds = tf.data.Dataset.from_tensor_slices(mnist_x)
print(mnist_ds)

这段代码将输出以下行,显示数据集中条目的形状和类型。请注意,数据集不知道自己包含多少条目。

<TensorSliceDataset shapes: (28,28), types: tf.uint8>

####2.1.3 操作

# Shuffle, repeat, and batch the examples.
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
  • shuffle方法使用一个固定大小的缓冲区,在条目经过时执行随机化处理。将 buffer_size设置为大于Dataset中样本数的值,可确保数据完全被随机化处理。Iris 数据集仅包含 150 个样本。

  • repeat 方法会在结束时重启 Dataset。要限制周期数量,请设置 count 参数。

  • batch方法会收集大量样本并将它们堆叠起来以创建批次。这为批次的形状增加了一个维度。新的维度将添加为第一个维度。以下代码对之前的 MNIST Dataset 使用 batch方法。这样会产生一个包含表示 (28,28) 图像堆叠的三维数组的 Dataset
    ####2.1.4 返回
    每个 Estimator 的 train、evaluate 和 predict 方法都需要输入函数返回包含 TensorFlow 张量的 (features, label) 对。train_input_fn 使用以下行将数据集转换为所需格式:

# Build the Iterator, and return the read end of the pipeline.
features_result, labels_result = dataset.make_one_shot_iterator().get_next()

结果会生成与 Dataset 中条目的布局相匹配的 TensorFlow 张量结构。

###2.2 从 csv 文件中读取行
####2.2.1 下载数据

import iris_data
train_path, test_path = iris_data.maybe_download()

iris_data.csv_input_fn 函数包含使用 Dataset 解析 csv 文件的备用实现。

####2.2.2 构建 Dataset

我们先构建一个 TextLineDataset 对象来实现一次读取文件中的一行数据。然后,我们调用 skip 方法来跳过文件的第一行,此行包含标题,而非样本:

ds = tf.data.TextLineDataset(train_path).skip(1)

####2.2.3 构建 csv 行解析器

最终,我们需要解析数据集中的每一行,以生成必要的 (features, label) 对

为了生成必要的 (features, label) 对,我们必须解析数据集中的每一行。以下 _parse_line 函数会调用 tf.decode_csv,以将单行解析为特征和标签两个部分。由于 Estimator 需要将特征表示为字典,因此我们依靠 Python 的内置 dict 和 zip 函数来构建此字典。特征名称是该字典的键。然后,我们调用字典的 pop 方法以从特征字典中移除标签字段:

# Metadata describing the text columns
COLUMNS = ['SepalLength', 'SepalWidth',
           'PetalLength', 'PetalWidth',
           'label']
FIELD_DEFAULTS = [[0.0], [0.0], [0.0], [0.0], [0]]
def _parse_line(line):
    # Decode the line into its fields
    fields = tf.decode_csv(line, FIELD_DEFAULTS)

    # Pack the result into a dictionary
    features = dict(zip(COLUMNS,fields))

    # Separate the label from the features
    label = features.pop('label')

    return features, label

ds = ds.map(_parse_line)
print(ds)

你可能感兴趣的:(tensorflow学习笔记(1):使用入门)