Hiperparaméter finomhangolása (előzetes verzió)
A hiperparaméter-finomhangolás a gépi tanulási modell által a betanítás során nem tanult paraméterek optimális értékeinek megkeresése, hanem a felhasználó által a betanítási folyamat megkezdése előtt beállított érték. Ezeket a paramétereket gyakran hiperparamétereknek nevezzük, például a tanulási arányt, a neurális hálózat rejtett rétegeinek számát, a rendszerezés erősségét és a köteg méretét.
A gépi tanulási modell teljesítménye rendkívül érzékeny lehet a hiperparaméterek kiválasztására, és a hiperparaméterek optimális készlete az adott probléma és adatkészlet függvényében nagy mértékben változhat. A hiperparaméterek finomhangolása ezért a gépi tanulási folyamat kritikus lépése, mivel jelentős hatással lehet a modell pontosságára és általánosítási teljesítményére.
A Fabricben az adattudósok egy egyszerűsített Python-kódtárat használhatnak FLAML
a gépi tanulás és az AI-műveletek hatékony automatizálásához a hiperparaméter-finomhangolási követelményeikhez. A Fabric-jegyzetfüzetekben a felhasználók gazdaságos hiperparaméter-finomhangolást kezdeményezhetnek flaml.tune
.
Egy alapszintű hangolási feladat elvégzéséhez három alapvető lépés szükséges flaml.tune
:
- Adja meg a finomhangolási célt a hiperparaméterekre vonatkozóan.
- Adja meg a hiperparaméterek keresési területét.
- Adjon meg hangolási korlátozásokat, beleértve az erőforrás-költségvetésre vonatkozó korlátozásokat a finomhangoláshoz, a konfigurációk korlátozásait vagy/és egy (vagy több) adott metrika(ok) korlátozásait.
Az első lépés a hangolási cél meghatározása. Ehhez először meg kell adnia a kiértékelési eljárást a felhasználó által definiált függvény evaluation_function
hiperparamétereivel kapcsolatban. A függvény bemenetként hiperparaméter-konfigurációt igényel. Egyszerűen visszaadhat egy metrikaértéket egy skalárisban, vagy visszaadhatja a metrikanév és a metrikaérték párok szótárát.
Az alábbi példában meghatározhatunk egy kiértékelési függvényt a nevesített x
és y
a .
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"]}
Ezután meg fogjuk adni a hiperparaméterek keresési területét. A keresési területen meg kell adnia a hiperparaméterek érvényes értékeit, valamint az értékek mintavételi módját (például egy egységes eloszlásból vagy egy napló-egységes eloszlásból). Az alábbi példában megadhatjuk a hiperparaméterek x
és y
a . Mindkét érték érvényes értéke az [1, 100 000] közötti egész szám. Ezek a hiperparaméterek a megadott tartományokban egységesen mintavételezettek.
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, ...)
A FLAML használatával a felhasználók testre szabhatják a tartományt egy adott hiperparaméterhez. Ez lehetővé teszi, hogy a felhasználók típust és érvényes tartományt adjanak meg a mintaparaméterekhez. A FLAML a következő hiperparaméter-típusokat támogatja: lebegőpontos, egész és kategorikus. Az alábbi példa a gyakran használt tartományokra vonatkozik:
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"]),
}
Ha többet szeretne megtudni arról, hogyan szabhatja testre a tartományokat a keresési területen belül, tekintse meg a keresési területek testreszabásával kapcsolatos FLAML-dokumentációt.
Az utolsó lépés a finomhangolási tevékenység korlátozásainak megadása. Ennek egyik fontos tulajdonsága flaml.tune
, hogy képes elvégezni a hangolási folyamatot egy szükséges erőforrás-korlátozáson belül. Ehhez a felhasználó az argumentummal time_budget_s
vagy az argumentummal végzett kísérletek számának függvényében (másodpercben) megadhat erőforrás-korlátozásokat a num_samples
falióra-idő alapján.
# 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, ...)
A hozzáadási konfigurációs korlátozásokról a FLAML dokumentációjában talál további információt a speciális hangolási lehetőségekről.
Miután meghatároztuk a hangolási feltételeket, végrehajthatjuk a finomhangolási próbaverziót. A próbaverzió eredményeinek nyomon követéséhez az MLFlow automatikus naplózásával rögzíthetjük az egyes futtatások metrikáit és paramétereit. Ez a kód rögzíti a teljes hiperparaméter-finomhangolási próbaverziót, kiemelve a FLAML által vizsgált hiperparaméter-kombinációkat.
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
)
Megjegyzés
Ha az MLflow automatikus naplózása engedélyezve van, a metrikákat, paramétereket és modelleket automatikusan naplózni kell az MLFlow futtatásakor. Ez azonban a keretrendszertől függően változik. Adott modellek metrikái és paraméterei nem naplózhatók. Például az XGBoost, a LightGBM, a Spark és a SynapseML modellekhez nem lesznek metrikák naplózva. Az MLFlow automatikus kitöltési dokumentációja segítségével többet is megtudhat arról, hogy az egyes keretrendszerek milyen metrikákat és paramétereket rögzítenek.
A flaml.tune
funkció támogatja az Apache Spark és az egycsomópontos tanulók hangolását is. Emellett az egycsomópontos tanulók (pl. Scikit-Learn tanulók) hangolása esetén a hangolást a beállítással use_spark = True
párhuzamosan is felgyorsíthatja. Spark-fürtök esetén a FLAML alapértelmezés szerint végrehajtónként egy próbaverziót indít el. Az egyidejű kísérletek számát az argumentum használatával n_concurrent_trials
is testre szabhatja.
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
Ha többet szeretne megtudni a hangolási nyomvonalak párhuzamosításáról, tekintse meg a párhuzamos Spark-feladatok FLAML-dokumentációját.
A flaml.visualization
modul segédprogramfüggvényeket biztosít az optimalizálási folyamat ábrázolására a Plotly használatával. A Plotly használatával a felhasználók interaktívan megismerhetik az AutoML-kísérlet eredményeit. A diagramfüggvények használatához egyszerűen adja meg az optimalizált flaml.AutoML
vagy flaml.tune.tune.ExperimentAnalysis
az objektumot bemenetként.
A jegyzetfüzetben a következő függvények használhatók:
plot_optimization_history
: A kísérletben szereplő összes kísérlet optimalizálási előzményeinek ábrázolása.plot_feature_importance
: Az adathalmaz minden funkciójának ábrázolása.plot_parallel_coordinate
: Ábrázolja a kísérletben a nagy dimenziójú paraméterkapcsolatokat.plot_contour
: A paraméterkapcsolat ábrázolása körvonaldiagramként a kísérletben.plot_edf
: Ábrázolja a kísérlet EDF (empirikus eloszlásfüggvénye) objektív értékét.plot_timeline
: Ábrázolja a kísérlet ütemtervét.plot_slice
: A paraméterkapcsolat ábrázolása szeletdiagramként egy tanulmányban.plot_param_importance
: Ábrázolja a kísérlet hiperparaméter-jelentőségét.