Best practices: Hyperparameter tuning with Hyperopt | Databricks on AWS [2021/6/11時点]の翻訳です。
注意
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
ベストプラクティス
- ベイジアンアプローチが、グリッドサーチやランダムサーチよりもはるかに効率的な場合があります。このため、HyperoptのTree of Parzen Estimators(TPE)アルゴリズムを用いることで、より多くのハイパーパラメーターやより広い範囲を探索することができます。検索ドメインを制限するためにドメイン知識を用いることで、チューニングを最適化し、より良い結果を得ることができます。
-
hp.choice()
を使う際には、Hyperoptは選択リストのインデックスを返却します。このため、MLflowに記録されるパラメーターもインデックスとなります。パラメーターの値を取得するには、hyperopt.space_eval()
を使用してください。 - トレーニング時間が長いモデルに対しては、小規模なデータセットと大量のハイパーパラメーターを用いて実験を開始してください。ベストのパフォーマンスを示すモデルと、どのハイパーパラメーターを固定できるのかを特定するためにMLflowを活用してください。このようにして、大規模データでチューニングができるように、パラメーターの空間を削減することができます。
- Hyperoptの条件付き次元、ハイパーパラメーターのサポートを活用してください。例えば、ハイパーパラメーター空間を単に一般的なハイパーパラメーターに限定するのではなく、複数のフレーバーの最急降下法を評価しているのであれば、Hyperoptに、フレーバーのサブセットにのみ適用される条件付きハイパーパラメーターを含めることができます。条件付きパラメーターの詳細に関しては、Defining a search spaceを参照ください。
-
SparkTrials
を使っている際には、CPUクラスター、GPUクラスターそれぞれに適した並列度の設定を行ってください。Databricksにおいて、CPUクラスターとGPUクラスターは、ワーカーノードあたりのエグゼキューターのスレッドの数が異なります。CPUクラスターはノードあたり複数のエグゼキュータースレッドを使用します。GPUクラスターでは、同じGPUを利用しようとする複数のSparkタスクの競合を避けるために、ノードあたり1つのみのエグゼキュータースレッドを使用します。これは、GPU向けに開発されたライブラリにおいては通常最適なものとなりますが、GPUクラスターにおいては最大の並列性が削減されていることを意味し、GPUインスタンスタイプを選択した際には、それぞれのトライアルで使用するGPU数に注意する必要があります。詳細はGPU-enabled Clustersをご覧ください。 - オートスケーリングが有効化されたクラスターで
SparkTrials
を使用しないでください。Hyperoptは処理が開始した時点で並列度を選択します。あとでクラスターがオートスケールしても、Hyperoptは新たなクラスターサイズを活用することができません。
トラブルシューティング
- lossがNaN(not a number)となる場合、多くの場合
fmin()
に渡された目的関数がNaNを返却したことを意味します。これは他のランに影響せず、問題なく無視することができます。この結果を回避するためには、ハイパーパラメーター空間を調整するか、目的関数を変更してください。 - Hyperoptは確率論的検索アルゴリズムを使用するので、それぞれのランでlossは単調減少しません。しかし、これらの方法は多くのケースで他の方用よりも迅速に最適なはイパーパラメーターを検知します。
- 短期間のトライアル実行において、Hyperopt、Sparkの両方でトライアル期間の大勢を占めるオーバーヘッド(数十秒)が生じます。観測できる速度改善の幅は小さく、場合によってはゼロとなります。
SparkTrials: サイズの異なるデータセットに対するベストプラクティス
SparkTrials
はトライアルをSparkワーカーノードで実行します。このノートブックでは、SparkTrials
を使用する際に異なる規模のデータセットをどのようにワーカーノードに移動すべきかを説明しています。
異なる規模のデータを取り扱うサンプルノートブック