使用tf.contrib.learn构建输入函数

来源:互联网 发布:安卓编程权威指南第3版 编辑:程序博客网 时间:2024/06/01 10:12

使用tf.contrib.learn构建输入函数

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

具有input_fn的自定义输入管道

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

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)将预处理和管道数据的逻辑封装到模型中。

一个input_fn的解剖

以下代码说明了输入函数的基本框架:

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_cols
包含将特征列名称映射到包含相应特征数据的Tensors(或SparseTensors)的键/值对的dict 
labels
Tensor包含您的标签(目标)值:您的模型旨在预测的值。

将特征数据转换为传感器

如果要素/标签数据存储在大熊猫 dataframes或numpy的数组,你需要将其转换为Tensor从返回之前小号input_fn

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

feature_column_data = [1, 2.4, 0, 9.9, 3, 120]
feature_tensor
= tf.constant(feature_column_data)

对于稀疏的分类数据 (大多数值为0的数据),您将要填充一个 SparseTensor,其中三个参数被实例化:

dense_shape
张量的形状。获取一个列表,显示每个维度中元素的数量。例如,dense_shape=[3,6]指定二维dense_shape=[2,3,4]3× 6张量,指定三维2x3x4张量,并dense_shape=[9]指定具有9个元素的一维张量。
indices
您的张量中包含非零值的元素的索引。获取术语列表,其中每个术语本身都是包含非零元素索引的列表。(元素为零索引 - 即,[0,0]是二维张量中第一行第一列中的元素的索引值。)例如,indices=[[1,3], [2,4]]指定索引为[1, 3]和[2,4]具有非零值。
values
价值的一维张量。期限ivalues对应到足月iindices,并指定其值。例如,给定indices=[[1,3], [2,4]],该参数values=[18, 3.6]指定张量的元素[1,3]的值为18,张量的元素[2,4]的值为3.6。

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

sparse_tensor = tf.SparseTensor(indices=[[0,1], [2,4]],
                                values
=[6, 0.5],
                                dense_shape
=[3, 5])

这对应于以下密集张量:

[[0, 6, 0, 0, 0]
 
[0, 0, 0, 0, 0]
 
[0, 0, 0, 0, 0.5]]

欲了解更多信息SparseTensor,请参阅 tf.SparseTensor

将input_fn数据传递给您的模型

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

classifier.fit(input_fn=my_input_fn, steps=2000)

请注意,input_fn负责向模型提供功能和标签数据,并替换其中的参数xy参数fit如果您提供的input_fnfitNone与非x或非y参数结合使用None,则会导致a ValueError

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

classifier.fit(input_fn=my_input_fn(training_set), steps=2000)

但是,如果您希望能够对输入函数进行参数设置,还有其他方法可以进行。您可以使用一个不需要参数的包装函数,input_fn并使用它来使用所需的参数来调用输入函数。例如:

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 函数来构造一个新的函数对象,并修改所有参数值:

classifier.fit(input_fn=functools.partial(my_input_function,
                                          data_set
=training_set), steps=2000)

第三个选项是将input_fn调用包装 lambda 到一个input_fn参数中,并将其传递给参数:

classifier.fit(input_fn=lambda: my_input_fn(training_set), steps=2000)

如上图所示,接受数据的参数在架构您的输入管道的一分大优势设置是,你可以在同一传递input_fnevaluate 和predict通过只是改变了数据集参数,如操作:

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每个住宅的平均房间年龄1940年以前建造的自住住宅的分数DIS距离波士顿地区就业中心每10,000元的物业税率PTRATIO学生与老师的比例

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

建立

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

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

进口房屋数据

要启动,请设置导入(包括pandastensorflow)并设置日志详细信息以 INFO获取更详细的日志输出:

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要区分功能与标签,还要定义FEATURESLABEL然后读取三个CSV(tf.train,,tf.test并 预测)到大熊猫 DataFrame s:

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并创建回归

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

feature_cols = [tf.contrib.layers.real_valued_column(k)
                 
for k in FEATURES]

注意:有关功能列的更深入的概述,请参阅 此介绍,以及说明如何定义FeatureColumns分类数据的示例,请参阅线性模型教程

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

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

构建input_fn

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

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参数,它表示该功能可以处理任何的DataFrame你已经导入S: ,training_settest_setprediction_set

训练回归者

训练神经网络回归器,运行fittraining_set传递input_fn如下:

regressor.fit(input_fn=lambda: input_fn(training_set), steps=5000)

您应该看到类似于以下内容的日志输出,其报告每100步骤的训练损失:

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

ev = regressor.evaluate(input_fn=lambda: input_fn(test_set), steps=1)

ev结果中检索出损失并将其输出:

loss_score = ev["loss"]
print("Loss: {0:f}".format(loss_score))

您应该会看到类似于以下内容的结果:

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,其中包含功能数据,但没有六个示例的标签:

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)))

您的结果应包含六项房屋价值预测数千美元,例如:

Predictions: [ 33.30348587  17.04452896  22.56370163  34.74345398  14.55953979
 
19.58005714]

其他资源

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

  • TensorFlow的大规模线性模型TensorFlow中线性模型的介绍提供了转换输入数据的特征列和技术的高级概述。

  • TensorFlow线性模型教程:本教程涵盖创建FeatureColumns和an,input_fn用于线性分类模型,根据人口普查数据预测收入范围。

  • TensorFlow Wide&Deep Learning教程:基于线性模型教程,本教程涵盖 FeatureColumninput_fn创建了一个“宽而深”的模型,它结合了线性模型和神经网络 DNNLinearCombinedClassifier

原创粉丝点击