次の方法で共有


Hyperopt の概念

この記事では、分散型の Hyperopt を使用するために知っておく必要のあるいくつかの概念について説明します。

このセクションの内容は次のとおりです。

Azure Databricks での Hyperopt の使用方法を示す例については、「Hyperopt を使用したハイパーパラメーターの調整」を参照してください。

fmin()

Hyperopt を実行するには fmin() を使用します。 fmin() の引数は、次の表に示しています。詳細については、Hyperopt のドキュメントを参照してください。 各引数を使用する方法の例については、ノートブックの例を参照してください。

引数名 説明
fn 目的関数。 Hyperopt では、space 引数で指定されたハイパーパラメーター空間から生成された値を使用して、この関数を呼び出します。 この関数は、損失をスカラー値または辞書で返すことができます (詳細については、Hyperopt のドキュメントを参照)。 この関数には、通常、モデルのトレーニングと損失計算のためのコードが含まれています。
space 検索するハイパーパラメーター空間を定義します。 Hyperopt では、非常に柔軟な方法でこの領域を定義できます。 アルゴリズムのような、カテゴリに関するオプションや、uniform や log のような、数値用の確率分布を選択できます。
algo ハイパーパラメーター空間の検索に使用する Hyperopt 検索アルゴリズム。 最も一般的に使用されるのは、ランダム検索には hyperopt.rand.suggest で、TPE には hyperopt.tpe.suggest です。
max_evals 試行するハイパーパラメーター設定の数 (適合するモデルの数)。
max_queue_len Hyperopt で事前に生成する必要のあるハイパーパラメーター設定の数。 Hyperopt の TPE 生成アルゴリズムでは一定の時間が必要な場合があるため、これを既定値の 1 よりも大きくすると有益ですが、通常は SparkTrials 設定の parallelism よりも大きくはしません。
trials Trials または SparkTrials オブジェクト。 SparkTrials は、目的関数で scikit-learn メソッドなどの単一マシン アルゴリズムを呼び出すときに使用します。 Trials は、目的関数で MLlib メソッドや Horovod などの分散トレーニング アルゴリズムを呼び出すときに使用します。
early_stop_fn max_evals に到達する前に fmin を停止する必要があるかどうかを判定するための、省略可能な早期停止関数。 既定値は None です。 関数の入力署名は Trials, *args で、出力署名は bool, *args です。 出力のブール値は、停止すべきかどうかを示します。 *args は任意の状態であり、early_stop_fn に対する呼び出しの出力が、次の呼び出しへの入力として機能します。 TrialsSparkTrials オブジェクトである場合があります。 SparkTrials の使用時には、早期停止関数は、すべての試行後に実行されることが保証されず、代わりにポーリングされます。 早期停止関数の例

SparkTrials クラスは

SparkTrials は、Hyperopt コードに他の変更を加えることなく Hyperopt 実行を配布することができる、Databricks によって開発された API です。 SparkTrials によって試用を Spark worker に配布することで、単一マシンのチューニングを高速化します。

注意

SparkTrials は、scikit-learn などの単一マシン ML モデルの計算を並列化するように設計されています。 MLlib や Horovod などの分散 ML アルゴリズムで作成されたモデルについては、SparkTrials を使用しないでください。 この場合、モデルの構築プロセスはクラスターで自動的に並列化されるので、既定の Hyperopt クラス Trials を使用する必要があります。

このセクションでは、SparkTrials に渡す引数を構成する方法と、SparkTrials の実装の側面について説明します。

引数

SparkTrials で受け取るのは 2 つの省略可能な引数です。

  • parallelism: 同時に評価する試行の最大数。 より大きな数値を指定すると、より多くのハイパーパラメーター設定のテストをスケールアウトできます。 Hyperopt では、過去の結果に基づいて新しい試行が提案されるため、並列処理と適応性の間にはトレードオフの関係があります。 max_evals が固定の場合、並列処理数を増やすと計算速度は上がりますが、反復のたびに過去の結果により多くアクセスできるため、並列処理数を減らすと良い結果につながる可能性があります。

    既定値: 使用可能な Spark Executor の数。 最大: 128。 並列処理数のこの値は、クラスター構成によって許可されている同時実行タスクの数よりも大きい場合、SparkTrials によって、その値まで減らされます。

  • timeout: fmin() 呼び出しで取ることができる最大秒数。 この数値を超過すると、すべての実行が終了され、fmin() が終了します。 完了した実行に関する情報は保存されます。

実装

fmin() に渡される目的関数 fn を定義するときや、クラスター設定を選択するときには、SparkTrials によってチューニング タスクがどのように分散されるかを理解しておくと助けになります。

Hyperopt では、1 回の試行は一般に、1 つのモデルをハイパーパラメーターの 1 つの設定に適合させることに対応しています。 Hyperopt では、試行が反復的に生成され、評価され、繰り返されます。

SparkTrials では、クラスターのドライバー ノードによって新しい試行が生成され、それらの試行はワーカー ノードによって評価されます。 各試行は、1 つのタスクを持つ Spark ジョブで生成され、worker マシン上のタスク内で評価されます。 お使いのクラスターが、複数のタスクを worker 単位で実行するように設定されている場合、その worker では複数の試行が一度に評価される可能性があります。

SparkTrials および MLflow

Databricks Runtime ML では、worker から MLflow へのログ記録がサポートされています。 Hyperopt に渡す目的関数にカスタムのログ記録用コードを追加できます。

SparkTrials では、チューニングの結果を、入れ子になった MLflow の実行として、以下のようにログに記録します。

  • メインまたは親の実行: fmin() の呼び出しは、メインの実行としてログに記録されます。 アクティブな実行がある場合、SparkTrials ではこのアクティブな実行に対してログを記録し、fmin() が返るときに実行を終了しません。 アクティブな実行がない場合、SparkTrials では新しい実行が作成され、それに対してログが記録されて、fmin() が返る前に実行が終了されます。
  • 子の実行: テストされた各ハイパーパラメーター設定 (1 回の "試行") は、メインの実行の下に、子の実行としてログ記録されます。 worker からの MLflow ログ レコードも、対応する子の実行の下に格納されます。

Databricks では、fmin() の呼び出し時に、アクティブな MLflow 実行を管理することが推奨されています。つまり、fmin() の呼び出しを with mlflow.start_run(): ステートメント内にラップします。 これで、それぞれの fmin() 呼び出しが別個の MLflow メイン実行にログ記録されるようになり、その実行に追加のタグ、パラメーター、メトリックをログ記録することが容易になります。

注意

同一のアクティブな MLflow 実行内で複数回 fmin() を呼び出すと、それらの呼び出しは、MLflow により、同じメイン実行にログ記録されます。 ログに記録されるパラメーターやタグの名前の競合を解決するため、競合がある名前には、MLflow によって UUID が追加されます。

worker からのログ記録を行う場合、目的関数内で実行を明示的に管理する必要はありません。 目標関数内で mlflow.log_param("param_from_worker", x) を呼び出して、パラメーターを子の実行にログ記録します。 目的関数では、パラメーター、メトリック、タグ、アーティファクトをログ記録できます。