本教程将向您介绍如何在tf.contrib.learn中创建输入函数。您将了解如何构建input_fn
预处理和将数据馈送到模型中的概述。然后,您将实施一个input_fn
将训练,评估和预测数据提供给神经网络回归器,用于预测房屋中值。
具有input_fn的自定义输入管道
当使用tf.contrib.learn训练神经网络,它可以直接通过您的特性和目标数据进入你fit
,evaluate
或predict
操作。这是一个从获取的示例:
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
输入函数的正文包含用于预处理输入数据的特定逻辑,例如擦除不良示例或。
输入函数必须返回以下两个值,其中包含要馈送到模型中的最终特征和标签数据(如上述代码框架所示):
- 包含将特征列名称映射到包含相应特征数据的
Tensor
s(或SparseTensor
s)的键/值对的dict 。 - A
Tensor
包含您的标签(目标)值:您的模型旨在预测的值。
feature_cols
labels
将特征数据转换为传感器
如果要素/标签数据存储在 dataframes或数组,你需要将其转换为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=[3,6]
指定二维dense_shape=[2,3,4]
3× 6张量,指定三维2x3x4张量,并dense_shape=[9]
指定具有9个元素的一维张量。 - 您的张量中包含非零值的元素的索引。获取术语列表,其中每个术语本身都是包含非零元素索引的列表。(元素为零索引 - 即,[0,0]是二维张量中第一行第一列中的元素的索引值。)例如,
indices=[[1,3], [2,4]]
指定索引为[1, 3]和[2,4]具有非零值。 - 价值的一维张量。期限
i
在values
对应到足月i
的indices
,并指定其值。例如,给定indices=[[1,3], [2,4]]
,该参数values=[18, 3.6]
指定张量的元素[1,3]的值为18,张量的元素[2,4]的值为3.6。
dense_shape
indices
values
以下代码定义了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
,请参阅 。
将input_fn数据传递给您的模型
要将数据提供给您的模型进行培训,您只需将创建的输入函数传递给您的fit
操作作为input_fn
参数的值,例如:
classifier.fit(input_fn=my_input_fn, steps=2000)
请注意,input_fn
负责向模型提供功能和标签数据,并替换其中的参数x
和y
参数fit
。如果您提供的input_fn
值fit
不None
与非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的 函数来构造一个新的函数对象,并修改所有参数值:
classifier.fit(input_fn=functools.partial(my_input_function, data_set=training_set), steps=2000)
第三个选项是将input_fn调用包装 到一个input_fn
参数中,并将其传递给参数:
classifier.fit(input_fn=lambda: my_input_fn(training_set), steps=2000)
如上图所示,接受数据的参数在架构您的输入管道的一分大优势设置是,你可以在同一传递input_fn
到evaluate
和predict
通过只是改变了数据集参数,如操作:
classifier.evaluate(input_fn=lambda: my_input_fn(test_set), steps=2000)
这种方法提高了代码的可维护性:无需捕获x
和y
在单独的变量的值(例如,x_train
,x_test
,y_train
,y_test
)对于每个类型的操作。
波士顿房价值的神经网络模型
在本教程的其余部分,您将编写一个输入函数,用于预处理从提取的波士顿住房数据的子集,并将其用于将数据馈送到神经网络回归器以预测房屋中值。
您将用于训练神经网络的包含 波士顿郊区的以下 :
特征 | 描述 |
---|---|
CRIM | 人均犯罪率 |
ZN | 住宅用地数目分布为25,000平方呎 |
INDUS | 非零售业务的土地部分 |
NOX | 一氧化氮浓度每1000万份 |
RM | 每个住宅的平均房间 |
年龄 | 1940年以前建造的自住住宅的分数 |
DIS | 距离波士顿地区就业中心 |
税 | 每10,000元的物业税率 |
PTRATIO | 学生与老师的比例 |
而您的模型可以预测的标签是MEDV,拥有自住住宅的中位数以千美元计。
建立
下载以下数据集: , 和 。
以下部分提供了如何创建输入函数的逐步演练,将这些数据集提供给神经网络回归器,训练和评估模型,并进行房屋价值预测。完整的,最终的代码。
进口房屋数据
要启动,请设置导入(包括pandas
和tensorflow
)并以 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
。要区分功能与标签,还要定义FEATURES
和LABEL
。然后读取三个CSV(,,并 )到大熊猫 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
为输入数据创建一个s 列表,该列表正式指定用于训练的功能集。因为外壳数据集中的所有功能都包含连续值,所以您可以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
和返回特征列和标签值为 Tensor
s:
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_fn
的data_set
参数,它表示该功能可以处理任何的DataFrame
你已经导入S: ,training_set
,test_set
和prediction_set
。
训练回归者
训练神经网络回归器,运行fit
与training_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_set
到input_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
用于其他类型模型的更多信息,请查看以下资源:
-
:介绍提供了转换输入数据的特征列和技术的高级概述。
-
:本教程涵盖创建
FeatureColumn
s和an,input_fn
用于线性分类模型,根据人口普查数据预测收入范围。 -
:基于,本教程涵盖
FeatureColumn
并input_fn
创建了一个“宽而深”的模型,它结合了线性模型和神经网络DNNLinearCombinedClassifier
。