Dela via


Hyperparameterjustering (förhandsversion)

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 Infrastruktur kan dataexperter använda FLAML, ett enkelt Python-bibliotek för effektiv automatisering av maskininlärnings- och AI-åtgärder, för deras krav på hyperparameterjustering. I Notebook-filer för Infrastruktur kan användarna anropa flaml.tune ekonomisk hyperparameterjustering.

Viktigt!

Den här funktionen är i förhandsversion.

Justera arbetsflöde

Det finns tre viktiga steg att använda flaml.tune för att slutföra en grundläggande justeringsuppgift:

  1. Ange justeringsmålet med avseende på hyperparametrar.
  2. Ange ett sökutrymme för hyperparametrar.
  3. 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.

Justeringsmå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. På så sätt kan användarna ange en typ och ett giltigt intervall för exempelparametrar 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 flaml.tune för ä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ärderingsversioner 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, ...)

Mer information om ytterligare konfigurationsbegränsningar finns i FLAML-dokumentationen för avancerade justeringsalternativ.

Sätta ihop den

När vi har definierat våra justeringsvillkor kan vi köra justeringsutvärderingen. För att spåra resultatet av utvärderingsversionen kan vi använda automatisk MLFlow-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
    )

Kommentar

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 för automatisk loggning av MLFlow.

Parallell justering med Apache Spark

Funktionen flaml.tune stöder justering av både Apache Spark- och single-node-elever. 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 n_concurrent_trials av argumentet .


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 besöka FLAML-dokumentationen för parallella Spark-jobb.

Visualisera resultat

Modulen flaml.visualization innehåller verktygsfunktioner för att rita 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 ditt optimerade flaml.AutoML objekt eller flaml.tune.tune.ExperimentAnalysis objekt som indata.

Du kan använda följande funktioner i notebook-filen:

  • 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 experimentets målvärde EDF (empirisk fördelningsfunktion).
  • 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.