Udostępnij za pośrednictwem


Dostrajanie hiperparametrów (wersja zapoznawcza)

Dostrajanie hiperparametryczne to proces znajdowania optymalnych wartości parametrów, które nie są poznane przez model uczenia maszynowego podczas trenowania, ale raczej ustawiane przez użytkownika przed rozpoczęciem procesu trenowania. Te parametry są często określane jako hiperparametry, a przykłady obejmują szybkość uczenia, liczbę ukrytych warstw w sieci neuronowej, siłę uregulowania i rozmiar partii.

Wydajność modelu uczenia maszynowego może być bardzo wrażliwa na wybór hiperparametrów, a optymalny zestaw hiperparametrów może się znacznie różnić w zależności od konkretnego problemu i zestawu danych. Dostrajanie hiperparametryczne jest zatem krytycznym krokiem w potoku uczenia maszynowego, ponieważ może mieć znaczący wpływ na dokładność i uogólnianie modelu.

W sieci szkieletowej analitycy danych mogą korzystać z FLAMLuproszczonej biblioteki języka Python w celu wydajnej automatyzacji operacji uczenia maszynowego i sztucznej inteligencji, aby spełnić wymagania dotyczące dostrajania hiperparametrów. W notesach sieci szkieletowej użytkownicy mogą wywoływać flaml.tune ekonomiczne dostrajanie hiperparametrów.

Ważne

Ta funkcja jest dostępna w wersji zapoznawczej.

Dostrajanie przepływu pracy

Aby ukończyć podstawowe zadanie dostrajania, należy wykonać flaml.tune trzy podstawowe kroki:

  1. Określ cel dostrajania w odniesieniu do hiperparametrów.
  2. Określ przestrzeń wyszukiwania hiperparametrów.
  3. Określ ograniczenia dostrajania, w tym ograniczenia dotyczące budżetu zasobów, aby wykonać dostrajanie, ograniczenia konfiguracji lub/i ograniczenia dotyczące określonej metryki (lub wielu).

Cel dostrajania

Pierwszym krokiem jest określenie celu dostrajania. W tym celu należy najpierw określić procedurę oceny w odniesieniu do hiperparametrów w funkcji evaluation_functionzdefiniowanej przez użytkownika. Funkcja wymaga konfiguracji hiperparametru jako danych wejściowych. Może ona po prostu zwrócić wartość metryki w skalarnym lub zwrócić słownik par nazwy metryki i wartości metryki.

W poniższym przykładzie możemy zdefiniować funkcję ewaluacyjną w odniesieniu do 2 hiperparametrów o nazwach x i 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"]}

Miejsce wyszukiwania

Następnie określimy przestrzeń wyszukiwania hiperparametrów. W obszarze wyszukiwania należy określić prawidłowe wartości dla hiperparametrów i sposób próbkowania tych wartości (np. z równomiernego rozkładu lub równomiernego rozkładu dziennika). W poniższym przykładzie możemy podać miejsce wyszukiwania hiperparametrów x i y. Prawidłowe wartości dla obu są liczbami całkowitymi od [1, 100 000]. Te hiperparametry są próbkowane równomiernie w określonych zakresach.

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

Za pomocą języka FLAML użytkownicy mogą dostosować domenę dla określonego hiperparametru. Dzięki temu użytkownicy mogą określić typ i prawidłowy zakres do przykładowych parametrów. Język FLAML obsługuje następujące typy hiperparametrów: zmiennoprzecinkowe, całkowite i podzielone na kategorie. Poniższy przykład można zobaczyć w przypadku często używanych domen:

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

Aby dowiedzieć się więcej na temat dostosowywania domen w przestrzeni wyszukiwania, odwiedź dokumentację FLAML dotyczącą dostosowywania przestrzeni wyszukiwania.

Dostrajanie ograniczeń

Ostatnim krokiem jest określenie ograniczeń zadania dostrajania. Jedną z godnych uwagi właściwością flaml.tune jest możliwość ukończenia procesu dostrajania w ramach wymaganego ograniczenia zasobów. W tym celu użytkownik może zapewnić ograniczenia zasobów w zakresie czasu zegara ściany (w sekundach) przy użyciu argumentu time_budget_s lub liczby prób przy użyciu 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, ...)

Aby dowiedzieć się więcej na temat ograniczeń konfiguracji dodawania, możesz zapoznać się z dokumentacją FLAML dotyczącą zaawansowanych opcji dostrajania.

Łączenie go

Po zdefiniowaniu kryteriów dostrajania możemy wykonać wersję próbną dostrajania. Aby śledzić wyniki naszej wersji próbnej, możemy wykorzystać funkcję automatycznego rejestrowania usługi MLFlow do przechwytywania metryk i parametrów dla każdego z tych przebiegów. Ten kod przechwytuje całą wersję próbną dostrajania hiperparametrów, wyróżniając każdą z kombinacji hiperparametrów, które zostały zbadane przez 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
    )

Uwaga

Po włączeniu automatycznego rejestrowania platformy MLflow metryki, parametry i modele powinny być rejestrowane automatycznie podczas uruchamiania biblioteki MLFlow. Jednak różni się to w zależności od platformy. Metryki i parametry dla określonych modeli mogą nie być rejestrowane. Na przykład dla modeli XGBoost, LightGBM, Spark i SynapseML nie będą rejestrowane żadne metryki. Więcej informacji na temat metryk i parametrów przechwyconych z każdej platformy można znaleźć w dokumentacji automatycznego rejestrowania mlFlow.

Dostrajanie równoległe za pomocą platformy Apache Spark

Funkcja flaml.tune obsługuje dostrajanie zarówno platformy Apache Spark, jak i uczniów z jednym węzłem. Ponadto podczas dostrajania uczniów z jednym węzłem (np. uczniów biblioteki Scikit-Learn) można również zrównać dostrajanie, aby przyspieszyć proces dostrajania, ustawiając wartość use_spark = True. W przypadku klastrów Spark domyślnie platforma FLAML uruchamia jedną wersję próbną na funkcję wykonawcza. Możesz również dostosować liczbę współbieżnych prób przy użyciu 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

Aby dowiedzieć się więcej na temat równoległości tras dostrajania, zapoznaj się z dokumentacją FLAML dotyczącą równoległych zadań platformy Spark.

Wizualizowanie wyników

Moduł flaml.visualization udostępnia funkcje narzędzi do kreślenia procesu optymalizacji przy użyciu narzędzia Plotly. Korzystając z funkcji Plotly, użytkownicy mogą interaktywnie eksplorować wyniki eksperymentu rozwiązania AutoML. Aby użyć tych funkcji kreślenia, po prostu podaj zoptymalizowany flaml.AutoML lub flaml.tune.tune.ExperimentAnalysis obiekt jako dane wejściowe.

W notesie można użyć następujących funkcji:

  • plot_optimization_history: Wykreślij historię optymalizacji wszystkich prób w eksperymencie.
  • plot_feature_importance: Wykreślij znaczenie dla każdej funkcji w zestawie danych.
  • plot_parallel_coordinate: Wykreślij relacje parametrów o wysokim wymiarach w eksperymencie.
  • plot_contour: Wykreślij relację parametrów jako wykres konturowy w eksperymencie.
  • plot_edf: wykreślić wartość docelową EDF (funkcja rozkładu empirycznego) eksperymentu.
  • plot_timeline: Wykreślij oś czasu eksperymentu.
  • plot_slice: Wykreślij relację parametrów jako wykres wycinka w badaniu.
  • plot_param_importance: Wykreślij znaczenie hiperparametru eksperymentu.