Hyperparameterafstemming (preview)
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 economische hyperparameterafstemming aanroepen flaml.tune
.
Belangrijk
Deze functie is beschikbaar als preview-versie.
Werkstroom afstemmen
Er zijn drie essentiële stappen om een eenvoudige afstemmingstaak te flaml.tune
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.
Doel afstemmen
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 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 een 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"]),
}
Voor meer informatie over hoe u domeinen in uw zoekruimte kunt aanpassen, gaat u naar de FLAML-documentatie over het aanpassen van zoekruimten.
Beperkingen afstemmen
De laatste stap is het opgeven van beperkingen van de afstemmingstaak. Een belangrijke eigenschap is flaml.tune
dat het het afstemmingsproces binnen een vereiste resourcebeperking kan voltooien. Om dit te doen, kan een gebruiker resourcebeperkingen opgeven in termen van tijd van wandklok (in seconden) met behulp van het time_budget_s
argument of in termen van het aantal experimenten met behulp van het num_samples
argument.
# 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 afstemmingsopties voor meer informatie over aanvullende configuratiebeperkingen.
Het samenbrengen
Zodra we onze afstemmingscriteria hebben gedefinieerd, kunnen we de afstemmingstest uitvoeren. Om de resultaten van onze proefversie bij te houden, kunnen we automatische logboekregistratie van MLFlow gebruiken 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 automatisch vastleggen van MLFlow.
Parallel afstemmen met Apache Spark
De flaml.tune
functionaliteit biedt ondersteuning voor het afstemmen van zowel Apache Spark als leren van één knooppunt. Daarnaast kunt u bij het afstemmen van leren met één knooppunt (bijvoorbeeld Scikit-Learn-cursisten) ook het afstemmen parallelliseren om het afstemmingsproces te versnellen door het instellen in te stellen use_spark = True
. Voor Spark-clusters start FLAML standaard één proefversie per uitvoerder. U kunt ook het aantal gelijktijdige experimenten aanpassen met behulp van het n_concurrent_trials
argument.
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-taken bezoeken.
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 plotting-functies 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 optimization history of all trials in the 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 EOF (empirische verdelingsfunctie) van het experiment.plot_timeline
: Teken de tijdlijn van het experiment.plot_slice
: Teken de parameterrelatie als segmentplot in een studie.plot_param_importance
: Teken het belang van de hyperparameter van het experiment.