Hyperparameterjustering (förhandsgranskning)
Hyperparameterjustering är processen att hitta optimala värden för de parametrar som inte har lärts av maskininlärningsmodellen under träningen, utan snarare anges av användaren innan träningsprocessen börjar. Dessa parametrar kallas ofta för hyperparametrar, och exempel är inlärningsfrekvensen, antalet dolda lager i ett neuralt nätverk, regulariseringsstyrkan och batchstorleken.
Prestandan för en maskininlärningsmodell kan vara mycket känslig för valet av hyperparametrar, och den optimala uppsättningen hyperparametrar kan variera mycket beroende på det specifika problemet och datauppsättningen. Hyperparameterjustering är därför ett viktigt steg i maskininlärningspipelinen, eftersom det kan ha en betydande inverkan på modellens noggrannhet och generaliseringsprestanda.
I Fabric kan datavetare använda FLAML
, ett enkelt Python-bibliotek för effektiv automatisering av maskininlärnings- och AI-operationer, för att möta deras behov av hyperparameterjustering. I Fabric Notebooks kan användare anropa flaml.tune
för ekonomisk hyperparameterjustering.
Viktig
Den här funktionen finns i förhandsversion.
Justera arbetsflöde
Det finns tre viktiga steg för att använda flaml.tune
för att slutföra en grundläggande justeringsuppgift:
- Ange justeringsmålet med avseende på hyperparametrar.
- Ange ett sökutrymme för hyperparametrar.
- Ange justeringsbegränsningar, inklusive begränsningar för resursbudgeten för att göra justeringen, begränsningar för konfigurationerna eller/och begränsningar för ett (eller flera) specifika mått.
Justeringens mål
Det första steget är att ange justeringsmålet. För att göra detta bör du först ange utvärderingsproceduren för hyperparametrar i en användardefinierad funktion evaluation_function
. Funktionen kräver en hyperparameterkonfiguration som indata. Det kan helt enkelt returnera ett måttvärde i en skalär eller returnera en ordlista med måttnamn och måttvärdepar.
I exemplet nedan kan vi definiera en utvärderingsfunktion med avseende på 2 hyperparametrar med namnet x
och y
.
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"]}
Sökutrymme
Därefter anger vi sökutrymmet för hyperparametrar. I sökutrymmet måste du ange giltiga värden för dina hyperparametrar och hur dessa värden samplas (t.ex. från en enhetlig distribution eller en logguniform distribution). I exemplet nedan kan vi ange sökutrymmet för hyperparametrar x
och y
. Giltiga värden för båda är heltal från [1, 100 000]. Dessa hyperparametrar samplas jämnt i de angivna intervallen.
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, ...)
Med FLAML kan användarna anpassa domänen för en viss hyperparameter. Detta gör att användarna kan ange en typ och ett giltigt intervall att provta parametrar från. FLAML stöder följande hyperparametertyper: float, heltal och kategorisk. Du kan se det här exemplet nedan för vanliga domäner:
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"]),
}
Mer information om hur du kan anpassa domäner i sökutrymmet finns i FLAML-dokumentationen om hur du anpassar sökutrymmen.
Justeringsbegränsningar
Det sista steget är att ange begränsningar för justeringsaktiviteten. En viktig egenskap för flaml.tune
är att den kan slutföra justeringsprocessen inom en nödvändig resursbegränsning. För att göra detta kan en användare ange resursbegränsningar när det gäller tid på väggklockan (i sekunder) med argumentet time_budget_s
eller när det gäller antalet utvärderingar med argumentet num_samples
.
# 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, ...)
Om du vill veta mer om ytterligare konfigurationsbegränsningar kan du besöka FLAML-dokumentationen för avancerade justeringsalternativ.
Sätta ihop
När vi har definierat våra justeringsvillkor kan vi köra justeringsutvärderingen. För att spåra resultaten av vårt prov kan vi använda MLFlow automatisk loggning för att samla in mått och parametrar för var och en av dessa körningar. Den här koden samlar in hela utvärderingsversionen av hyperparameterjusteringen och markerar var och en av de hyperparameterkombinationer som utforskades av FLAML.
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
)
Not
När automatisk MLflow-loggning är aktiverat ska mått, parametrar och modeller loggas automatiskt när MLFlow körs. Detta varierar dock beroende på ramverket. Mått och parametrar för specifika modeller kanske inte loggas. Till exempel loggas inga mått för XGBoost-, LightGBM-, Spark- och SynapseML-modeller. Du kan lära dig mer om vilka mått och parametrar som samlas in från varje ramverk med hjälp av dokumentationen MLFlow-automatisk loggning.
Parallell optimering med Apache Spark
Funktionen flaml.tune
stöder konfigurering av både Apache Spark och single-node-algoritmer. När du justerar elever med en nod (t.ex. Scikit-Learn elever) kan du dessutom parallellisera justeringen för att påskynda justeringsprocessen genom att ange use_spark = True
. För Spark-kluster startar FLAML som standard en utvärderingsversion per köre. Du kan också anpassa antalet samtidiga utvärderingsversioner med hjälp av argumentet n_concurrent_trials
.
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
Om du vill veta mer om hur du parallelliserar dina justeringsspår kan du gå till FLAML-dokumentationen för parallella Spark-jobb.
Visualisera resultat
Modulen flaml.visualization
innehåller verktygsfunktioner för ritning av optimeringsprocessen med hjälp av Plotly. Genom att använda Plotly kan användarna interaktivt utforska sina AutoML-experimentresultat. Om du vill använda de här ritfunktionerna anger du helt enkelt dina optimerade flaml.AutoML
eller flaml.tune.tune.ExperimentAnalysis
objekt som indata.
Du kan använda följande funktioner i din anteckningsbok:
-
plot_optimization_history
: Rita optimeringshistorik för alla försök i experimentet. -
plot_feature_importance
: Rita prioritet för varje funktion i datauppsättningen. -
plot_parallel_coordinate
: Rita de högdimensionella parameterrelationerna i experimentet. -
plot_contour
: Rita parameterrelationen som konturdiagram i experimentet. -
plot_edf
: Rita upp det objektiva värdet EDF (empirisk fördelningsfunktion) för experimentet. -
plot_timeline
: Rita tidslinjen för experimentet. -
plot_slice
: Rita parameterrelationen som segmentdiagram i en studie. -
plot_param_importance
: Rita hyperparameterns betydelse för experimentet.