標籤:

譯文 | 簡明 TensorFlow 教程:混合模型

原文地址:TensorFlow in a Nutshell?—?Part Two: Hybrid Learning

原文作者:Camron Godbout

譯者:edvardhua

校對者:marcmoore, futureshine

確保你已經閱讀了第一部分

在本文中,我們將演示一個寬 N 深度網路,它使用廣泛的線性模型與前饋網路同時訓練,以證明它比一些傳統的機器學習技術能提供精度更高的預測結果。下面我們將使用混合學習方法預測泰坦尼克號乘客的生存概率。

混合學習技術已被 Google 應用在 Play 商店中提供應用推薦。Youtube 也在使用類似的混合學習技術來推薦視頻。

本文的代碼可以在這裡找到。

廣泛深度網路

寬和深網路將線性模型與前饋神經網路結合,使得我們的預測將具有記憶和通用化。 這種類型的模型可以用於分類和回歸問題。 這種方法能夠在減少特徵工程的同時擁有相對精確的預測結果,可謂一箭雙鵰。

廣泛深度網路

數據

我們將使用泰坦尼克號 Kaggle 數據來預測乘客的生存率是否和某些屬性有關,如姓名,性別,船票,船艙的類型等。有關此數據的更多信息請點擊這裡。

首先,我們要將所有列定義為連續或分類。

連續的列 - 連續範圍內的任何數值。 像錢或年齡。

分類列 - 有限集的一部分。 像男性或女性,或著乘客的國籍。

CATEGORICAL_COLUMNS = ["Name", "Sex", "Embarked", "Cabin"] nCONTINUOUS_COLUMNS = ["Age", "SibSp", "Parch", "Fare", "PassengerId", "Pclass"]n

因為我們只是想看看一個人是否倖存下來,這是一個二元分類問題。 所以預測結果 1 表示該乘客倖存下來,而結果 0 表示沒有倖存。(也即創建一列來儲存預測結果)

SURVIVED_COLUMN = "Survived"n

網路

現在我們可以創建列和添加嵌入層。 當我們構建我們的模型時,我們想要將我們的分類列變成稀疏列。 對於沒有那麼多類別(例如 Sex 或 Embarked(S,Q 或 C))的列,我們根據類名將它們轉換為稀疏列。(sparse_column_with_keys)

sex = tf.contrib.layers.sparse_column_with_keys(column_name="Sex",nkeys=["female", n"male"]) nembarked = tf.contrib.layers.sparse_column_with_keys(column_name="Embarked",nkeys=["C",n"S",n"Q"])n

對於類別較多的分類列,由於我們沒有一個辭彙表文件(vocab file)將所有可能的類別映射為一個整數,所以我們使用哈希值作為鍵值。(sparse_column_with_hash_bucket)

cabin = tf.contrib.layers.sparse_column_with_hash_bucket( n"Cabin", hash_bucket_size=1000) nname = tf.contrib.layers.sparse_column_with_hash_bucket( n"Name", hash_bucket_size=1000)n

我們的連續列使用的是真實的值。 因為 passengerId 是連續的而不是分類的,並且他們已經是整數的 ID 而不是字元串。

age = tf.contrib.layers.real_valued_column("Age") npassenger_id = tf.contrib.layers.real_valued_column("PassengerId") nsib_sp = tf.contrib.layers.real_valued_column("SibSp") nparch = tf.contrib.layers.real_valued_column("Parch")n fare = tf.contrib.layers.real_valued_column("Fare") np_class = tf.contrib.layers.real_valued_column("Pclass")n

我們需要根據年齡對乘客進行分類。 桶化(Bucketization )允許我們找到乘客對應年齡組的生存相關性,而不是將所有年齡作為一個大整體,從而提高我們的準確性。

age_buckets = tf.contrib.layers.bucketized_column(age,nboundaries=[n5, 18, 25, n30, 35, 40, n 45, 50, 55, n65 n])n

最後,我們將定義我們的廣度列和深度列。 我們的寬列將有效地記住我們與特徵之間的交互。 我們的寬列不會將我們的特徵通用化,這是深度列的用處。

wide_columns = [sex, embarked, p_class, cabin, name, age_buckets, tf.contrib.layers.crossed_column([p_class, cabin], hash_bucket_size=int(1e4)), ntf.contrib.layers.crossed_column( n[age_buckets, sex], n hash_bucket_size=int(1e6)), ntf.contrib.layers.crossed_column([embarked, name], hash_bucket_size=int(1e4))]n

擁有這些深度列的好處是,它會將我們提供的高維度稀疏的特徵進行降維來計算。

deep_columns = [ ntf.contrib.layers.embedding_column(sex, dimension=8), tf.contrib.layers.embedding_column(embarked, dimension=8), tf.contrib.layers.embedding_column(p_class, ndimension=8), ntf.contrib.layers.embedding_column(cabin, dimension=8), tf.contrib.layers.embedding_column(name, dimension=8), nage, npassenger_id, nsib_sp, nparch, nfare, n ]n

我們通過使用深度列和廣度列來創建分類器,以完成我們的函數。

return tf.contrib.learn.DNNLinearCombinedClassifier( nlinear_feature_columns=wide_columns, ndnn_feature_columns=deep_columns, ndnn_hidden_units=[100, 50])n

我們在運行網路之前要做的最後一件事是為我們的連續和分類列創建映射。 我們先創建一個輸入函數給我們的數據框,它能將我們的數據框轉換為 Tensorflow 可以操作的對象。 這樣做的好處是,我們可以改變和調整我們的 tensors 創建過程。 例如說我們可以將特徵列傳遞到.fit .feature .predict作為一個單獨創建的列,就像我們上面所描述的一樣,但這個是一個更加簡潔的方案。

def input_fn(df, train=False): n"""Input builder function.""" n# Creates a dictionary mapping from each continuous feature column name (k) to n# the values of that column stored in a constant Tensor. ncontinuous_cols = {k: tf.constant(df[k].values) for k in CONTINUOUS_COLUMNS} n# Creates a dictionary mapping from each categorical feature column name (k) n # to the values of that column stored in a tf.SparseTensor. ncategorical_cols = {k: tf.SparseTensor( nindices=[[i, 0] for i in range(df[k].size)], nvalues=df[k].values, nshape=[df[k].size, 1]) nfor k in CATEGORICAL_COLUMNS} n# Merges the two dictionaries into one. n feature_cols = dict(continuous_cols) nfeature_cols.update(categorical_cols) n# Converts the label column into a constant Tensor. nif train: nlabel = tf.constant(df[SURVIVED_COLUMN].values) n# Returns the feature columns and the label. nreturn feature_cols, label nelse: n # so we can predict our results that dont exist in the csv nreturn feature_colsn

現在,做完了以上工作,我們就可以開始編寫訓練功能了

def train_and_eval(): n """Train and evaluate the model.""" ndf_train = pd.read_csv( ntf.gfile.Open("./train.csv"), nskipinitialspace=True) ndf_test = pd.read_csv( n tf.gfile.Open("./test.csv"), nskipinitialspace=True) nmodel_dir = "./models" nprint("model directory = %s" % model_dir) nm = build_estimator(model_dir) nm.fit(input_fn=lambda: input_fn(df_train, True), steps=200) nprint m.predict(input_fn=lambda: input_fn(df_test)) nresults = m.evaluate(input_fn=lambda: input_fn(df_train, True), steps=1) nfor key in sorted(results): nprint("%s: %s" % (key, results[key]))n

我們讀取預處理後的 csv 文件,像處理缺失值等。為了讓文章保持簡潔,更多有關預處理的代碼和內容可以在代碼倉庫中找到。

這些 csv 文件將通過調用 input_fn 函數轉換為 tensors 。 我們先構建評價指標,然後列印我們的預測和評估結果。

結果

網路結果

運行我們的代碼為我們提供了相當好的結果,不需要添加任何額外的列或做任何特徵工程。 而且只要很少的微調這個模型可以得到相對較好的結果。

對比圖

與傳統廣度線性模型一起添加嵌入層的能力,允許通過將稀疏維度降低到低維度來進行準確的預測。

結論

這部分偏離了傳統的深度學習,說明 Tensorflow 還有許多其他用途和應用。 本文主要根據 Google 提供的論文和代碼進行廣泛深入的學習。 研究論文可以在這裡找到。 Google 將此模型用作 Google Play 商店的產品推薦引擎,並幫助他們在提高應用銷量上給出了建議。 YouTube 也發布了一篇關於他們使用混合模型做推薦系統的文章。 這些模型開始更多地被各種公司推薦,並且會因為優秀的嵌入能力越來越流行。

歡迎關注我們的微信公眾號:人工智慧LeadAI,ID:atleadai

推薦閱讀:

如何看待谷歌移動端深度學習框架 TensorFlow Lite 正式發布?可能會帶來什麼影響?
當tensorflow模型超過單張顯卡顯存的時候,應該怎麼拆分到多個GPU上運行?
cs20si: tensorflow for research 學習筆記1

TAG:TensorFlow |