Hyperparameterafstemming (voorbeeld)
Hyperparameterafstemming is het proces van het vinden van de optimale waarden voor de parameters die niet worden geleerd door het machine learning-model tijdens de training, maar eerder ingesteld door de gebruiker voordat het trainingsproces begint. Deze parameters worden vaak hyperparameters genoemd en voorbeelden zijn de leersnelheid, het aantal verborgen lagen in een neuraal netwerk, de regularisatiesterkte en de batchgrootte.
De prestaties van een machine learning-model kunnen zeer gevoelig zijn voor de keuze van hyperparameters en de optimale set hyperparameters kan sterk variëren, afhankelijk van het specifieke probleem en de gegevensset. Hyperparameterafstemming is daarom een kritieke stap in de machine learning-pijplijn, omdat deze een aanzienlijke invloed kan hebben op de nauwkeurigheid en generalisatieprestaties van het model.
In Fabric kunnen gegevenswetenschappers gebruikmaken van FLAML
, een lichtgewicht Python-bibliotheek voor efficiënte automatisering van machine learning- en AI-bewerkingen, voor hun hyperparameterafstemmingsvereisten. Binnen Fabric-notebooks kunnen gebruikers flaml.tune
aanroepen voor economische afstemming van hyperparameters.
Belangrijk
Deze functie bevindt zich in preview-versie.
Afstemming van de workflow
Er zijn drie essentiële stappen om flaml.tune
te gebruiken om een eenvoudige afstemmingstaak te voltooien:
- Geef de afstemmingsdoelstelling op met betrekking tot de hyperparameters.
- Geef een zoekruimte op van de hyperparameters.
- Geef afstemmingsbeperkingen op, inclusief beperkingen voor het resourcebudget om het afstemmen uit te voeren, beperkingen voor de configuraties of/en beperkingen voor een (of meerdere) specifieke metrische gegevens.
Afstemmingsdoel
De eerste stap is het opgeven van uw afstemmingsdoelstelling. Hiervoor moet u eerst uw evaluatieprocedure opgeven met betrekking tot de hyperparameters in een door de gebruiker gedefinieerde functie evaluation_function
. De functie vereist een hyperparameterconfiguratie als invoer. Het kan gewoon een metrische waarde in een scalaire waarde retourneren of een woordenlijst met metrische naam en metrische waardeparen retourneren.
In het onderstaande voorbeeld kunnen we een evaluatiefunctie definiëren met betrekking tot 2 hyperparameters met de naam x
en 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"]}
Zoekruimte
Vervolgens geven we de zoekruimte van hyperparameters op. In de zoekruimte moet u geldige waarden opgeven voor uw hyperparameters en hoe deze waarden worden gemonsterd (bijvoorbeeld uit een uniforme distributie of een log-uniform distributie). In het onderstaande voorbeeld kunnen we de zoekruimte bieden voor de hyperparameters x
en y
. De geldige waarden voor beide zijn gehele getallen van [1, 100.000]. Deze hyperparameters worden uniform gemonsterd in de opgegeven bereiken.
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, ...)
Met FLAML kunnen gebruikers het domein aanpassen voor een bepaalde hyperparameter. Hiermee kunnen gebruikers een type en geldig bereik opgeven van waaruit de voorbeeldparameters afkomstig zijn. FLAML ondersteunt de volgende hyperparametertypen: float, integer en categorisch. Hieronder ziet u dit voorbeeld voor veelgebruikte domeinen:
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"]),
}
Ga naar de FLAML-documentatie over het aanpassen van zoekruimtenvoor meer informatie over het aanpassen van domeinen in uw zoekruimte.
Instellen van beperkingen
De laatste stap is het opgeven van beperkingen van de tuningtaak. Een belangrijke eigenschap van flaml.tune
is dat het afstemmingsproces binnen een vereiste resourcebeperking kan worden voltooid. Om dit te doen, kan een gebruiker resourcebeperkingen opgeven in termen van wandkloktijd (in seconden) met behulp van het time_budget_s
argument of in termen van het aantal experimenten met behulp van het argument 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, ...)
Zie de FLAML-documentatie voor geavanceerde afstemmingsoptiesvoor meer informatie over aanvullende configuratiebeperkingen.
Alles samenbrengen
Zodra we onze afstemmingscriteria hebben gedefinieerd, kunnen we de afstemmingstest uitvoeren. Om de resultaten van onze proefversie bij te houden, kunnen we gebruikmaken van MLFlow-automatische logboekregistratie om de metrische gegevens en parameters voor elk van deze uitvoeringen vast te leggen. Met deze code wordt de volledige proefversie voor het afstemmen van hyperparameters vastgelegd, waarbij elk van de combinaties van hyperparameters wordt gemarkeerd die door FLAML zijn verkend.
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
)
Notitie
Wanneer automatische aanmelding van MLflow is ingeschakeld, moeten metrische gegevens, parameters en modellen automatisch worden geregistreerd wanneer MLFlow wordt uitgevoerd. Dit verschilt echter per framework. Metrische gegevens en parameters voor specifieke modellen worden mogelijk niet vastgelegd. Er worden bijvoorbeeld geen metrische gegevens vastgelegd voor XGBoost-, LightGBM-, Spark- en SynapseML-modellen. Meer informatie over welke metrische gegevens en parameters worden vastgelegd vanuit elk framework met behulp van de documentatie voor automatische logboeken van MLFlow.
Parallel afstemmen met Apache Spark
De flaml.tune
-functionaliteit biedt ondersteuning voor het afstemmen van zowel Apache Spark als enkelvoudige knooppunt algoritmen. Daarnaast kunt u bij het afstellen van leermodellen met één knooppunt (bijvoorbeeld Scikit-Learn modellen) ook het afstellen parallel maken om het afstelproces te versnellen door use_spark = True
in te stellen. Voor Spark-clusters start FLAML standaard één proefversie per uitvoerder. U kunt ook het aantal gelijktijdige experimenten aanpassen met behulp van het argument 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
Voor meer informatie over het parallelliseren van uw afstemmingspaden, kunt u de FLAML-documentatie voor parallelle Spark-takenbezoeken.
Resultaten visualiseren
De flaml.visualization
-module biedt hulpprogrammafuncties voor het plotten van het optimalisatieproces met behulp van Plotly. Door Gebruik te maken van Plotly kunnen gebruikers interactief hun Resultaten van het AutoML-experiment verkennen. Als u deze tekenfuncties wilt gebruiken, geeft u gewoon uw geoptimaliseerde flaml.AutoML
of flaml.tune.tune.ExperimentAnalysis
object op als invoer.
U kunt de volgende functies in uw notebook gebruiken:
-
plot_optimization_history
: Plot de optimalisatiegeschiedenis van alle proeven in het experiment. -
plot_feature_importance
: Belang van plot voor elke functie in de gegevensset. -
plot_parallel_coordinate
: Teken de hoogdimensionale parameterrelaties in het experiment. -
plot_contour
: Teken de parameterrelatie als contourplot in het experiment. -
plot_edf
: Plot de objectieve waarde EDF (empirische verdelingsfunctie) van het experiment. -
plot_timeline
: De tijdlijn van het experiment uitzetten. -
plot_slice
: Teken de parameterrelatie als segmentplot in een studie. -
plot_param_importance
: Het belang van de hyperparameter van het experiment uitzetten.