Hyperparameter-Optimierung (Vorschau)
Bei der Hyperparameter-Optimierung geht es darum, die optimalen Werte für die Parameter zu finden, die nicht vom Machine-Learning-Modell während des Trainings erlernt werden, sondern vom Benutzer vor Beginn des Trainingsprozesses festgelegt werden. Diese Parameter werden gemeinhin als Hyperparameter bezeichnet. Beispiele hierfür sind die Lerngeschwindigkeit, die Anzahl der ausgeblendeten Ebenen in einem neuronalen Netzwerk, die Stärke der Regularisierung und die Batchgröße.
Die Leistung eines Machine-Learning-Modells kann sehr sensibel auf die Wahl der Hyperparameter reagieren, und der optimale Satz von Hyperparametern kann je nach Problem und DataSet stark variieren. Die Hyperparameter-Optimierung ist daher ein wichtiger Schritt in der Machine Learning-Pipeline, da sie signifikante Auswirkungen auf die Genauigkeit und Generalisierungsleistung des Modells haben kann.
In Fabric können wissenschaftliche Fachkräfte für Daten FLAML
eine einfache Python-Bibliothek für eine effiziente Automatisierung des maschinellen Lernens und von KI-Operationen für ihre Anforderungen der Hyperparameter-Optimierungs nutzen . Innerhalb von Fabric-Notebooks können Benutzer flaml.tune
für eine wirtschaftliche Hyperparameter-Optimierung aufrufen.
Wichtig
Dieses Feature befindet sich in der Vorschauphase.
Optimierung des Workflows
Es gibt drei wesentliche Schritte flaml.tune
zu nutzen, um eine grundlegende Optimierungs-Aufgabe zu beenden:
- Geben Sie das Ziel der Optimierung in Bezug auf die Hyperparameter an.
- Geben Sie einen Suchbereich für die Hyperparameter an.
- Geben Sie Einschränkungen für die Optimierung an, einschließlich Einschränkungen für das Ressourcenbudget für die Optimierung, Einschränkungen für die Konfigurationen oder/und Einschränkungen für eine (oder mehrere) bestimmte Metrik(en).
Ziel der Optimierung
Der erste Schritt besteht darin, Ihr Optimierungsziel anzugeben. Dazu sollten Sie zuerst das Auswertungsverfahren in Bezug auf die Hyperparameter in einer benutzerdefinierten Funktion evaluation_function
angeben. Für die Funktion ist eine Hyperparameter-Konfiguration als Eingabe erforderlich. Sie kann einfach einen Metrikwert in einem Skalar zurückgeben oder ein Schlüsselverzeichnis mit Metriknamen und Metrik-Wertpaaren zurückgeben.
Im folgenden Beispiel können wir eine Auswertungsfunktion in Bezug auf 2 Hyperparameter mit den Namen x
und y
festlegen.
import time
def evaluate_config(config: dict):
"""evaluate a hyperparameter configuration"""
score = (config["x"] - 85000) ** 2 - config["x"] / config["y"]
faked_evaluation_cost = config["x"] / 100000
time.sleep(faked_evaluation_cost)
# we can return a single float as a score on the input config:
# return score
# or, we can return a dictionary that maps metric name to metric value:
return {"score": score, "evaluation_cost": faked_evaluation_cost, "constraint_metric": config["x"] * config["y"]}
Suchbereich
Dann geben Sie einen Suchbereich für die Hyperparameter an. Im Suchbereich müssen Sie gültige Werte für Ihre Hyperparameter angeben und wie diese Werte erfasst werden (z.B. aus einer uniformen Verteilung oder einer Log-uniformen Verteilung). Im nachfolgenden Beispiel können wir den Suchbereich für die Hyperparameter x
und y
angeben. Die gültigen Werte für beide sind ganze Zahlen, die zwischen [1, 100.000] liegen. Diese Hyperparameter werden gleichmäßig in den angegebenen Bereichen abgefragt.
from flaml import tune
# construct a search space for the hyperparameters x and y.
config_search_space = {
"x": tune.lograndint(lower=1, upper=100000),
"y": tune.randint(lower=1, upper=100000)
}
# provide the search space to tune.run
tune.run(..., config=config_search_space, ...)
Mit FLAML können Benutzer die Domäne für einen bestimmten Hyperparameter anpassen. Auf diese Weise können Benutzer einen Typ und einen gültigen Bereich für Beispielparameter angeben. FLAML unterstützt die folgenden Hyperparameter-Typen: Float, Integer und Kategorisiert. Das Beispiel unten zeigt Ihnen häufig verwendete Domains:
config = {
# Sample a float uniformly between -5.0 and -1.0
"uniform": tune.uniform(-5, -1),
# Sample a float uniformly between 3.2 and 5.4,
# rounding to increments of 0.2
"quniform": tune.quniform(3.2, 5.4, 0.2),
# Sample a float uniformly between 0.0001 and 0.01, while
# sampling in log space
"loguniform": tune.loguniform(1e-4, 1e-2),
# Sample a float uniformly between 0.0001 and 0.1, while
# sampling in log space and rounding to increments of 0.00005
"qloguniform": tune.qloguniform(1e-4, 1e-1, 5e-5),
# Sample a random float from a normal distribution with
# mean=10 and sd=2
"randn": tune.randn(10, 2),
# Sample a random float from a normal distribution with
# mean=10 and sd=2, rounding to increments of 0.2
"qrandn": tune.qrandn(10, 2, 0.2),
# Sample a integer uniformly between -9 (inclusive) and 15 (exclusive)
"randint": tune.randint(-9, 15),
# Sample a random uniformly between -21 (inclusive) and 12 (inclusive (!))
# rounding to increments of 3 (includes 12)
"qrandint": tune.qrandint(-21, 12, 3),
# Sample a integer uniformly between 1 (inclusive) and 10 (exclusive),
# while sampling in log space
"lograndint": tune.lograndint(1, 10),
# Sample a integer uniformly between 2 (inclusive) and 10 (inclusive (!)),
# while sampling in log space and rounding to increments of 2
"qlograndint": tune.qlograndint(2, 10, 2),
# Sample an option uniformly from the specified choices
"choice": tune.choice(["a", "b", "c"]),
}
Um mehr darüber zu erfahren, wie Sie Domains innerhalb Ihres Suchbereichs anpassen können, besuchen Sie die FLAML-Dokumentation zur Anpassung von Suchbereichen.
Optimierungs-Beschränkungen
Der letzte Schritt besteht darin, Einschränkungen des Optimierungsvorgangs anzugeben. Eine wichtige Eigenschaft von flaml.tune
ist, dass es den Optimierungsprozess innerhalb einer erforderlichen Ressourceneinschränkung abschließen kann. Dazu kann ein Benutzer Ressourceneinschränkungen in Bezug auf die Pinnwand-Uhr (in Sekunden) mithilfe des time_budget_s
Arguments oder in Bezug auf die Anzahl der Testversionen mit dem num_samples
Argument bereitstellen.
# Set a resource constraint of 60 seconds wall-clock time for the tuning.
flaml.tune.run(..., time_budget_s=60, ...)
# Set a resource constraint of 100 trials for the tuning.
flaml.tune.run(..., num_samples=100, ...)
# Use at most 60 seconds and at most 100 trials for the tuning.
flaml.tune.run(..., time_budget_s=60, num_samples=100, ...)
Weitere Informationen zu zusätzlichen Konfigurationseinschränkungen finden Sie in der FLAML-Dokumentation für erweiterte Optimierungsoptionen.
Zusammenführung
Nachdem wir unsere Optimierungskriterien definiert haben, können wir die Tuning-Testversion ausführen. Um die Ergebnisse unserer Testversion nachzuverfolgen, können wir MLFlow autologging nutzen, um die Metriken und Parameter für jede dieser Ausführungen zu erfassen. Dieser Code erfasst die gesamte Testversion der Hyperparameter-Optimierung, wobei alle Hyperparameter-Kombinationen hervorgehoben werden, die von FLAML untersucht wurden.
import mlflow
mlflow.set_experiment("flaml_tune_experiment")
mlflow.autolog(exclusive=False)
with mlflow.start_run(nested=True, run_name="Child Run: "):
analysis = tune.run(
evaluate_config, # the function to evaluate a config
config=config_search_space, # the search space defined
metric="score",
mode="min", # the optimization mode, "min" or "max"
num_samples=-1, # the maximal number of configs to try, -1 means infinite
time_budget_s=10, # the time budget in seconds
)
Hinweis
Wenn die automatische Protokollierung von MLFlow aktiviert ist, dann sollten Metriken, Parameter und Modelle automatisch protokolliert werden, wenn MLFlow läuft. Dies variiert jedoch je nach Framework. Metriken und Parameter für bestimmte Modelle werden möglicherweise nicht protokolliert. Beispielsweise werden keine Metriken für XGBoost-, LightGBM-, Spark- und SynapseML-Modelle protokolliert. Sie können mehr darüber erfahren, welche Metriken und Parameter in den einzelnen Frameworks erfasst werden, indem Sie die Autoprotokollierungsdokumentation von MLFlow verwenden.
Parallele Optimierung mit Apache Spark
Die flaml.tune
Funktionalität unterstützt die Optimierung von Apache Spark und Single Node Learners. Darüber hinaus können Sie beim Optimieren von Single Node Learners (z. B. Scikit-Learn-Learners) auch die Optimierung parallelisieren, um Ihren Optimierungsprozess durch Festlegen von use_spark = True
zu beschleunigen. Bei Spark-Clustern startet FLAML standardmäßig einen Versuch pro Executor. Sie können auch die Anzahl der gleichzeitigen Testversionen mit dem Argument n_concurrent_trials
anpassen.
analysis = tune.run(
evaluate_config, # the function to evaluate a config
config=config_search_space, # the search space defined
metric="score",
mode="min", # the optimization mode, "min" or "max"
num_samples=-1, # the maximal number of configs to try, -1 means infinite
time_budget_s=10, # the time budget in seconds
use_spark=True,
)
print(analysis.best_trial.last_result) # the best trial's result
print(analysis.best_config) # the best config
Weitere Informationen zum Parallelisieren Ihrer Optimierungs-Testversionen finden Sie in der FLAML-Dokumentation für parallele Spark-Aufträge.
Visualisieren der Ergebnisse
Das flaml.visualization
Modul bietet Dienstprogramm-Funktionen zum Plotten des Optimierungsprozesses mit Plotly. Durch die Nutzung von Plotly können Benutzer ihre AutoML-Experimentergebnisse interaktiv untersuchen. Um diese Plotting-Funktionen zu verwenden, stellen Sie einfach Ihr optimiertes Objekt flaml.AutoML
oder flaml.tune.tune.ExperimentAnalysis
als Eingabe zur Verfügung.
Sie können die folgenden Funktionen innerhalb Ihres Notebooks verwenden:
plot_optimization_history
: Plot-Optimierungshistorie aller Testversionen im Experiment.plot_feature_importance
: Plot-Wichtigkeit für jedes Feature im DataSet.plot_parallel_coordinate
: Plot von hochdimensionalen Parameterbeziehungen im Experiment.plot_contour
: Plot der Parameterbeziehung als Profil-Plot im Experiment.plot_edf
: Plot des Zielwerts EDF (empirische Verteilungsfunktion) des Experiments.plot_timeline
: Plot der Zeitleiste des Experiments.plot_slice
: Plot der Parameterbeziehung als Segment-Plot in einer Studie.plot_param_importance
: Plot der Hyperparameter-Wichtigkeit des Experiments.