Hyperopt ハイパーパラメーターのチューニングを並列化する

注記

Hyperopt のオープンソース バージョンはメンテナンスされなくなりました。

Hyperopt は、16.4 LTS ML 以降の Databricks Runtime for Machine Learning には含まれません。 Azure Databricks では、単一ノードの最適化に Optuna を、非推奨の Hyperopt 分散ハイパーパラメーター チューニング機能と同様のエクスペリエンスには RayTune を使用することを推奨しています。 Azure Databricks での RayTune の使用の詳細については、こちらをご覧ください。

このノートブックの例では、hyperopt と SparkTrials を使用して、単一コンピューターのハイパーパラメーター調整をAzure Databricks クラスターにスケーリングする方法を示します。 Iris データセットで scikit-learn SVM 分類子をチューニングするには、最初に単一コンピューターの fmin() ワークフローを構築してから、MLflow を使用して Spark worker 間で並列化し、すべての試用版を自動的に追跡します。

必要なパッケージをインポートしてデータセットを読み込む

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

第 1 部 単一マシン ハイパーオプト ワークフロー

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)

検索アルゴリズムを選択する

2 つの主な選択肢は次のとおりです。

  • hyperopt.tpe.suggest: 過去の結果に基づいて探索する新しいハイパーパラメーター設定を反復的かつ適応的に選択するベイジアンアプローチ、パルゼン推定器のツリー
  • 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)

第 2 部 Apache Spark と MLflow を使用した分散チューニング

チューニングを分散するには、fmin()にもう 1 つの引数 (Trials と呼ばれるSparkTrials クラス) を追加します。

SparkTrials は 2 つの省略可能な引数を受け取ります。

  • parallelism: 同時に適合および評価するモデルの数。 既定値は、使用可能な Spark タスク スロットの数です。
  • timeout: fmin() が実行できる最大時間 (秒単位)。 既定値は最大時間制限なしです。

この例では、Cmd 7 で定義されている非常に単純な目的関数を使用します。 この場合、関数はすぐに実行され、Spark ジョブを開始するオーバーヘッドが計算時間を支配するため、分散ケースの計算に時間がかかります。 一般的な実際の問題では、目的関数はより複雑であり、 SparkTrails を使用して計算を分散することは、単一マシンのチューニングよりも高速です。

自動 MLflow 追跡は既定で有効になっています。 これを使用するには、例に示すように、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 ハイパーパラメーターのチューニングを並列化する

ノートブックを入手