機器學習項目配置太複雜怎麼辦?Facebook 開發了 Hydra 來幫你

  • 2020 年 2 月 21 日
  • 筆記

編譯 | skura

本文作者是 Omry Yadan,他是 Facebook 人工智慧軟體工程師,創建了 Hydra。

Hydra 是最近發布的一個開源 Python 框架,由 Facebook AI 開發,能夠簡化科研和其他複雜應用程式的開發。這個新框架功能強大,可以從命令行和配置文件中組合和重寫配置。作為 PyTorch 生態系統的一部分,Hydra 幫助 PyTorch 的研究人員和開發人員更容易地管理複雜的機器學習項目。Hydra 是通用的,可以應用於機器學習以外的領域。

這篇文章分為兩部分,第一部分描述開發機器學習軟體時出現的常見問題,第二部分主要是 Hydra 如何解決這些問題。

Part 1 . 你的程式碼比你想像的更加複雜

命令行是每個軟體開發人員最先了解的知識之一。命令行的核心是一個字元串列表,這些字元串通常被分解為標誌(例如,-verbose)和參數(例如,-port=80)。這對於許多簡單的應用程式來說已經足夠了,你可能只需要在命令行介面(CLI)解析庫中定義 2 到 3 個命令行參數就足夠了。

當人們開始使用你的應用程式時,他們將不可避免地發現缺少的功能。很快,你將添加更多功能,導致更多的命令行標誌。這在機器學習中尤其常見。

上面的圖片來自 PyTorch ImageNet 訓練示例。儘管是一個很小的例子,但是命令行標誌的數量已經很高了。其中一些標誌在邏輯上描述了相同的組件,它們在理想情況下應該被分成一組(例如,與分散式訓練相關的標誌),但是沒有一種簡單的方法可以將這些標誌分組並使用。

在此示例的基礎上,你可能希望添加新功能,支援需要附加命令行標誌的新模型、數據集或優化器。你可以想像在這個例子,隨著你的擴展支援新的想法是如何做到的。

這種樣式的另一個微妙問題是,所有東西都需要解析的 args 對象。這會鼓勵耦合,並使單個組件更難在不同的項目中重用。

配置文件

一個常見的解決方案是切換到配置文件。配置文件可以是分層的,並且可以幫助減少定義命令行參數的程式碼的複雜性。不幸的是,配置文件中也會面臨挑戰,你將在下一節中看到。

配置文件很難更改

在嘗試時,你需要使用不同的配置選項運行應用程式。起初,你可能只是在每次運行之前更改配置文件,但你很快就會意識到跟蹤與每次運行相關聯的更改是非常困難的。

試圖解決該問題的方法可能是複製配置文件,在實驗後命名,並對新文件進行更改。這種方法也不是很完美,因為它創建了一個很長的配置文件進行跟蹤,這個文件將很快就不能與程式碼同步,變得毫無用處。此外,通過查看實驗配置文件很難判斷你要做什麼,因為它與其他配置文件 99% 相同。

最後,對於經常更改的內容,你可能會返回到命令行標誌,以允許從命令行更改它們。這是乏味的,並且會讓命令行程式碼再次變得複雜。理想情況下,你可以從命令行重寫配置中的所有內容,而不必為每種情況單獨編寫程式碼。

配置文件變得單一

當開發人員編寫程式碼時,他們喜歡將事情分解成很小的部分(模組、函數)。這可以幫助他們保存程式碼模型,並使程式碼更易於維護。它還支援函數重用——調用一個函數比複製它容易。

配置文件不提供類似的功能。如果希望應用程式使用不同的配置選項,例如一個用於 ImageNet 數據集,一個用於 CIFAR-10 數據集,則有兩個選擇:

  1. 維護兩個配置文件
  2. 將這兩個選項放在一個配置文件中,並在運行時以某種方式使用所需的內容

第一種方法似乎很好,但後面你會意識到,隨著你增加更多的選項,事情很快就會崩潰。例如,除了兩個數據集選擇之外,你可能還想嘗試三種不同的模型體系結構(AlexNet、ResNet50 和一些新的、令人興奮的、你稱之為 BestNet 的東西)。你還可以在兩個損失函數之間進行選擇。這使組合總數達到 12 個!你確實希望避免維護 12 個類似的配置文件。

第二種方法最初的效果更好。你只需得到一個大的配置文件,該文件知道所選的兩個數據集、三個體系結構和兩個損失函數。但是,等等,當你在 AlexNet 和 ResNet50 上進行訓練時,你的學習速率需要有所不同,而且你需要在單個配置文件中表達出來。

這種複雜性也會泄漏到程式碼中,現在需要找出在運行時使用的學習速率!在設計、運行和調試實驗時,大部分未使用的大型配置會產生顯著的認知負載。由於 90% 的配置未使用,很難判斷每次運行最重要 10% 在哪裡。

通過添加從命令行重寫配置中所有內容的功能來組合配置,可以為這些問題提供一個強大的解決方案。由於這個原因,許多日益複雜的項目最終到達了開發 Hydra 所提供的功能子集的必要位置。這種功能往往與單個項目的需求緊密結合,因此很難重用,迫使開發人員不斷地在每個新項目中重新發明輪子。

