页面树结构

版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

目录

 

面板
borderColor#00FFFF
borderStyledashed

原文链接 : https://www.tensorflow.org/get_started/input_fn

译文链接 : http://www.apache.wiki/pages/viewpage.action?pageId=10029487

贡献者 : 片刻 ApacheCN Apache中文网

校对:Ngxin

本教程将向您介绍如何在tf.contrib.learn中创建输入函数。您将了解如何构建input_fn去预处理和将数据输到模型中的概述。然后,您将实现利用input_fn将训练,评估和预测数据提供给神经网络回归器,用于预测房价中位数。

 

利用input_fn自定义输入Pipelines

当使用tf.contrib.learn训练神经网络,它可以直接通过您的特征和目标数据进行训练,分析或预测操作。这是一个从tf.contrib.learn快速入门教程中获取的示例

代码块
languagepy
training_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float32)
test_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TEST, target_dtype=np.int, features_dtype=np.float32)
...

classifier.fit(x=training_set.data,
               y=training_set.target,
               steps=2000) 
当需要对源数据进行少量操作时,这种方法运行良好。但是在需要更多特征工程的情况下, tf.contrib.learn支持使用自定义输入函数(input_fn)将预处
理和piping数据的逻辑封装到模型中。

解析input_fn

以下代码阐述了输入函数的基本框架:

代码块
languagepy
def my_input_fn():

    # Preprocess your data here...

    # ...then return 1) a mapping of feature columns to Tensors with
    # the corresponding feature data, and 2) a Tensor containing labels
    return feature_cols, labels
输入函数部分包含用于预处理输入数据的特定逻辑,例如擦除不良示例或feature scaling

输入函数必须返回以下两个值,其中包含要馈送到模型中的最终特征和标签数据(如上述代码框架所示):

feature_cols

      将特征列名称映射到相应特征数据的Tensors(或SparseTensors)的keys/values对的字典。

 labels

     包含您的标签(目标)值的张量:您的模型预测的值。

将特征数据转换为张量

如果特征/标签数据存储在pandas 数据架构或numpy数组,你需要将其转换为Tensor在它从input_fn返回之前。

对于连续数据,您可以使用tf.constant创建和填充Tensor

代码块
languagepy
feature_column_data = [1, 2.4, 0, 9.9, 3, 120]
feature_tensor = tf.constant(feature_column_data) 
对于稀疏分类数据 (大多数值为0的数据),您对含三个参数得SparseTensor实例化处理:

dense_shape

张量的形状。获取一个表示每个维度中元素数量的list。例如,dense_shape=[3,6]指二维3×6张量,dense_shape=[2,3,4]指三维2x3x4张量,dense_shape=[9]指具有9个元素的一维张量。

indices

您的张量中包含非零值的元素索引。获取term列表,其中每个term本身都是包含非零元素索引的列表。(零索引元素,如[0,0]是二维张量中第一行第一列中的元素的索引值。)例如,indices=[[1,3], [2,4]]指定索引为[1,3]和[2,4]的元素具有非零值。

values

values的一维张量。在values第i个term对应indices中第i个term,并指定其值。例如,给定indices=[[1,3], [2,4]],该参数values=[18, 3.6]指张量的元素[1,3]的值为18,张量的元素[2,4]的值为3.6。

以下代码定义了具有3行5列的二维SparseTensor。indices元素中的[0,1]值为6,indices元素中的[2,4]值为0.5(其他值为0):

代码块
languagepy
sparse_tensor = tf.SparseTensor(indices=[[0,1], [2,4]],
                                values=[6, 0.5],
                                dense_shape=[3, 5]) 
这对应于以下密集张量:
代码块
languagepy
[[0, 6, 0, 0, 0]
 [0, 0, 0, 0, 0]
 [0, 0, 0, 0, 0.5]]
欲了解SparseTensor的更多信息,请参阅 tf.SparseTensor

input_fn将数据传给模型

要将数据提供给您的模型进行训练,您只需将创建的输入函数传递给您的fit操作作为参数input_fn的值,例如:

