Uber開源TensorFlow框架工具箱Ludwig,無需編碼即可進行深度學習開發

日前,網約車服務商 Uber 開源併發布了它們開發的 Ludwig,這是一款基於 Google TensorFlow 框架上的開源工具箱。藉由 Ludwig,用戶無需再編寫任何代碼即可進行深度學習的開發,AI 前線爲讀者們翻譯了由 Uber AI 工程師們撰寫的這篇文章,希望有所啓示。

在過去的十年中,人們證明了深度學習在視覺、語音和語言方面執行各種各樣的機器學習任務非常有效。Uber 將這些深度學習模型用於各種任務,包括客戶支持、對象檢測、改進地圖、簡化聊天溝通、預測和防止欺詐。

現在有很多開源庫,包括 TensorFlow、PyTorch、CNTK 和 Chainer 等,已經實現了構建此類模型所需的構件,從而可以進行更快、更不易出錯的開發。而這些反過來又推動了機器學習研究界和行業從業者採用這種模型,從而在架構設計和行業解決方案方面取得了快速的進展。

Uber AI 決定避免重新發明輪子,在開源庫所提供的強大基礎之上開發軟件包。爲此,Uber AI 於 2017 年發佈了 Pyro,這是一種基於 PyTorch 的深度概率編程語言,並藉助開源社區的力量繼續改進。Uber 開發的另一個主要開源人工智能工具是 Horovod,這是由 LF 深度學習基金會(LF Deep Learning Foundation)託管的一個框架,允許在多個 GPU 和多臺機器上對深度學習模型進行分佈式訓練。

Uber 在 TensorFlow 的基礎上開發了一款開源深度學習工具箱,命名爲 Ludwig,允許用戶在無需編寫代碼的情況下即可訓練並測試深度學習模型。

Ludwig 的獨特之處在於它能夠幫助非專家更容易地理解深度學習,併爲經驗豐富的機器學習開發者和研究人員提供更快的模型改進迭代週期。通過使用 Ludwig,專家和研究人員可以簡化原型設計過程及數據處理,這樣他們就可以專注於開發深度學習體系架構,而不是深陷數據整理。

Ludwig

在過去兩年裏,爲了簡化應用項目中深度學習模型的使用,因爲它們通常需要在不同架構和快速迭代之間進行比較,Uber 內部一直在開發 Ludwig。Uber 已經見證了 Ludwig 對 Uber 自有的幾個項目帶來的價值,包括人工智能客服助理平臺(Customer Obsession Ticket Assistant ,COTA)、駕照的信息提取、司乘之間對話興趣點的識別、送餐速度預測等等。出於這些原因,Uber 決定開源併發布 Ludwig,因爲他們認爲目前還沒有任何其他解決方案具有相同的易用性和靈活性。

Uber 最初將 Ludwig 設計爲通用工具,用於在處理新的應用機器學習問題時簡化模型開發和比較過程。爲實現這一目標,Uber 從其他機器學習軟件汲取了靈感:Weka 和 MLlib,它們直接處理原始數據並提供一定數量的預構建模型的想法;Caffe 定義文件的聲明性;scikit-learn,一套簡單的編程 API。這些靈感混合在一起,使得 Ludwig 迥異於常見的深度學習庫,後者提供張量代數(tensor algebra)原語和很少的其他工具來編碼模型,同時使 Ludwig 比 PyText、StanfordNLP、AllenNLP 和 OpenCV等其他專業庫更加通用。

Ludwig 提供了一組模型架構,這些架構可以組合在一起,爲給定的用例創建端到端模型。打個比方,如果說深度學習庫爲你的建築提供了構建塊,那麼 Ludwig 就相當於構建城市的構建塊,你可以選擇可用的建築物或你自己的建築物添加到可用的建築中。

Uber 在 Ludwig 工具箱中提出的核心設計原則是:

  • 無需編碼:該工具無需編碼技能即可訓練模型並將其用於獲取預測。
  • 通用性:一種新的基於數據類型的深度學習模型設計方法,使該工具可用於許多不同的用例。
  • 靈活性:經驗豐富的用戶可以對模型構建和訓練進行廣泛的控制,而對新手而言,該工具易於使用。
  • 可擴展性:該工具易於添加新的模型架構和新的特徵數據類型。
  • 可理解性:深度學習模型內部通常被認爲是 “黑盒”,但 Uber 提供了標準的可視化來理解它們的性能並比較它們的預測。

Ludwig 允許用戶通過僅提供包含數據的表格文件(如 CSV)和 YAML 配置文件來訓練深度學習模型,YAML 配置文件指定表格文件的哪些列是輸入特徵,哪些列是輸出目標變量。配置文件的簡單性可以加快原型設計速度,從而有望將編碼時間減少到幾分鐘。如果指定了多個輸出目標變量,Ludwig 將執行多任務學習,學習同時預測所有的輸出,而這通常需要定製代碼。

