迈向 Optuna v5

我们目前正在开发 Optuna v5。与 v5 路线图相关的功能将添加到 v4.x 更新中。

Optuna MCP 服务器

Optuna MCP 服务器,支持通过大型语言模型(LLM)控制 Optuna,并通过对话提供交互式优化功能。

Optuna 面板 LLM 集成

由大型语言模型(LLM)驱动的 Optuna 面板灵活控制,例如使用自然语言查询数据。

多目标 GPSampler

基于高斯过程的多目标贝叶斯优化。

阅读 Optuna v5 路线图博客 为 Optuna v5 贡献 就 Optuna v5 向我们提供反馈

主要特性

急切(Eager)搜索空间

使用 Python 条件语句、循环和语法自动搜索最优超参数

最先进的算法

高效搜索大空间并修剪无望的试验,以获得更快的结果

轻松并行化

在多个线程或进程中并行进行超参数搜索,无需修改代码

代码示例

Optuna 与框架无关。你可以将其与任何机器学习或深度学习框架一起使用。

一个简单的优化问题

  1. 定义要优化的 objective 函数。让我们最小化 (x - 2)^2
  2. 使用 trial 对象建议超参数值。这里,建议 x 的浮点值范围从 -1010
  3. 创建一个 study 对象,并在 100 次试验中调用 optimize 方法
import optuna

def objective(trial):
    x = trial.suggest_float('x', -10, 10)
    return (x - 2) ** 2

study = optuna.create_study()
study.optimize(objective, n_trials=100)

study.best_params  # E.g. {'x': 2.002108042}

colab.research.google Open in Colab Open in Colab

你可以通过三个步骤优化 PyTorch 超参数,例如层数和每层中的隐藏节点数

  1. 使用 objective 函数包装模型训练并返回准确率
  2. 使用 trial 对象建议超参数
  3. 创建一个 study 对象并执行优化
import torch

import optuna

# 1. Define an objective function to be maximized.
def objective(trial):

    # 2. Suggest values of the hyperparameters using a trial object.
    n_layers = trial.suggest_int('n_layers', 1, 3)
    layers = []

    in_features = 28 * 28
    for i in range(n_layers):
        out_features = trial.suggest_int(f'n_units_l{i}', 4, 128)
        layers.append(torch.nn.Linear(in_features, out_features))
        layers.append(torch.nn.ReLU())
        in_features = out_features
    layers.append(torch.nn.Linear(in_features, 10))
    layers.append(torch.nn.LogSoftmax(dim=1))
    model = torch.nn.Sequential(*layers).to(torch.device('cpu'))
    ...
    return accuracy

# 3. Create a study object and optimize the objective function.
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
在 GitHub 上查看完整示例

你可以通过三个步骤优化 TensorFlow 超参数,例如层数和每层中的隐藏节点数

  1. 使用 objective 函数包装模型训练并返回准确率
  2. 使用 trial 对象建议超参数
  3. 创建一个 study 对象并执行优化
import tensorflow as tf

import optuna

# 1. Define an objective function to be maximized.
def objective(trial):

    # 2. Suggest values of the hyperparameters using a trial object.
    n_layers = trial.suggest_int('n_layers', 1, 3)
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten())
    for i in range(n_layers):
        num_hidden = trial.suggest_int(f'n_units_l{i}', 4, 128, log=True)
        model.add(tf.keras.layers.Dense(num_hidden, activation='relu'))
    model.add(tf.keras.layers.Dense(CLASSES))
    ...
    return accuracy

# 3. Create a study object and optimize the objective function.
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
在 GitHub 上查看完整示例

你可以通过三个步骤优化 Keras 超参数,例如滤波器数量和核大小

  1. 使用 objective 函数包装模型训练并返回准确率
  2. 使用 trial 对象建议超参数
  3. 创建一个 study 对象并执行优化
import keras

import optuna

# 1. Define an objective function to be maximized.
def objective(trial):
    model = Sequential()

    # 2. Suggest values of the hyperparameters using a trial object.
    model.add(
        Conv2D(filters=trial.suggest_categorical('filters', [32, 64]),
               kernel_size=trial.suggest_categorical('kernel_size', [3, 5]),
               strides=trial.suggest_categorical('strides', [1, 2]),
               activation=trial.suggest_categorical('activation', ['relu', 'linear']),
               input_shape=input_shape))
    model.add(Flatten())
    model.add(Dense(CLASSES, activation='softmax'))

    # We compile our model with a sampled learning rate.
    lr = trial.suggest_float('lr', 1e-5, 1e-1, log=True)
    model.compile(loss='sparse_categorical_crossentropy', optimizer=RMSprop(lr=lr), metrics=['accuracy'])
    ...
    return accuracy

# 3. Create a study object and optimize the objective function.
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
在 GitHub 上查看完整示例

你可以通过三个步骤优化 Scikit-Learn 超参数,例如 SVCC 参数和 RandomForestClassifiermax_depth

  1. 使用 objective 函数包装模型训练并返回准确率
  2. 使用 trial 对象建议超参数
  3. 创建一个 study 对象并执行优化
import sklearn

import optuna

# 1. Define an objective function to be maximized.
def objective(trial):

    # 2. Suggest values for the hyperparameters using a trial object.
    classifier_name = trial.suggest_categorical('classifier', ['SVC', 'RandomForest'])
    if classifier_name == 'SVC':
         svc_c = trial.suggest_float('svc_c', 1e-10, 1e10, log=True)
         classifier_obj = sklearn.svm.SVC(C=svc_c, gamma='auto')
    else:
        rf_max_depth = trial.suggest_int('rf_max_depth', 2, 32, log=True)
        classifier_obj = sklearn.ensemble.RandomForestClassifier(max_depth=rf_max_depth, n_estimators=10)
    ...
    return accuracy

