Sdílet prostřednictvím


Ladění hyperparametrů (Preview)

Ladění hyperparametrů je proces hledání optimálních hodnot pro parametry, které se během trénování nenaučí model strojového učení, ale místo toho, aby ho uživatel nastavil před zahájením trénovacího procesu. Tyto parametry se běžně označují jako hyperparametry a příklady zahrnují rychlost učení, počet skrytých vrstev v neurální síti, sílu regularizace a velikost dávky.

Výkon modelu strojového učení může být vysoce citlivý na výběr hyperparametrů a optimální sada hyperparametrů se může výrazně lišit v závislosti na konkrétním problému a datové sadě. Ladění hyperparametrů je proto kritickým krokem v kanálu strojového učení, protože může mít významný vliv na přesnost a generalizaci modelu.

Datoví vědci můžou v Prostředcích infrastruktury využít FLAMLzjednodušenou knihovnu Pythonu pro efektivní automatizaci operací strojového učení a umělé inteligence pro požadavky na ladění hyperparametrů. V poznámkových blocích Fabric můžou uživatelé volat flaml.tune úsporné ladění hyperparametrů.

Důležité

Tato funkce je ve verzi Preview.

Pracovní postup ladění

K dokončení základní úlohy ladění je potřeba použít flaml.tune tři základní kroky:

  1. Zadejte cíl ladění s ohledem na hyperparametry.
  2. Zadejte vyhledávací prostor hyperparametrů.
  3. Určete omezení ladění, včetně omezení rozpočtu zdrojů, aby bylo možné provést ladění, omezení konfigurací nebo omezení konkrétních metrik (nebo více).

Cíl ladění

Prvním krokem je určení cíle ladění. Chcete-li to provést, měli byste nejprve zadat postup vyhodnocení s ohledem na hyperparametry v uživatelem definované funkci evaluation_function. Funkce vyžaduje jako vstup konfiguraci hyperparametrů. Může jednoduše vrátit hodnotu metriky ve skaláru nebo vrátit slovník párů názvů metrik a hodnot metriky.

V následujícím příkladu můžeme definovat vyhodnocovací funkci s ohledem na 2 hyperparametry pojmenované x a 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"]}

Vyhledávací prostor

Dále určíme vyhledávací prostor hyperparametrů. Ve vyhledávacím prostoru je potřeba zadat platné hodnoty pro hyperparametry a způsob vzorkování těchto hodnot (např. z jednotné distribuce nebo rovnoměrného rozdělení protokolu). V následujícím příkladu můžeme zadat vyhledávací prostor pro hyperparametry x a y. Platné hodnoty pro oba jsou celá čísla od [1, 100 000]. Tyto hyperparametry se v zadaných oblastech vzorkují jednotně.

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, ...)

Pomocí FLAML můžou uživatelé přizpůsobit doménu pro konkrétní hyperparametr. To umožňuje uživatelům zadat typ a platný rozsah pro ukázkové parametry. FLAML podporuje následující typy hyperparametrů: float, integer a kategorical. Tento příklad najdete níže pro běžně používané domény:

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"]),
}

Další informace o tom, jak přizpůsobit domény v rámci vyhledávacího prostoru, najdete v dokumentaci FLAML k přizpůsobení prostorů hledání.

Omezení ladění

Posledním krokem je určení omezení úlohy ladění. Jednou z hlavních vlastností flaml.tune je, že je schopna dokončit proces ladění v rámci požadovaného omezení prostředků. K tomu může uživatel poskytnout omezení prostředků z hlediska času na zdi (v sekundách) pomocí argumentu time_budget_s nebo z hlediska počtu pokusů, které argument používají 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, ...)

Další informace o omezeních konfigurace přidání najdete v dokumentaci FLAML pro pokročilé možnosti ladění.

Seskupování

Jakmile definujeme kritéria ladění, můžeme spustit zkušební verzi ladění. Abychom mohli sledovat výsledky naší zkušební verze, můžeme využít automatické protokolování MLFlow k zachycení metrik a parametrů pro každé z těchto spuštění. Tento kód zachytí celou zkušební verzi ladění hyperparametrů a zvýrazní všechny kombinace hyperparametrů, které byly prozkoumány flamlem.

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
    )

Poznámka:

Pokud je povolené automatické protokolování MLflow, metriky, parametry a modely by se měly protokolovat automaticky při spuštění MLFlow. To se ale liší podle architektury. Metriky a parametry pro konkrétní modely se nemusí protokolovat. Například pro modely XGBoost , LightGBM , Spark a SynapseML se nebudou protokolovat žádné metriky. Další informace o tom, jaké metriky a parametry se zaznamenávají z každé architektury, najdete v dokumentaci k automatickému protokolování MLFlow.

Paralelní ladění pomocí Apache Sparku

Funkce flaml.tune podporuje ladění Apache Sparku i learnerů s jedním uzlem. Kromě toho při ladění learnerů s jedním uzlem (např. Scikit-Learn learnerů) můžete také paralelizovat ladění, abyste urychlili proces ladění nastavením use_spark = True. Pro clustery Spark ve výchozím nastavení flaml spustí jednu zkušební verzi na exekutor. Počet souběžných pokusů můžete také přizpůsobit pomocí argumentu 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

Další informace o paralelizaci tras ladění najdete v dokumentaci FLAML pro paralelní úlohy Sparku.

Vizualizace výsledků

Modul flaml.visualization poskytuje pomocné funkce pro vykreslení procesu optimalizace pomocí Plotly. Díky využití Plotly můžou uživatelé interaktivně zkoumat výsledky experimentu AutoML. Pokud chcete tyto vykreslovací funkce použít, jednoduše jako vstup zadejte optimalizovaný flaml.AutoML objekt nebo flaml.tune.tune.ExperimentAnalysis objekt.

V poznámkovém bloku můžete použít následující funkce:

  • plot_optimization_history: Vykreslení historie optimalizace všech pokusů v experimentu
  • plot_feature_importance: Vykreslení důležitosti pro každou funkci v datové sadě
  • plot_parallel_coordinate: Vykreslíte ve experimentu relace s vysoce dimenzionálními parametry.
  • plot_contour: Vykreslení relace parametru jako obrysového grafu v experimentu
  • plot_edf: Vykreslení objektivní hodnoty EDF (empirická distribuční funkce) experimentu
  • plot_timeline: Vykreslí časovou osu experimentu.
  • plot_slice: Vykreslení relace parametru jako výsečového grafu ve studii
  • plot_param_importance: Vykreslení důležitosti hyperparametrů experimentu