跳到主要内容

使用 MLflow 跟踪超参数调优

MLflow UI Chart page

超参数调优是提高机器学习模型性能的重要过程,然而,手动跟踪和比较不同的试验可能很麻烦。MLflow 提供了一个强大的超参数调优框架,允许您系统地探索超参数空间并找到最佳模型。

在本教程结束时,您将了解如何

  • 使用 MLflow 跟踪设置您的环境。
  • 定义一个用于拟合机器学习模型的偏函数,该模型可与超参数调优库一起使用。
  • 使用 Optuna 进行超参数调优。
  • 利用 MLflow 中的子运行来跟踪超参数调优过程中的每次迭代。

先决条件:设置 MLflow 和 Optuna

MLflow 可在 PyPI 上获取。使用以下命令安装 MLflow 和 Optuna(超参数调优库):

bash
pip install mlflow optuna

然后,请按照 设置 MLflow 指南中的说明进行 MLflow 的设置。

团队协作和托管设置

对于生产环境或团队协作,请考虑托管一个共享的 MLflow 跟踪服务器。有关完全托管的解决方案,请访问 Databricks 试用注册页面 并按照其中的说明进行操作,以开始使用 Databricks 免费试用。

步骤 1:创建新实验

python
import mlflow

# The set_experiment API creates a new experiment if it doesn't exist.
mlflow.set_experiment("Hyperparameter Tuning Experiment")

步骤 2:准备您的数据

首先,让我们加载一个示例数据集并将其分割成训练集和验证集。

python
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_california_housing

X, y = fetch_california_housing(return_X_y=True)
X_train, X_val, y_train, y_val = train_test_split(X, y, random_state=0)

步骤 3:定义目标函数

在 Optuna 中,study 是一个单一的优化任务,代表由多个 trial 组成的整个超参数调优会话。Trial 是对目标函数的单次执行,即使用单个超参数组合训练模型。

在 MLflow 中,此结构由一个父运行子运行表示。父运行是包含不同 trial 的所有子运行的运行。父子关系使我们能够跟踪超参数调优过程中的每次 trial,并在 MLflow UI 中对它们进行分组。

首先,我们定义每次 trial 执行的目标函数。为了记录参数、指标和模型文件,我们在目标函数中使用 MLflow 的 API。使用 nested=True 标志创建 MLflow 运行,以指示它是子运行。

python
import mlflow
import optuna
import sklearn


def objective(trial):
# Setting nested=True will create a child run under the parent run.
with mlflow.start_run(nested=True, run_name=f"trial_{trial.number}") as child_run:
rf_max_depth = trial.suggest_int("rf_max_depth", 2, 32)
rf_n_estimators = trial.suggest_int("rf_n_estimators", 50, 300, step=10)
rf_max_features = trial.suggest_float("rf_max_features", 0.2, 1.0)
params = {
"max_depth": rf_max_depth,
"n_estimators": rf_n_estimators,
"max_features": rf_max_features,
}
# Log current trial's parameters
mlflow.log_params(params)

regressor_obj = sklearn.ensemble.RandomForestRegressor(**params)
regressor_obj.fit(X_train, y_train)

y_pred = regressor_obj.predict(X_val)
error = sklearn.metrics.mean_squared_error(y_val, y_pred)
# Log current trial's error metric
mlflow.log_metrics({"error": error})

# Log the model file
mlflow.sklearn.log_model(regressor_obj, name="model")
# Make it easy to retrieve the best-performing child run later
trial.set_user_attr("run_id", child_run.info.run_id)
return error

步骤 3:运行超参数调优研究

现在,让我们使用 Optuna 运行超参数调优研究。我们创建一个名为“study”的父运行,并将最佳 trial 的参数和指标记录在那里。

python
# Create a parent run that contains all child runs for different trials
with mlflow.start_run(run_name="study") as run:
# Log the experiment settings
n_trials = 30
mlflow.log_param("n_trials", n_trials)

study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=n_trials)

# Log the best trial and its run ID
mlflow.log_params(study.best_trial.params)
mlflow.log_metrics({"best_error": study.best_value})
if best_run_id := study.best_trial.user_attrs.get("run_id"):
mlflow.log_param("best_child_run_id", best_run_id)

步骤 4:在 MLflow UI 中查看结果

要查看训练结果,您可以访问跟踪服务器 URL 来访问 MLflow UI。如果您尚未启动跟踪服务器,请打开一个新的终端,在 MLflow 项目的根目录下运行以下命令,然后通过 https://:5000(或您指定的端口号)访问 UI。

bash
mlflow server --port 5000

打开网站后,您将看到一个类似于以下内容的屏幕:

MLflow UI Home page

“Experiments”部分显示了(最近创建的)实验列表。单击本教程中创建的“Hyperparameter Tuning Experiment”实验。

MLflow UI Run list page

单击左上角的图表图标以查看调优结果的可视化表示。您可以进一步单击每个子运行以查看每次 trial 的详细指标和参数。

MLflow UI Chart page

步骤 5:注册您的最佳模型

一旦确定了最佳 trial,就可以将模型注册到 MLflow 模型注册表 中,以便将其推广到生产环境。

python
# Register the best model using the model URI
mlflow.register_model(
model_uri="runs:/d0210c58afff4737a306a2fbc5f1ff8d/model",
name="housing-price-predictor",
)

# > Successfully registered model 'housing-price-predictor'.
# > Created version '1' of model 'housing-price-predictor'.

后续步骤