模型定義可以包含附加信息,尤其是數據集中每個特徵的預處理信息,用於每個特徵的編碼器或解碼器,每個編碼器和解碼器的架構參數以及訓練參數。預處理、訓練和各種模型架構參數的默認值是依據 Uber 的經驗選擇的,或者是根據學術文獻改變的,這樣新手就可以輕鬆訓練複雜的模型。同時,在模型配置文件中分別設置每一項的能力,爲專家提供了充分的靈活性。使用 Ludwig 訓練的每個模型都將會被保存,並且可以在以後加載來獲得對新數據的預測。比如,模型可以被加載到服務環境中,這樣就可以在軟件應用中提供預測。

image

圖1:可以在Ludwig的模型描述文件中指定幾個輸入和輸出特徵,它們的組合涵蓋了許多機器學習任務。
Ludwig 引入的主要新思想是數據類型特定編碼器和解碼器的概念,這爲 Uber 帶來了高度模塊化和可擴展的架構:支持的每種數據類型(文本、圖像、類別等)都有特定的預處理功能。簡言之,編輯器將原始數據映射到張量,而解碼器則將張量映射到原始數據。

通過這種設計,用戶可以訪問組合器(架構的膠合組件),他們組合了來自所有輸入編碼器的張量,並進行處理,然後返回用於輸出解碼器的張量。例如,Ludwig 的默認合併多個數據組合器連接不同編碼器的輸出,將它們傳遞到完全連接的層,並提供最終激活作爲輸出解碼器的輸入。其他組合器可用於其他用例,通過實現簡單的函數接口即可輕鬆添加更多的組合器。

通過組合這些特定於數據類型的組件,用戶可以在各種任務上構建 Ludwig 訓練模型。例如,通過組合文本編碼器和類別編碼器,用戶可以獲得文本分類器;而組合圖像編碼器和文本解碼器則可獲得圖像字幕模型。

每種數據類型可以有多個編碼器和解碼器。例如,文本可以使用卷積神經網絡(CNN)、遞歸神經網絡(RNN)或其他編碼器進行編碼。然後,用戶可以直接在模型定義文件中指定要使用的參數及超參數,而無需編寫任何代碼。

這種靈活多樣的編碼器 - 解碼器架構使經驗不足的深度學習從業者能夠輕鬆地訓練各種機器學習任務的模型,例如文本分類、對象分類、圖像字幕、序列標記、迴歸、語言建模、機器翻譯、時間序列預測和問答系統等。這就開啓了各種用例,而這些用例對毫無經驗的從業者而言通常是遙不可及的,並且還允許在一個領域中有經驗的用戶去接觸新的領域。

目前,Ludwig 包含了二進制值、浮點數、類別、離散序列、集合、包、圖像、文本和時間序列的編碼器和解碼器,以及加載一些預訓練的模型(例如詞嵌入)的功能。Uber 還計劃在未來版本中繼續擴展支持的數據類型。

除了可用性和靈活的架構外,Ludwig 還爲非程序員提供了額外的好處。Ludwig 集成了一組用於訓練、測試模型和獲取預測的命令行實用程序。爲了進一步提高可用性,工具箱還提供了一套編程 API,用戶可以只需幾行代碼即可訓練和使用模型。

此外,它還包括一套其他工具,用戶評估模型,通過可視化來比較它們的性能和預測,並從中提取出模型權重和激活。

最後,通過使用開源分佈式訓練框架 Horovod,在多個 GPU 上以本地和分佈式的方式訓練模型,這一做法使得在模型上迭代和快速獲得結果成爲可能。

使用 Ludwig

爲了更好地理解如何將 Ludwig 用於現實世界的應用程序,讓我們用工具箱來構建一個簡單的模型。在這個例子中,我們創建了一個模型,根據書名、作者、描述和封面來預測某本圖書的類型和價格。

訓練模型

我們的圖書數據集如下表所示:

image

爲了學習一種模型,這個模型使用標題、作者、描述和封面欄的內容作爲輸入來預測圖書的類型和價格欄中的值,那麼模型定義 YAML 應該如下所示:

input_features:
 –
   name: title
   type: text
 –
   name: author
   type: category
 –
   name: description
   type: text
 –
   name: cover
   type: image
output_features:
 –
   name: genre
   type: category
 –
   name: price
   type: numerical
training:
 epochs: 10

我們在控制檯輸入以下命令開始訓練:

ludwig train –data_csv path/to/file.csv –model_definition_file model_definition.yaml

