將遷移學習應用于計算機視覺模型的例子很常見,但如果將其用于文本分類,情況又會如何呢?不妨進入TensorFlow Hub,這是通過遷移學習來增強 TF 模型的內容庫。遷移學習是這樣一種過程:選用已借助大量數據訓練好的已有模型的權重和變量,并將其運用于自己的數據和預測任務。
遷移學習具有諸多好處,其中之一就是您無需像從頭開始訓練時一樣提供自己的大量訓練數據。但這些已有模型又來自何處呢?這正是 TensorFlow Hub 大顯身手之處:它可以為各類模型(圖像、文本等)提供現有模型檢查點的完整存儲區。在本篇博文中,我將介紹如何使用 TensorFlow Hub 文本模塊構建一個模型,以根據相關描述預測電影類型。
您可以使用Colab在瀏覽器中運行此模型,無需任何設置。
導入數據并進行預處理
在這個模型中,我們將使用Kaggle 電影數據集這個出色的公共領域資源。該數據集包含逾 45000 部電影的數據,每部電影均有大量相關數據。為簡便起見,我們僅使用該數據集中的電影描述(稱作 “簡介”)和電影類型。下面是該數據集在 Kaggle 中的預覽:
注:Kaggle 電影數據集鏈接
https://www.kaggle.com/rounakbanik/the-movies-dataset/home
首先,我們將導入要使用的內容庫,以構建此模型:
1import numpy as np
2import pandas as pd
3
4import tensorflow as tf
5import tensorflow_hub as hub
6
7from sklearn.preprocessing import MultiLabelBinarizer
我已經將這個數據集的 CSV 文件放在一個公共 Cloud Storage 存儲分區中。我們可以運行如下命令,將數據下載到我們的 Colab 實例中,并讀取為 Pandas dataframe 格式:
1!wget 'https://storage.googleapis.com/movies_data/movies_metadata.csv'
2data = pd.read_csv('movies_metadata.csv')
3
4descriptions = data['overview']
5genres = data['genres']
為簡便起見,我們將可能的類型限定為下列幾種:
1top_genres = ['Comedy', 'Thriller', 'Romance', 'Action', 'Horror', 'Crime', 'Documentary', 'Adventure', 'Science Fiction']
我們將數據集限定為這些類型中描述非空白的電影,然后按照 80% 訓練和 20% 測試的比例將數據劃分為訓練數據集和測試數據集:
1train_size = int(len(descriptions) * .8)
2
3train_descriptions = descriptions[:train_size]
4train_genres = genres[:train_size]
5
6test_descriptions = descriptions[train_size:]
7test_genres = genres[train_size:]
使用 TF Hub 構建嵌入層
以 TF Hub 創建嵌入層時僅需使用極少量代碼。我們的模型僅有一個特征(描述),并將表示為一個嵌入列。文本嵌入提供了在向量空間表示文本內容的方法,如此一來,嵌入空間中相似的字詞或句子會更靠近(您可在此處閱讀更多相關內容)。您可以完全使用自己的數據從頭開始構建文本嵌入向量。TF Hub 可提供已使用各種文本數據訓練過的文本嵌入,因而能夠簡化這一過程。
注:文本嵌入鏈接
https://www.tensorflow.org/hub/modules/text
對于英文文本,TF Hub 提供了各種已使用不同種類文本數據訓練過的嵌入:
通用語句編碼器 (Universal sentence encoder):用于較長的文本輸入
ELMo:使用十億單詞基準 (1B Word Benchmark) 訓練過的深度嵌入
神經網絡語言模型 (Neural Network Language Model)嵌入:通過 Google 新聞訓練
Word2vec:通過 Wikipedia 訓練
您所選擇的預訓練文本嵌入是您模型中的一個超參數,所以最好用不同的文本嵌入進行試驗,看看哪個的準確性最高。先從用與您的文本最接近的文本訓練過的模型開始。由于我們的電影描述都是較長的輸入,因此,我發現使用通用語句編碼器嵌入的準確性最高。這可以將我們的描述編碼為高維文本向量。請注意,這一特定模型很大,會占用 1GB 容量。
注:通用語句編碼器鏈接
https://www.tensorflow.org/hub/modules/google/universal-sentence-encoder/2
我們可以使用 hub.text_embedding_column,以一行代碼為該層創建一個特征列,并向其傳遞我們層的名稱 (“movie_descriptions”) 和要使用的 TF Hub 模型網址:
1description_embeddings = hub.text_embedding_column(
2"movie_descriptions",
3module_spec="https://tfhub.dev/google/universal-sentence-encoder/2"
4)
請注意,該單元正在下載預訓練過的嵌入,因此需要一些時間來運行。
此操作最大的好處在于,我們無需進行任何預處理,即可將文本描述饋送至預訓練過的字詞嵌入。如果從頭開始構建此模型,我們就需要自己將描述轉換為向量,但使用 TF Hub 列,我們可以將描述字符串直接傳遞至模型。
將標簽變為 multi-hot 編碼
由于一部電影往往具有多種類型,所以我們的模型會為每部電影返回多個可能的標簽。我們的類型目前是每部電影有一個字符串列表(例如 [‘Action’, ‘Adventure’])。由于每個標簽的長度必須相同,所以我們要將這些列表轉換為由 1 和 0(與特定描述中的類型相對應)組成的 multi-hot 向量。動作冒險片的 multi-hot 向量如下所示:
注:多個可能的標簽鏈接
https://en.wikipedia.org/wiki/Multi-label_classification
1# Genre lookup, each genre corresponds to an index
2top_genres = ['Comedy', 'Thriller', 'Romance', 'Action', 'Horror', 'Crime', 'Documentary', 'Adventure', 'Science Fiction']
3
4# Multi-hot label for an action and adventure movie
5[0 0 0 1 0 0 0 1 0]
要用短短幾行代碼將字符串標簽轉換為 multi-hot 向量,我們需要使用名為 MultiLabelBinarizer 的 Scikit Learn 實用程序:
1encoder = MultiLabelBinarizer()
2encoder.fit_transform(train_genres)
3train_encoded = encoder.transform(train_genres)
4test_encoded = encoder.transform(test_genres)
5num_classes = len(encoder.classes_)
您可以打印 encoder.classes_,查看模型預測的所有字符串類列表。
構建并訓練 DNNEstimator 模型
針對我們的模型,我們將使用 DNNEstimator 構建能夠返回 multi-hot 向量的深度神經網絡,這是因為每部電影會具有 0 個或多個可能的標簽(這與每個輸出正好有一個標簽的模型不同)。我們傳遞至 DNNEstimator 的第一個參數稱作 head,且此參數會定義我們的模型預期具有的標簽類型。我們希望我們的模型可以輸出多個標簽,所以我們在這里使用 multi_label_head:
1multi_label_head = tf.contrib.estimator.multi_label_head(
2num_classes,
3loss_reduction=tf.losses.Reduction.SUM_OVER_BATCH_SIZE
4)
現在,當我們實例化 DNNEstimator 時,便可對其進行傳遞。hidden_units 參數表示我們網絡中的層數。此模型有 2 個層,第一層有 64 個神經元,第二層有 10 個。層數和層大小是超參數,所以您應當嘗試不同的值,看看哪個最適合您的數據集。最后,我們將特征列傳遞至估算器。在本例中,我們只有一個特征列(即描述),而且在上文中已將其定義為 TF Hub 嵌入列,所以在此我們可以將其作為列表傳遞:
1estimator = tf.contrib.estimator.DNNEstimator(
2head=multi_label_head,
3hidden_units=[64,10],
4feature_columns=[description_embeddings]
5)
我們基本準備就緒,很快就可以開始訓練模型了。在訓練估算器實例之前,我們需要定義訓練輸入函數。輸入函數可以將我們的數據與模型聯系起來。在這里,我們將使用 numpy_input_fn,并將我們的數據作為 Numpy 數組饋送至模型:
1# Format our data for the numpy_input_fn
2features = {
3"descriptions": np.array(train_descriptions)
4}
5labels = np.array(train_encoded)
6
7train_input_fn = tf.estimator.inputs.numpy_input_fn(
8features,
9labels,
10shuffle=True,
11batch_size=32,
12num_epochs=20
13)
我們輸入函數中的 batch_size 和 num_epochs 參數都是超函數。batch_size 可告知我們的模型在一次迭代中會有多少示例傳遞至模型,而 num_epochs 是指我們的模型完成整個訓練集的次數。
現在可以開始訓練我們的模型了。只用一行代碼即可:
1estimator.train(input_fn=train_input_fn)
為了評估模型的準確性,我們用自己的測試數據創建一個 eval 函數 input_function,然后調用 estimator.evaluate():
1eval_input_fn = tf.estimator.inputs.numpy_input_fn({"descriptions": np.array(test_descriptions).astype(np.str)}, test_encoded.astype(np.int32), shuffle=False)
2
3estimator.evaluate(input_fn=eval_input_fn)
此模型的 AUC 達到 91.5%,而查準率/查全率為 74%。您的結果可能稍有不同。
使用我們已訓練的模型生成預測結果
現在到了最精彩的部分:根據我們的模型從未見過的數據生成預測結果。首先,我們設置一個包含一些描述的數組(我從 IMDB 中獲取這些描述):
1raw_test = [
2"An examination of our dietary choices and the food we put in our bodies. Based on Jonathan Safran Foer's memoir.", # Documentary
3"A teenager tries to survive the last week of her disastrous eighth-grade year before leaving to start high school.", # Comedy
4"Ethan Hunt and his IMF team, along with some familiar allies, race against time after a mission gone wrong." # Action, Adventure
5]
然后,我們定義預測輸入函數并調用 predict():
1predict_input_fn = tf.estimator.inputs.numpy_input_fn({"descriptions": np.array(raw_test).astype(np.str)}, shuffle=False)
2
3results = estimator.predict(predict_input_fn)
最后,我們可以迭代訪問結果,并顯示為每部電影找到的前 2 個類型及其置信度值:
1for movie_genres in results:
2top_2 = movie_genres['probabilities'].argsort()[-2:][::-1]
3for genre intop_2:
4text_genre = encoder.classes_[genre]
5print(text_genre + ': ' + str(round(movie_genres['probabilities'][genre] * 100, 2)) + '%')
我們的模型能夠正確標記上述所有電影描述。
使用入門
想用 TF Hub 開始構建自己的模型嗎?請參閱此文檔和教程。您可以在GitHub或Colab上找到本文所述的完整模型代碼。在之后的博文中,我會介紹如何導出此模型,以用于 TensorFlow Serving 或 Cloud ML Engine,并構建可根據新描述生成預測結果的應用。
-
數據集
+關注
關注
4文章
1223瀏覽量
25366 -
tensorflow
+關注
關注
13文章
330瀏覽量
61102 -
遷移學習
+關注
關注
0文章
74瀏覽量
5707
原文標題:使用 TensorFlow Hub 和估算器構建文本分類模型
文章出處:【微信號:tensorflowers,微信公眾號:Tensorflowers】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
評論