我是一個(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ù)傳遞給 Estimator
的 train
, evaluate
和 predict
方法。用戶可以在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
的 termi
對應(yīng)于indices
的 termi
,并指定它的值。例如,給定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_fn
給 evaluate
和 predict
操作而只需要改變數(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_epochs
和 shuffle
來控制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.csv 和 boston_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(包含 pandas
和 tensorflow
) 并設(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ū)分特征,還定義了FEATURES
和 LABEL
。然后讀取三個(gè) CSV(tf.train
, tf.test
, 和predict) 到 pandas 的 DataFrame
:
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_fn
的train
,如下所示:
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_set
給input_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ù)測收入范圍的線性分類模型的
FeatureColumn
和input_fn
。 -
TensorFlow Wide & Deep Learning Tutorial: 基于 Linear Model Tutorial ,本教程介紹使用結(jié)合了線性模型和使用
DNNLinearCombinedClassifier
神經(jīng)網(wǎng)絡(luò)的一個(gè)“又深又廣”的模型,創(chuàng)建FeatureColumn
和input_fn
。