# 3. Create a study object and optimize the objective function.
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
在 GitHub 上查看完整示例

你可以通过三个步骤优化 XGBoost 超参数,例如 booster 类型和 alpha

  1. 使用 objective 函数包装模型训练并返回准确率
  2. 使用 trial 对象建议超参数
  3. 创建一个 study 对象并执行优化
import xgboost as xgb

import optuna

# 1. Define an objective function to be maximized.
def objective(trial):
    ...

    # 2. Suggest values of the hyperparameters using a trial object.
    param = {
        "objective": "binary:logistic",
        "booster": trial.suggest_categorical("booster", ["gbtree", "gblinear", "dart"]),
        "lambda": trial.suggest_float("lambda", 1e-8, 1.0, log=True),
        "alpha": trial.suggest_float("alpha", 1e-8, 1.0, log=True),
        "subsample": trial.suggest_float("subsample", 0.2, 1.0),
        "colsample_bytree": trial.suggest_float("colsample_bytree", 0.2, 1.0),
    }

    bst = xgb.train(param, dtrain)
    ...
    return accuracy

# 3. Create a study object and optimize the objective function.
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
在 GitHub 上查看完整示例

你可以通过三个步骤优化 LightGBM 超参数,例如 boosting 类型和叶子数量

  1. 使用 objective 函数包装模型训练并返回准确率
  2. 使用 trial 对象建议超参数
  3. 创建一个 study 对象并执行优化
import lightgbm as lgb

import optuna

# 1. Define an objective function to be maximized.
def objective(trial):
    ...

    # 2. Suggest values of the hyperparameters using a trial object.
    param = {
        'objective': 'binary',
        'metric': 'binary_logloss',
        'verbosity': -1,
        'boosting_type': 'gbdt',
        'lambda_l1': trial.suggest_float('lambda_l1', 1e-8, 10.0, log=True),
        'lambda_l2': trial.suggest_float('lambda_l2', 1e-8, 10.0, log=True),
        'num_leaves': trial.suggest_int('num_leaves', 2, 256),
        'feature_fraction': trial.suggest_float('feature_fraction', 0.4, 1.0),
        'bagging_fraction': trial.suggest_float('bagging_fraction', 0.4, 1.0),
        'bagging_freq': trial.suggest_int('bagging_freq', 1, 7),
        'min_child_samples': trial.suggest_int('min_child_samples', 5, 100),
    }

    gbm = lgb.train(param, dtrain)
    ...
    return accuracy

# 3. Create a study object and optimize the objective function.
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
在 GitHub 上查看完整示例

在我们的 GitHub 仓库中查看更多示例,包括 PyTorch Ignite、Dask-ML 和 MLFlow。
它还提供了如下可视化演示

from optuna.visualization import plot_intermediate_values

...
plot_intermediate_values(study)
在 GitHub 上查看完整示例

安装

Optuna 可以使用 pip 安装。支持 Python 3.8 或更高版本。

% pip install optuna
详情

面板

Optuna 面板 是一个 Optuna 的实时 Web 面板。你可以在图表和表格中查看优化历史、超参数重要性等。

% pip install optuna-dashboard
% optuna-dashboard sqlite:///db.sqlite3

Optuna 面板也作为 Jupyter Lab 和 Visual Studio Code 的扩展提供。

VS Code 扩展

VS Code Extension

要使用,请安装该扩展,在文件浏览器中右键单击 SQLite3 文件,然后从下拉菜单中选择“在 Optuna 面板中打开”。

Jupyter Lab 扩展

Jupyter Lab Extension
% pip install jupyterlab jupyterlab-optuna
GitHub 仓库 文档 VS Code 扩展 (应用商店)

OptunaHub

OptunaHub 是一个 Optuna 功能分享平台。用户可以免费使用注册的功能,贡献者可以注册他们实现的功能。以下示例使用了 OptunaHub 上的 AutoSampler,它会自动从 Optuna 中实现的采样器中选择合适的采样器。

% pip install optunahub
% pip install cmaes scipy torch  # install AutoSampler dependencies
import optuna
import optunahub

def objective(trial: optuna.Trial) -> float:
	x = trial.suggest_float("x", -5, 5)
	y = trial.suggest_float("y", -5, 5)
	return x**2 + y**2

module = optunahub.load_module(package="samplers/auto_sampler")
study = optuna.create_study(sampler=module.AutoSampler())
study.optimize(objective, n_trials=50)

print(study.best_trial.value, study.best_trial.params)
OptunaHub 注册你的包
在 Medium 上查看更多故事

视频

论文

如果你在科学出版物中使用 Optuna,请使用以下引用

Takuya Akiba, Shotaro Sano, Toshihiko Yanase, Takeru Ohta, and Masanori Koyama. 2019.
Optuna: A Next-generation Hyperparameter Optimization Framework. In KDD.
查看论文 arXiv 预印本

Bibtex 条目

@inproceedings{optuna_2019,
    title={Optuna: A Next-generation Hyperparameter Optimization Framework},
    author={Akiba, Takuya and Sano, Shotaro and Yanase, Toshihiko and Ohta, Takeru and Koyama, Masanori},
    booktitle={Proceedings of the 25th {ACM} {SIGKDD} International Conference on Knowledge Discovery and Data Mining},
    year={2019}
}