Sdílet prostřednictvím


Ladění hyperparametrů (Preview)

Ladění hyperparametrů je proces hledání optimálních hodnot pro parametry, které model strojového učení během trénování sám nezíská, ale které nastavuje uživatel 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 mohou v Fabric využít FLAML, lehkou knihovnu Pythonu pro efektivní automatizaci operací strojového učení a AI pro požadavky na ladění hyperparametrů. V zápisnících Fabric můžou uživatelé použít flaml.tune pro úsporné ladění hyperparametrů.

Důležitý

Tato funkce je ve verzi Preview.

Pracovní postup ladění

Existují tři základní kroky k použití flaml.tune k dokončení základní úlohy ladění:

  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 určit svůj 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 určit platné hodnoty pro hyperparametry a způsob vzorkování těchto hodnot (např. z rovnoměrného rozdělení nebo logaritmického rovnoměrného rozdělení). 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 , ze kterého lze vzorkovat 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í doladění

Posledním krokem je určení omezení úlohy ladění. Jednou z hlavních vlastností flaml.tune je, že dokáže 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 skutečného času (v sekundách) pomocí argumentu time_budget_s nebo z hlediska počtu pokusů pomocí argumentu 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ávání najdete v dokumentaci FLAML pro pokročilé nastavení.

Dáváme to dohromady

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ého zalogová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 můžete při ladění učení s jedním uzlem (např. Scikit-Learn learnery) paralelizovat ladění, abyste urychlili proces ladění nastavením use_spark = True. Pro clustery Spark FLAML ve výchozím nastavení spustí jednu zkušební verzi na executoru. 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 nebo flaml.tune.tune.ExperimentAnalysis objekt.

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

  • plot_optimization_history: Vykreslí historii optimalizace všech pokusů v experimentu.
  • plot_feature_importance: Vykreslení důležitosti pro každou funkci v datové sadě
  • plot_parallel_coordinate: Vykreslujte v experimentu vztahy s vysoce dimenzionálními parametry.
  • plot_contour: Vykresli vztah parametru jako konturový graf v experimentu.
  • plot_edf: Vykreslete objektivní hodnotu EDF (empirickou distribuční funkci) experimentu.
  • plot_timeline: Vykreslí časovou osu experimentu.
  • plot_slice: Vykreslete vztah parametrů jako graf řezu ve studii.
  • plot_param_importance: Vykreslení důležitosti hyperparametrů experimentu