將 Hyperopt 超參數優化平行化

注意

不再維護 Hyperopt 的開放原始碼版本。

Hyperopt 在 16.4 LTS ML 之後不再包含在 Databricks 機器學習執行時中。 Azure Databricks 建議針對單一節點優化使用 Optuna,或 RayTune,以取得與已取代的 Hyperopt 分散式超參數微調功能類似的體驗。 深入瞭解如何在 Azure Databricks 上使用 RayTune。

本範例筆記本展示了如何利用 Hyperopt 搭配 SparkTrials,將單機超參數調整擴展到Azure Databricks叢集。 在 Iris 資料集上調校 scikit-learn SVM 分類器時,你先建立一個單機器 fmin() 工作流程,然後用 MLflow 自動追蹤每個試驗,將它平行化到各個 Spark 工作者之間。

匯入所需套件與載入資料集

from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC

from hyperopt import fmin, tpe, hp, SparkTrials, STATUS_OK, Trials

# If you are running Databricks Runtime for Machine Learning, `mlflow` is already installed and you can skip the following line.
import mlflow
# Load the iris dataset from scikit-learn
iris = iris = load_iris()
X = iris.data
y = iris.target

第一部分。 單機版 Hyperopt 工作流程

以下是Hyperopt工作流程的步驟:

  1. 定義一個最小化函數。
  2. 定義超參數的搜尋空間。
  3. 選擇搜尋演算法。
  4. 用 Hyperopt fmin()執行調校演算法。

欲了解更多資訊,請參閱 Hyperopt文件。

定義一個最小化的函數

在這個例子中,我們使用了支持向量機分類器。 目標是找到正則化參數 C的最佳值。

Hyperopt 工作流程的大部分程式碼都在目標函式中。 此範例使用 scikit-learn 的支援向量分類器。

如果你的叢集使用 Databricks Runtime 11.3 ML,請編輯支持向量分類器,取一個位置參數。 clf = SVC(C)

def objective(C):
    # Create a support vector classifier model
    clf = SVC(C=C)

    # Use the cross-validation accuracy to compare the models' performance
    accuracy = cross_val_score(clf, X, y).mean()

    # Hyperopt tries to minimize the objective function. A higher accuracy value means a better model, so you must return the negative accuracy.
    return {'loss': -accuracy, 'status': STATUS_OK}

定義超參數上的搜尋空間

請參閱 Hyperopt 文件 ,了解如何定義搜尋空間和參數表達式。

search_space = hp.lognormal('C', 0, 1.0)

選擇搜尋演算法

主要有兩個選擇:

  • hyperopt.tpe.suggest:Parzen 估計樹,一種貝葉斯方法,透過迭代與自適應選擇新的超參數設定,根據過去的結果進行探索
  • hyperopt.rand.suggest:隨機搜尋,一種非自適應方法,在搜尋空間中取樣
algo=tpe.suggest

用 Hyperopt 執行調校演算法 fmin()

設定 max_evals 為超參數空間中可測試的最大點數,也就是擬合與評估的最大模型數量。

argmin = fmin(
  fn=objective,
  space=search_space,
  algo=algo,
  max_evals=16)
# Print the best value found for C
print("Best value found: ", argmin)

第二部分。 使用 Apache Spark 與 MLflow 進行分散式調校

為了分配調整,向 fmin()再添加一個參數:Trials 中名為 SparkTrials 的類別。

SparkTrials 取兩個可選參數:

  • parallelism:需同時擬合與評估的模型數量。 預設值是可用的 Spark 任務欄位數量。
  • timeout:可運行的最大時間(秒數)。fmin() 預設是沒有最大時間限制。

此範例使用指令 7 中定義的非常簡單的目標函數。 在這種情況下,函式執行得很快,啟動 Spark 作業的開銷佔據了計算時間,因此分散式情境的計算會花更多時間。 對於典型的現實問題,目標函數更為複雜,使用 SparkTrails 來分配計算比單機調校更快。

自動 ML Flow 追蹤預設已啟用。 使用時,請先呼叫 mlflow.start_run() ,再呼叫 fmin() ,如範例所示。

from hyperopt import SparkTrials

# To display the API documentation for the SparkTrials class, uncomment the following line.
# help(SparkTrials)
spark_trials = SparkTrials()

with mlflow.start_run():
  argmin = fmin(
    fn=objective,
    space=search_space,
    algo=algo,
    max_evals=16,
    trials=spark_trials)
# Print the best value found for C
print("Best value found: ", argmin)

若要查看與筆記本相關的 MLflow 實驗,請點擊右上角筆記本上下文列中的 實驗 圖示。 在此,你可以查看所有執行紀錄。 要在 MLflow UI 中查看實驗,請點擊「 實驗運行」旁邊最右邊的圖示。

檢視調音 C的影響:

  1. 選擇結果的運行然後點選 比較。
  2. 在散佈圖中,X軸選擇 C,Y 軸選擇 損失 。

在筆記本中的最後一個儲存格中執行動作後,MLflow UI 應顯示:

Hyperopt MLflow 示範

範例筆記本

將 Hyperopt 超參數優化平行化

拿筆記本