代码块
languagepy
classifier.fit(input_fn=my_input_fn, steps=2000)
请注意,input_fn负责向模型提供特征和标签数据,并替换fit中的x,y参数。如果您提供给fitinput_fn值是x或y这样的非None参数,它会导致
 ValueError错误。

还要注意,input_fn参数必须接收一个函数对象(如input_fn=my_input_fn),而不是调用函数的返回值(如input_fn=my_input_fn())。这意味着如果您尝试将参数传递给fit中调用的输入函数,如下面的代码所示,它将导致 TypeError错误:

代码块
languagepy
classifier.fit(input_fn=my_input_fn(training_set), steps=2000)
但是,如果您希望能够对输入函数进行参数设置,还有其他方法可以进行。您可以使用一个不需要参数的包装函数作为你的input_fn,并使用它来使用所需的
参数传入函数。例如:
代码块
languagepy
def my_input_function_training_set():
  return my_input_function(training_set)

classifier.fit(input_fn=my_input_fn_training_set, steps=2000)
或者,您可以使用Python的functools.partial 函数来构造一个新的函数对象,并修改所有参数值:
代码块
languagepy
classifier.fit(input_fn=functools.partial(my_input_function,
                                          data_set=training_set), steps=2000)
第三个选则是在lambda中包装input_fn,并将其传递给input_fn参数:
代码块
languagepy
classifier.fit(input_fn=lambda: my_input_fn(training_set), steps=2000)
如上所示构建输入pipline的一个最大优点是接受数据集的参数,那就是您可以通过更改数据集参数传递input_fn进行分析和预测操作,例如:
代码块
languagepy
classifier.evaluate(input_fn=lambda: my_input_fn(test_set), steps=2000)
这种方法提高了代码的可维护性:无需捕获xy值在每个操作类型的独立变量(例如,x_trainx_testy_trainy_test)。

搭建波士顿房价的神经网络模型

在本教程的其余部分,您将编写一个输入函数,用于预处理从UCI住房数据集提取的波士顿住房数据的子集,并将其数据馈送到神经网络回归器以预测房价中位数。

用于训练神经网络的波士顿CSV数据集包含以下波士顿郊区的特征数据

特征描述
CRIM人均犯罪率
ZN住宅用地数目分布为25,000平方呎
INDUS非零售业务的土地部分
NOX每1000单位量的一氧化氮浓度
RM每个住宅的平均房间
AGE1940年以前建造的自住住宅分布
DIS距离波士顿地区就业中心
TAX每10,000元的物业税率
PTRATIO学生与老师的比例

而您的模型可以预测的标签是MEDV,拥有自住住宅的中位数,单位以千美元计。

 

构建

下载以下数据集: boston_train.csv, boston_test.csv和 boston_predict.csv

以下部分提供了如何创建输入函数的步骤,将这些数据集提供给神经网络回归器,训练和评估模型,并进行房屋价值预测。完整的代码可以在这里找到

导入房屋数据

导入Housing Data

让我们开始吧,请先安装需要的库(包括pandastensorflow)并将日志 设置成INFO以获取更详细的日志输出:

代码块
languagepy
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import itertools

import pandas as pd
import tensorflow as tf