不幸的是,在許多開發人員意識到這一點的時候,他們已經有了一個複雜且不靈活的程式碼庫,具有高耦合、硬編碼的配置。理想情況下,你希望像編寫程式碼一樣編寫配置。這使你可以擴大項目的複雜性。

Part 2 . 像使用 Hydra 編寫程式碼一樣編寫配置

如果你走到了這一步,你一定會想,對於我在第 1 部分中描述的那些軟體工程的問題,有什麼神奇的解決方案?你可能會猜到它就是 Hydra。

Hydra 是 Facebook AI Research 開發的一個開源 Python 框架,它通過允許你組合傳遞給應用程式的配置來解決很多問題,包括第 1 部分中概述的問題。合成可以通過配置文件或命令行進行,合成配置中的所有內容也可以通過命令行重寫。

基本示例

下面示例的源程式碼在這裡可以找到:https://github.com/omry/hydra-article-code。

假設你的數據集的配置如下:

config.yaml

以下是載入此配置的簡單 Hydra 應用程式:

my_app.py

這裡最有趣的一行是 @hydra.main()修飾器。它採用一個 config_ 路徑,提到了上面的 config.yaml 文件。

程式很好地列印了它得到的配置對象。毫無疑問,config 對象包含 ImageNet 數據集配置:

my_app 的常規輸出

我們現在可以從命令行重寫此配置文件中的任何內容:

重寫 dataset.path 時的輸出

構成示例

有時,你可能希望在兩個不同的數據集之間進行替換,每個數據集都有自己的配置。要支援此功能,請為數據集引入一個配置組,並在其中放置單個配置文件,每個選項一個:

你還可以在 config.yaml 中添加「defaults」部分,告訴 Hydra 如何編寫配置。在這種情況下,我們只想默認載入 cifar10 的配置,因為在它上面訓練更快:

config.yaml

這個應用看起來幾乎相同,唯一的區別是配置路徑現在指向 conf/config.yaml。運行應用程式時,會載入預期的 cifar10 配置:

但我們也可以很容易地選擇使用 imagenet:

你可以擁有多個配置組,讓我們在優化器中添加一個:

默認情況下,還可以更新 config.yaml 以載入 adam:

config.yaml

運行應用程式時,我們會得到一個包含 cifar10 和 adam 的聯合配置:

這裡還有很多可以談的,但現在,讓我們轉到下一個激動人心的特性。

Multirun

Multirun 是 Hydra 的一種功能,它可以多次運行你的函數,每次都組成一個不同的配置對象。這是一個自然的擴展,可以輕鬆地組合複雜的配置,並且非常方便地進行參數掃描,而無需編寫冗長的腳本。

例如,我們可以掃描所有 4 個組合(2 個數據集 X 2 個優化器):

基本的內置啟動程式是串列運行,但是其他啟動程式插件可以並行運行程式碼,甚至遠程運行程式碼。這些插件還沒有公開,但在社區的幫助下,我希望很快能看到它們。

自動工作目錄

如果仔細觀察上面的輸出,你會注意到 sweep 輸出目錄是根據我運行命令的時間生成的。人們在做研究時經常遇到的一個問題是如何保存輸出。典型的解決方案是傳入一個指定輸出目錄的命令行標誌,但這很快會變得乏味。當你希望同時運行多項任務,並且必須為每個任務傳遞不同的輸出目錄時,這尤其令人惱火。

Hydra 通過為每次運行生成輸出目錄並在運行程式碼之前更改當前工作目錄來解決此問題。使用 –multirun 執行掃描時,會為每個任務生成一個附加子目錄。

這樣可以很好地將來自同一 sweep 的任務分組在一起,同時保持每個任務與其他任務的輸出分離。

你仍然可以通過 Hydra 中的 API 訪問原始工作目錄。

original_cwd

從 /home/omry/dev/hydra 運行時的輸出:

生成的工作目錄可以完全自定義,這包括讓它作為路徑的一部分,包含命令行參數或配置中的任何其他內容。

寫在最後

本文中包含的只是 Hydra 提供的特性之一。其他功能包括動態選項卡完成、Python 日誌記錄子系統的自動配置、庫和應用程式打包配置支援等等。

在 Facebook AI 中,我們使用 Hydra 從命令行直接向內部集群發送程式碼。在社區的幫助下,我希望 Hydra 能夠成長為支援 AWS 和 GCP,並為 Facebook AI 之外的研究人員提供類似的功能。另一個感興趣的領域是命令行驅動的超參數優化。第一個這樣的插件,Ax 正在開發中。

Hydra 是新的,我們剛剛開始了解它是如何改變事物的。

我期待著看到社區在未來幾年如何使用 Hydra。

要了解有關 Hydra 的更多資訊,請參閱 Hydra 網站上的教程和文檔:https://hydra.cc/ 。

via:https://medium.com/pytorch/hydra-a-fresh-look-at-configuration-for-machine-learning-projects-50583186b710