通過上面這條命令,Ludwig 在訓練、驗證和測試集中的數據進行隨機分割,對其進行預處理,併爲四個輸入構建四個不同的編碼器,爲兩個輸出目標構建一個組合器和兩個解碼器。然後,在訓練集上對模型進行訓練,直到驗證集的正確度不再提高或者達到最大的十個輪數。

訓練進度將會在控制檯中顯示,但也可以使用 TensorBoard 來顯示訓練進度。

默認情況下,文本特徵由 CNN 編碼器進行編碼,但我們可以使用 RNN 編碼器,使用狀態大小爲 200 的雙向 LSTM 來編碼標題。我們只需將標題編碼器定義更改爲如下所示:

name: title
type: text
encoder: rnn
cell_type: lstm
bidirectional: true

如果我們想要更改訓練參數,如輪數、學習率和批大小,我們會像這樣更改模型的定義,如下所示:

input_features:
 – …
output_features:
 – …
training:
 epochs: 100
 learning_rate: 0.001
 batch_size: 64

有關如何執行分割和數據預處理的所有參數,每個編碼器組合器和解碼器的參數都具有默認值,但它們是可配置的。用戶可以參閱這本指南:https://uber.github.io/ludwig/user_guide/,瞭解模型定義和訓練參數,並查看 Uber 的示例,以瞭解 Ludwig 如何應用於幾個不同的任務的。(https://uber.github.io/ludwig/examples/))

可視化訓練結果

訓練結束後,Ludwig 創建一個結果目錄,其中包含了訓練模型機器超參數和訓練過程的彙總統計信息。我們可以使用可視化工具提供的幾種可視化選項之一對它們進行可視化,例如:

ludwig visualize –visualization learning_curves –training_stats results/training_stats.json

這樣將顯示如下圖所示的圖形,顯示了作爲訓練輪數函數的損失和正確率:

image

圖2:這些學習曲線顯示了訓練輪數的損失和正確率。

還有幾種可視化的方法可以用。用戶指南中的可視化章節提供了更多的細節:https://uber.github.io/ludwig/user_guide/#visualizations

用已訓練的模型預測結果

如果用戶擁有新的數據,想用以前訓練過的模型來預測目標輸出值,可以鍵入如下命令:

ludwig predict –data_csv path/to/data.csv –model_path /path/to/model

如果數據集包含與預測進行比較的真相信息,運行這條命令將會返回模型預測以及一些測試性能的統計信息。這些可以通過可視化命令(如上所示)進行可視化,也可用於比較不同模型的性能和結果預測,例如:

ludwig visualize –visualization compare_performance –test_stats path/to/test_stats_model_1.json path/to/test_stats_model_2.json

將返回一個柱狀圖,比較不同指標下的模型:

image

圖3:這些柱狀圖比較了兩個模型的性能。

還有一條實驗命令,無需使用兩條單獨的命令就可以先進行訓練然後進行預測。

使用 Ludwig 的編程 API

Ludwig 還提供了一個簡單的 Python 編程 API,可以讓用戶訓練或加載模型並使用它來獲取對新數據的預測:

# train a model
model_definition = {…}
model = LudwigModel(model_definition)
train_stats = model.train(training_dataframe)
# or load a model
model = LudwigModel.load(model_path)

# obtain predictions
predictions = model.predict(test_dataframe)

model.close()

該 API 支持使用在現有代碼中使用 Ludwig 培訓的模型在其上構建應用程序。在用戶指南(https://uber.github.io/ludwig/user_guide/#programatic-api)和 API 文檔(https://uber.github.io/ludwig/api/)中提供了使用 Ludwig 編程 API 的更多細節。

結論

Uber 決定將 Ludwig 開源發佈,因爲 Uber 相信,Ludwig 對非專業的機器學習從業者和經驗豐富的深度學習開發人員及研究人員來說,都是一款有用的工具。藉由 Ludwig,非專家可以快速訓練和測試深度學習模型,而無需編寫一行代碼。通過執行標準的數據預處理和可視化,專家可以獲得強大的基線來比較他們的模型,並具有實驗設置,可以輕鬆測試新想法和分析模型。

在未來的版本中,Uber 希望爲每種數據類型添加幾個新的編碼器,例如用於文本的 Transformer、ELMo 和 BERT、用於圖像的 DenseNet 和 FractaNet。Uber 還希望添加其他數據類型,如音頻、點雲和圖形,同時集成更多可擴展的解決方案來管理大數據,如 Petastorm。

Uber 在開發 Ludwig 時考慮了可擴展性原則,爲促進社區的貢獻,Uber 還提供了開發人員指南:https://uber.github.io/ludwig/developer_guide/,這份指南表明了爲現有數據類型添加額外的數據類型以及其他編碼器、解碼器都是一件簡單的事。

原文鏈接:
https://eng.uber.com/introducing-ludwig/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章