tf.logging.set_verbosity(tf.logging.INFO)
定义数据集中的列名COLUMNS。为了区分标签的feature,还要定义FEATURESLABEL。然后读取三个CSV(tf.train,tf.test,predict到pandas DataFrames:
代码块
languagepy
COLUMNS = ["crim", "zn", "indus", "nox", "rm", "age",
           "dis", "tax", "ptratio", "medv"]
FEATURES = ["crim", "zn", "indus", "nox", "rm",
            "age", "dis", "tax", "ptratio"]
LABEL = "medv"

training_set = pd.read_csv("boston_train.csv", skipinitialspace=True,
                           skiprows=1, names=COLUMNS)
test_set = pd.read_csv("boston_test.csv", skipinitialspace=True,
                       skiprows=1, names=COLUMNS)
prediction_set = pd.read_csv("boston_predict.csv", skipinitialspace=True,
                             skiprows=1, names=COLUMNS)

定义FeatureColumns并创建回归

接下来,为输入数据创建一个FeatureColumns 列表,该列表正式指用于训练的特征集。因为数据集中的所有特征都包含连续值,所以您可以使用tf.contrib.layers.real_valued_column()函数创建FeatureColumn

代码块
languagepy
feature_cols = [tf.contrib.layers.real_valued_column(k)
                  for k in FEATURES]
注意:有关特征列的更深入的概述,请参阅 此介绍,以及说明如何定义FeatureColumns分类数据的示例,请参阅线性模型教程

现在,实例化一个DNNRegressor神经网络回归模型。您需要在这里提供两个参数:hidden_units,一个指定每个隐藏层中的节点数的超参数,(本例使用两个隐藏层,每个层具有10个节点),feature_columns包含刚刚定义的FeatureColumns列表 :

代码块
languagepy
regressor = tf.contrib.learn.DNNRegressor(feature_columns=feature_cols,
                                          hidden_units=[10, 10],
                                          model_dir="/tmp/boston_model")

构建input_fn

要将输入数据传入regressor,创建一个输入函数,它将接受一个pandas Dataframe并返回特征列和标签值作为 Tensors:

代码块
languagepy
def input_fn(data_set):
  feature_cols = {k: tf.constant(data_set[k].values)
                  for k in FEATURES}
  labels = tf.constant(data_set[LABEL].values)
  return feature_cols, labels
需要注意的是传入input_fndata_set参数,它表示该函数可以处理任何你已经导入的DataFrames:training_settest_setprediction_set

训练回归器

训练神经网络回归器,运行fit,其中training_set传递给input_fn,如下所示:

代码块
languagepy
regressor.fit(input_fn=lambda: input_fn(training_set), steps=5000)
您应该看到类似于以下内容的日志输出,每100步报告训练损失:
代码块
languagepy
INFO:tensorflow:Step 1: loss = 483.179
INFO:tensorflow:Step 101: loss = 81.2072
INFO:tensorflow:Step 201: loss = 72.4354
...
INFO:tensorflow:Step 1801: loss = 33.4454
INFO:tensorflow:Step 1901: loss = 32.3397
INFO:tensorflow:Step 2001: loss = 32.0053
INFO:tensorflow:Step 4801: loss = 27.2791
INFO:tensorflow:Step 4901: loss = 27.2251
INFO:tensorflow:Saving checkpoints for 5000 into /tmp/boston_model/model.ckpt.
INFO:tensorflow:Loss for final step: 27.1674.

评估模型

接下来,看看训练模型的性能对测试数据集的影响。运行 evaluate,这个时候传递test_setinput_fn

代码块
languagepy
ev = regressor.evaluate(input_fn=lambda: input_fn(test_set), steps=1)
ev结果中检索出损失并将其输出:
代码块
languagepy
loss_score = ev["loss"]
print("Loss: {0:f}".format(loss_score))
您应该会看到类似于以下内容的结果:
代码块
languagepy
INFO:tensorflow:Eval steps [0,1) for training step 5000.
INFO:tensorflow:Saving evaluation summary for 5000 step: loss = 11.9221
Loss: 11.922098

预测

最后,您可以使用该模型预测房价中值prediction_set,其中包含特征数据,但没有标签的六个示例:

代码块
languagepy
y = regressor.predict(input_fn=lambda: input_fn(prediction_set))
# .predict() returns an iterator; convert to a list and print predictions
predictions = list(itertools.islice(y, 6))
print ("Predictions: {}".format(str(predictions)))
您的结果应包含六项房屋价值预测数千美元,例如:
代码块
languagepy
Predictions: [ 33.30348587  17.04452896  22.56370163  34.74345398  14.55953979  19.58005714]

其他资源

本教程的重点是神经网络回归器创建一个input_fn。要了解有关将input_fn用于其他类型模型的更多信息,请查看以下资源: