使用 tf.contrib.learn 構(gòu)建輸入函數(shù)

我是一個(gè)很懶的人,我想試試

希望我能堅(jiān)持到最后,把tensorflow的官方教程全部翻譯出來

提高自己,也幫助他人

Building Input Functions with tf.estimator

本教程將向你介紹如何使用 tf.estimator 創(chuàng)建輸入函數(shù)。你將了解如何構(gòu)建一個(gè) input_fn 來預(yù)處理并將數(shù)據(jù)傳入你的模型中。然后你將使用 input_fn 將訓(xùn)練,評估和預(yù)測的數(shù)據(jù)傳入到神經(jīng)網(wǎng)絡(luò)回歸以便預(yù)測房屋的中位數(shù)價(jià)值。

Custom Input Pipelines with input_fn

input_fn 用于將特征和目標(biāo)數(shù)據(jù)傳遞給 Estimatortrainevaluatepredict 方法。用戶可以在input_fn進(jìn)行特征工程或者預(yù)處理。以下是從 tf.estimator Quickstart tutorial 得到的一個(gè)例子:

import numpy as np

training_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TRAINING, target_dtype=np.int, features_dtype=np.float32)

train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": np.array(training_set.data)},
    y=np.array(training_set.target),
    num_epochs=None,
    shuffle=True)

classifier.train(input_fn=train_input_fn, steps=2000)

Anatomy of an input_fn

以下代碼說明了輸入函數(shù)的基本框架:

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

輸入函數(shù)的主題包含了預(yù)處理輸入數(shù)據(jù)的特定邏輯,例如清理不好的樣本或 特征縮放

輸入函數(shù)必須返回以下兩個(gè)值,這兩個(gè)值是傳遞給你的模型的最終特征和標(biāo)簽數(shù)據(jù)(如上代碼框架所示):

  • feature_cols

    鍵/值對的字典,映射包含了相對應(yīng)的特征數(shù)據(jù)的特征 columns 名字到Tensor (或 SparseTensor) 中。

  • labels

    Tensor 包含了你的標(biāo)簽(目標(biāo))值:這個(gè)值是你的模型需要預(yù)測的。

Converting Feature Data to Tensors

如果你的特征/標(biāo)簽數(shù)據(jù)是一個(gè) python 數(shù)組或保存在 pandas 數(shù)據(jù)幀中或者 numpy 數(shù)組,你可以使用下面的方法構(gòu)造 input_fn:

import numpy as np
# numpy input_fn.
my_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": np.array(x_data)},
    y=np.array(y_data),
    ...)
import pandas as pd
# pandas input_fn.
my_input_fn = tf.estimator.inputs.pandas_input_fn(
    x=pd.DataFrame({"x": x_data}),
    y=pd.Series(y_data),
    ...)

對于 sparse, categorical data (其中大部分?jǐn)?shù)據(jù)值都是0),你將使用SparseTensor,它使用三個(gè)參數(shù)實(shí)例化:

  • dense_shape

    張量形狀。獲取一個(gè)列表指明每個(gè)維度的元素總數(shù)。例如,dense_shape=[3,6] 表示一個(gè)二維 3x6 張量,dense_shape=[2,3,4] 表示一個(gè)三維 2x3x4 張量,而 dense_shape=[9] 表示一個(gè)一維的包含9個(gè)元素的張量。

  • indices

    張量中包含非零值的元素的索引。獲取一個(gè) terms 列表,每個(gè) term 也是一個(gè)列表,包含了非零元素的索引。(元素為零的索引——例如[0,0]是一個(gè)二維張量第一行第一列的元素的索引值。) 例如,indices=[[1,3], [2,4]] 指索引為 [1,3] 和 [2,4] 的元素有非零值。

  • values

    一維張量值。values 的 term i 對應(yīng)于 indices 的 term i ,并指定它的值。例如,給定indices=[[1,3], [2,4]],參數(shù) values=[18, 3.6] 指定了張量元素 [1,3] 值為 18,張量元素 [2,4] 的值是 3.6。

以下代碼定義了一個(gè) 3 行 5 列的二維 SparseTensor 。索引 [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])

對應(yīng)下面的稠密 (dense) 張量:

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

欲了解更多 SparseTensor,請查閱 tf.SparseTensor

Passing input_fn Data to Your Model

提供數(shù)據(jù)給你的模型以便訓(xùn)練,你傳遞你創(chuàng)建的輸入函數(shù)到你的 train 函數(shù)中,作為input_fn 參數(shù)的值,例如:

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

注意input_fn 參數(shù)必須接收一個(gè)函數(shù)對象(例如,input_fn=my_input_fn),而不是函數(shù)調(diào)用的返回值(input_fn=my_input_fn()) 。這意味著,如果你嘗試在你的train 調(diào)用中傳遞值給input_fn ,如下代碼,將產(chǎn)生 TypeError

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

然而,如果你想要能夠參數(shù)化你的輸入函數(shù),還有其他的方法。你可以使用一個(gè) 不帶參數(shù)的 wrapper 函數(shù)作為你的 input_fn 。并使用它調(diào)用你的帶有想要的參數(shù)的輸入函數(shù)。例如:

def my_input_fn(data_set):
  ...

def my_input_fn_training_set():
  return my_input_fn(training_set)

classifier.train(input_fn=my_input_fn_training_set, steps=2000)

或者,你可以使用 Python 的 functools.partial 函數(shù)來構(gòu)造一個(gè)所有參數(shù)值是固定的新的函數(shù)對象:

classifier.train(
    input_fn=functools.partial(my_input_fn, data_set=training_set),
    steps=2000)

第三個(gè)選項(xiàng)是將你的 input_fn 調(diào)用包裝在 lambda 表達(dá)式中,并將其傳遞給 input_fn 參數(shù):

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

設(shè)計(jì)如上所示的輸入管道來接收數(shù)據(jù)集的參數(shù)的一個(gè)巨大的優(yōu)勢,是你可以傳遞相同的input_fnevaluatepredict 操作而只需要改變數(shù)據(jù)集參數(shù),例如:

classifier.evaluate(input_fn=lambda: my_input_fn(test_set), steps=2000)

這種方法增強(qiáng)了代碼的可維護(hù)性:不需要為每種操作定義多個(gè)input_fn (例如,input_fn_train, input_fn_test, input_fn_predict)。

最后,你可以使用 tf.estimator.inputs 中的方法來從 numpy 或者 pandas 數(shù)據(jù)集創(chuàng)建input_fn 。額外的好處是你可以使用更多的參數(shù),比如 num_epochsshuffle 來控制input_fn 如何迭代數(shù)據(jù):

import pandas as pd

def get_input_fn_from_pandas(data_set, num_epochs=None, shuffle=True):
  return tf.estimator.inputs.pandas_input_fn(
      x=pdDataFrame(...),
      y=pd.Series(...),
      num_epochs=num_epochs,
      shuffle=shuffle)
import numpy as np

def get_input_fn_from_numpy(data_set, num_epochs=None, shuffle=True):
  return tf.estimator.inputs.numpy_input_fn(
      x={...},
      y=np.array(...),
      num_epochs=num_epochs,
      shuffle=shuffle)

A Neural Network Model for Boston House Values

在本教程剩余部分,你將寫一個(gè)輸入函數(shù)來預(yù)處理從 UCI Housing Data Set 提取出的波士頓房價(jià)的子集,并用它傳遞數(shù)據(jù)給一個(gè)神經(jīng)網(wǎng)絡(luò)回歸,以便預(yù)測房價(jià)的中位數(shù)。

你將使用 Boston CSV data sets 來訓(xùn)練你的神經(jīng)網(wǎng)絡(luò),包含了以下波士頓郊區(qū)的 特征數(shù)據(jù)

特征 描述
CRIM Crime rate per capita
ZN Fraction of residential land zoned to permit 25,000+ sq ft lots
INDUS Fraction of land that is non-retail business
NOX Concentration of nitric oxides in parts per 10 million
RM Average Rooms per dwelling
AGE Fraction of owner-occupied residences built before 1940
DIS Distance to Boston-area employment centers
TAX Property tax rate per $10,000
PTRATIO Student-teacher ratio

你的模型預(yù)測的標(biāo)簽是 MEDV,自住住宅的價(jià)值的中位數(shù),單位千美元。

Setup

下載以下數(shù)據(jù)集:boston_train.csv, boston_test.csvboston_predict.csv

以下部分提供了逐步介紹如何創(chuàng)建一個(gè)輸入函數(shù),傳遞這些數(shù)據(jù)集給一個(gè)神經(jīng)網(wǎng)絡(luò)回歸,訓(xùn)練和評估模型,并預(yù)測房價(jià)。最終完整的代碼 available here

Importing the Housing Data

首先,設(shè)置 imports(包含 pandastensorflow) 并設(shè)置日志標(biāo)志為 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中定義數(shù)據(jù)集的列名。為了從標(biāo)簽中區(qū)分特征,還定義了FEATURESLABEL。然后讀取三個(gè) CSV(tf.train, tf.test, 和predict) 到 pandasDataFrame

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)

Defining FeatureColumns and Creating the Regressor

接下來,為輸入數(shù)據(jù)創(chuàng)建一列 FeatureColumn,它指定用于訓(xùn)練的特征 columns 。因?yàn)榉课輸?shù)據(jù)集的所有特征含有連續(xù)值,可以使用tf.contrib.layers.real_valued_column() 函數(shù)創(chuàng)建它們的 FeatureColumn

feature_cols = [tf.feature_column.numeric_column(k) for k in FEATURES]

注意:有關(guān)特征 columns 更深入的了解,請查看 這個(gè)介紹 ,例如說明如何定義 分類數(shù)據(jù)的FeatureColumns,請查閱 線性模型教程

現(xiàn)在,實(shí)例化神經(jīng)網(wǎng)絡(luò)回歸模型 DNNRegressor 。這里你需要提供兩個(gè)參數(shù):hidden_units,一個(gè)超參數(shù),指定每個(gè)隱藏層的節(jié)點(diǎn)數(shù)量(這里,兩個(gè)包含 10 個(gè)節(jié)點(diǎn)的隱藏層), feature_columns,包含你定義的一列的FeatureColumns

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

Building the input_fn

傳遞輸入數(shù)據(jù)給regressor,編寫一個(gè)接收 pandas Dataframe 的工廠方法并返回一個(gè)input_fn

def get_input_fn(data_set, num_epochs=None, shuffle=True):
  return tf.estimator.inputs.pandas_input_fn(
      x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
      y = pd.Series(data_set[LABEL].values),
      num_epochs=num_epochs,
      shuffle=shuffle)

請注意,輸入數(shù)據(jù)使用data_set 參數(shù)傳遞給input_fn ,這意味著函數(shù)可以處理你導(dǎo)入的任意的DataFrame : training_set, test_set, 和prediction_set

提供另外兩個(gè)參數(shù):num_epochs:控制迭代所有數(shù)據(jù)的 epochs 次數(shù) 。對于訓(xùn)練,設(shè)置這個(gè)值為 None,這樣input_fn 保持返回?cái)?shù)據(jù)知道達(dá)到所需的訓(xùn)練次數(shù)。對于評估和預(yù)測,設(shè)置這個(gè)值為 1,這樣input_fn將迭代所有數(shù)據(jù)一次,然后產(chǎn)生OutOfRangeError錯(cuò)誤。這個(gè)錯(cuò)誤會(huì)告訴Estimator停止評估和預(yù)測。shuffle:是否打亂數(shù)據(jù)。對于評估和預(yù)測,設(shè)置為False,這樣input_fn 將順序迭代所有的數(shù)據(jù)。對于訓(xùn)練,設(shè)置為 True

Training the Regressor

為了訓(xùn)練神經(jīng)網(wǎng)絡(luò)回歸器,運(yùn)行將training_set 傳遞給input_fntrain ,如下所示:

regressor.train(input_fn=get_input_fn(training_set), steps=5000)

你將看到類似下面的輸入日志,記錄了每一百次的訓(xùn)練損失:

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.

Evaluating the Model

接下來,看看對于測試數(shù)據(jù)集訓(xùn)練模型的性能如何。運(yùn)行evaluate,傳遞test_setinput_fn

ev = regressor.evaluate(
    input_fn=get_input_fn(test_set, num_epochs=1, shuffle=False))

ev 中取回?fù)p失并打印到輸出端:

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

你將看到類似下面的結(jié)果:

INFO:tensorflow:Eval steps [0,1) for training step 5000.
INFO:tensorflow:Saving evaluation summary for 5000 step: loss = 11.9221
Loss: 11.922098

Making Predictions

最后,你可以在prediction_set上使用模型預(yù)測房價(jià)的中位值,這六個(gè)樣本包含了特征數(shù)據(jù)但是沒有標(biāo)簽:

y = regressor.predict(
    input_fn=get_input_fn(prediction_set, num_epochs=1, shuffle=False))
# .predict() returns an iterator of dicts; convert to a list and print
# predictions
predictions = list(p["predictions"] for p in itertools.islice(y, 6))
print("Predictions: {}".format(str(predictions)))

你的結(jié)果應(yīng)包含六個(gè)房價(jià)預(yù)測值,單位千美元,例如:

Predictions: [ 33.30348587  17.04452896  22.56370163  34.74345398  14.55953979
  19.58005714]

Additional Resources

本教程重點(diǎn)在于創(chuàng)建一個(gè)神經(jīng)網(wǎng)絡(luò)回歸器的input_fn 。想要學(xué)習(xí)更多其他模型類型的input_fn ,請查看以下資源:

  • Large-scale Linear Models with TensorFlow: 對于線性模型,介紹了在 TensorFlow 中提供了一個(gè)高層次的特征 columns 的概述和技術(shù)轉(zhuǎn)換輸入數(shù)據(jù)。
  • TensorFlow Linear Model Tutorial: 本教程將介紹如何創(chuàng)建根據(jù)人口普查數(shù)據(jù)預(yù)測收入范圍的線性分類模型的FeatureColumninput_fn
  • TensorFlow Wide & Deep Learning Tutorial: 基于 Linear Model Tutorial ,本教程介紹使用結(jié)合了線性模型和使用DNNLinearCombinedClassifier神經(jīng)網(wǎng)絡(luò)的一個(gè)“又深又廣”的模型,創(chuàng)建FeatureColumninput_fn
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容