optuna可视化调参魔法指南

optuna-自动化调参利器 optuna调参利器 阅读详情
AI摘要

Optuna是一个强大的开源调参工具,支持多种优化算法如贝叶斯优化、遗传算法。文章通过PyTorch和TensorFlow模型调参实例展示了Optuna的使用,包括模型融合权重的优化。此外,还介绍了Optuna的断点续搜、剪枝策略、可视化功能以及如何添加手动采样点等特性。

Optuna是一款开源的调参工具,github star数量超过7k, 是目前最受欢迎的调参框架之一。

其主要优点如下:

1,Optuna拥有许多非常先进的调参算法(如贝叶斯优化,遗传算法采样等),这些算法往往可以在几十上百次的尝试过程中找到一个不可微问题的较优解。

2,通过配合optuna-dashboard,可以可视化整个调参过程,从各个方面加深对问题的理解,这是一个令人心动的特性😋!

公众号后台回复关键词:optuna,获取本文源代码和bilibili视频演示。

9ee24a164362f47bb7149baac79b9e06.jpeg

另外,Optuna还有如下一些非常实用的特性:

1,通过将搜索结果存储到sqlite或mysql、postgresql,Optuna支持断点续搜。

2,Optuna支持剪枝策略,提前结束一些中间返回结果较差的采样点从而加快搜索进程。

3,Optuna支持手动指定一些超参采样点,也可以添加已经计算过的采样点及其结果作为初始化样本点。

4,Optuna提供ask and tell 接口模式,无需显式定义目标函数,直接在循环中调优超参。

5,Optuna封装了非常丰富的基于plotly的可视化函数,便于分析调参结果。

6,通过将搜索结果存储到mysql或postgresql,并设置分布式模式,Optuna支持多机分布式搜索,通过并行方式加快搜索进程。

我们将首先展示一些非常实用的综合应用范例演示optuna在算法调优实践中的魔力。

然后展示一些optuna的基础特性范例详细讲解optuna的主要特性和API应用方法。

综合应用范例:

一,optuna对pytorch模型调参范例

二,optuna对tensorflow模型调参范例

三,optuna对多模型加权融合范例

基础特性范例:

四,单参数空间搜索范例

五,网格参数空间搜索范例

六,断点续搜范例

七,剪枝策略范例

八,各种调参可视化函数范例

九,手动添加超参数采样点范例

参考文档

optuna官方文档:https://optuna.readthedocs.io/en/stable/tutorial/index.html

optuna更多范例库:https://github.com/optuna/optuna-examples 【价值非常大,强烈建议参考】

〇,环境准备

!pip install optuna -i https://pypi.tuna.tsinghua.edu.cn/simple
!pip install optuna-dashboard -i https://pypi.tuna.tsinghua.edu.cn/simple
!pip install plotly -i https://pypi.tuna.tsinghua.edu.cn/simple

在后台异步执行打开 optuna-dashboard 可视化 监控页面,

然后浏览器中输入:http://localhost:8083/dashboard/ 查看监控页面,类似tensorboard

nohup optuna-dashboard --host 0.0.0.0  --port 8083 sqlite:///optuna.db &
#杀死 optuna-dashboard
#!ps aux|grep optuna-dashboard 
#!kill -9 1161

一,optuna对pytorch模型调参范例

import os

import optuna
from optuna.trial import TrialState
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torch.utils.data
from torchvision import datasets
from torchvision import transforms


DEVICE = torch.device("cpu")
BATCHSIZE = 128
CLASSES = 10
DIR = os.getcwd()
EPOCHS = 10
N_TRAIN_EXAMPLES = BATCHSIZE * 30
N_VALID_EXAMPLES = BATCHSIZE * 10


def define_model(trial):
    # We optimize the number of layers, hidden units and dropout ratio in each layer.
    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("n_units_{}".format(i), 16, 64)
        layers.append(nn.Linear(in_features, out_features))
        layers.append(nn.ReLU())
        p = trial.suggest_float("dropout_{}".format(i), 0.1, 0.5)
        layers.append(nn.Dropout(p))

        in_features = out_features
    layers.append(nn.Linear(in_features, CLASSES))
    layers.append(nn.LogSoftmax(dim=1))

    return nn.Sequential(*layers)


def get_mnist():
    # Load FashionMNIST dataset.
    train_loader = torch.utils.data.DataLoader(
        datasets.FashionMNIST(DIR, train=True, download=True, transform=transforms.ToTensor()),
        batch_size=BATCHSIZE,
        shuffle=True,
    )
    valid_loader = torch.utils.data.DataLoader(
        datasets.FashionMNIST(DIR, train=False, transform=transforms.ToTensor()),
        batch_size=BATCHSIZE,
        shuffle=True,
    )

    return train_loader, valid_loader


def objective(trial):

    # Generate the model.
    model = define_model(trial).to(DEVICE)

    # Generate the optimizers.
    optimizer_name = trial.suggest_categorical("optimizer", ["Adam", "RMSprop", "SGD"])
    lr = trial.suggest_float("lr", 1e-5, 1e-1, log=True)
    optimizer = getattr(optim, optimizer_name)(model.parameters(), lr=lr)

    # Get the FashionMNIST dataset.
    train_loader, valid_loader = get_mnist()

    # Training of the model.
    for epoch in range(EPOCHS):
        model.train()
        for batch_idx, (data, target) in enumerate(train_loader):
            # Limiting training data for faster epochs.
            if batch_idx * BATCHSIZE >= N_TRAIN_EXAMPLES:
                break

            data, target = data.view(data.size(0), -1).to(DEVICE), target.to(DEVICE)

            optimizer.zero_grad()
            output = model(data)
            loss = F.nll_loss(output, target)
            loss.backward()
            optimizer.step()

        # Validation of the model.
        model.eval()
        correct = 0
        with torch.no_grad():
            for batch_idx, (data, target) in enumerate(valid_loader):
                # Limiting validation data.
                if batch_idx * BATCHSIZE >= N_VALID_EXAMPLES:
                    break
                data, target = data.view(data.size(0), -1).to(DEVICE), target.to(DEVICE)
                output = model(data)
                # Get the index of the max log-probability.
                pred = output.argmax(dim=1, keepdim=True)
                correct += pred.eq(target.view_as(pred)).sum().item()

        accuracy = correct / min(len(valid_loader.dataset), N_VALID_EXAMPLES)

        
        #attention here 
        trial.report(accuracy, epoch)
        # Handle pruning based on the intermediate value.
        if trial.should_prune():
            raise optuna.exceptions.TrialPruned()

    return accuracy


if __name__ == "__main__":
    storage_name = "sqlite:///optuna.db"
    study = optuna.create_study(
        pruner=optuna.pruners.MedianPruner(n_warmup_steps=3), direction="maximize",
        study_name="fashion_mnist_torch", storage=storage_name,load_if_exists=True
    )
    
    study.optimize(objective, n_trials=20, timeout=1200)

    best_params = study.best_params
    best_value = study.best_value
    print("\n\nbest_value = "+str(best_value))
    print("best_params:")
    print(best_params)

打印结果如下

best_value = 0.83359375
best_params:
{'dropout_0': 0.19431468838501847, 'dropout_1': 0.3924836525263806, 'lr': 0.009735042569270273, 'n_layers': 2, 'n_units_0': 22, 'n_units_1': 52, 'optimizer': 'Adam'}
 

144a2ad115d05b8ced245c4816465ba1.jpeg

二,optuna对tensorflow模型调参范例

import optuna
from optuna.integration import TFKerasPruningCallback
from optuna.trial import TrialState

import tensorflow as tf 
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.utils import to_categorical


N_TRAIN_EXAMPLES = 3000
N_VALID_EXAMPLES = 1000
BATCHSIZE = 128
CLASSES = 10
EPOCHS = 20


def create_model(trial):
    # We optimize the number of layers, hidden units and dropout in each layer and
    # the learning rate of RMSProp optimizer.

    # We define our MLP.
    n_layers = trial.suggest_int("n_layers", 1, 3)
    model = keras.models.Sequential()
    for i in range(n_layers):
        num_hidden = trial.suggest_int("n_units_{}".format(i), 4, 64, log=True)
        model.add(layers.Dense(num_hidden, activation="relu"))
        dropout = trial.suggest_float("dropout_{}".format(i), 0.1, 0.5)
        model.add(layers.Dropout(rate=dropout))
    model.add(layers.Dense(CLASSES, activation="softmax"))

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

    return model


def objective(trial):
    
    tf.keras.backend.clear_session()

    # The data is split between train and validation sets.
    (x_train, y_train), (x_valid, y_valid) = keras.datasets.mnist.load_data()
    x_train = x_train.reshape(60000, 784)[:N_TRAIN_EXAMPLES].astype("float32") / 255
    x_valid = x_valid.reshape(10000, 784)[:N_VALID_EXAMPLES].astype("float32") / 255

    # Convert class vectors to binary class matrices.
    y_train = to_categorical(y_train[:N_TRAIN_EXAMPLES], CLASSES)
    y_valid = to_categorical(y_valid[:N_VALID_EXAMPLES], CLASSES)

    # Generate our trial model.
    model = create_model(trial)

    # Fit the model on the training data.
    # The KerasPruningCallback checks for pruning condition every epoch.
    model.fit(
        x_train,
        y_train,
        batch_size=BATCHSIZE,
        callbacks=[TFKerasPruningCallback(trial, "val_accuracy")],
        epochs=EPOCHS,
        validation_data=(x_valid, y_valid),
        verbose=0,
    )

    # Evaluate the model accuracy on the validation set.
    score = model.evaluate(x_valid, y_valid, verbose=0)
    return score[1]


if __name__ == "__main__":
    storage_name = "sqlite:///optuna.db"
    study = optuna.create_study(
        pruner=optuna.pruners.MedianPruner(n_warmup_steps=10), direction="maximize",
        study_name="mnist-tf", storage=storage_name,load_if_exists=True
    )
    study.optimize(objective, n_trials=20)
    
    best_params = study.best_params
    best_value = study.best_value
    print("\n\nbest_value = "+str(best_value))
    print("best_params:")
    print(best_params)

打印结果如下

best_value = 0.9079999923706055
best_params:
{'dropout_0': 0.22384888955958546, 'learning_rate': 0.0024974162743369756, 'n_layers': 1, 'n_units_0': 59}

三,optuna对多模型加权融合范例

多模型加权融合是一个常见的提升机器学习效果的方案。

但是各个模型的权重如何确定呢?

有些方案是使用线性回归或者逻辑回归模型进行学习,这种方案一般叫做stacking ensemble,但是这种方案一般是对可微的Loss进行优化的,无法直接对auc,acc等不可微的评价指标进行优化。

还有一些方案叫做greedy ensemble,可以直接对auc,acc等不可微的评价指标进行优化,是一种贪心的也是非常高效的一种方案。大家感兴趣的话可以去了解一下它的细节,但是因为是greedy的方式,有可能陷入局部最优值。

由于optuna是一个强大的不可微问题调优工具,我们可以使用它来寻找模型融合的权重,直接对auc,acc等不可微的评价指标进行优化,并且原则上说,不会陷入局部最优解,能够获得比greedy ensemble更好的融合权重。

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

from sklearn.neural_network import MLPClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC 

from sklearn.metrics import roc_auc_score 

# 一,准备数据
data,target = make_classification(n_samples=3000,n_features=20,
        n_informative=12,n_redundant=4,n_repeated=0,n_classes=2,
        n_clusters_per_class=4)

x_train_val, x_test, y_train_val, y_test = train_test_split(data, target)
x_train, x_valid, y_train, y_valid = train_test_split(x_train_val, y_train_val)
# 二,训练3个基础模型

tree = DecisionTreeClassifier()
mlp = MLPClassifier()
svc = SVC(probability=True) 

mlp.fit(x_train,y_train)
tree.fit(x_train,y_train)
svc.fit(x_train,y_train)
# 三,评估模型效果

def get_val_auc(model):
    probs = model.predict_proba(x_valid)[:,1]
    val_auc = roc_auc_score(y_valid,probs)
    return val_auc

def get_test_auc(model):
    probs = model.predict_proba(x_test)[:,1]
    val_auc = roc_auc_score(y_test,probs)
    return val_auc

print("mlp_score:",get_test_auc(mlp))
print("tree_score:",get_test_auc(tree))
print("svc_score:",get_test_auc(svc))
# 四, optuna搜索权重

import optuna 
preds_val = {name:(eval(name)).predict_proba(x_valid)[:,1] for name in ['mlp','tree','svc']}

def objective(trial):
    weights = {name:trial.suggest_int(name, 1, 100) for name in ['mlp','tree','svc']}
    probs = sum([weights[name]*preds_val[name] for name in ['mlp','tree','svc']])/sum(
        [weights[name] for name in ['mlp','tree','svc']])
    
    val_auc = roc_auc_score(y_valid,probs)
    trial.report(val_auc, 0)
    return val_auc

storage_name = "sqlite:///optuna.db"
study = optuna.create_study(
    direction="maximize",
    study_name="optuna_ensemble", storage=storage_name,load_if_exists=True
)
study.optimize(objective, n_trials=300, timeout=600)

best_params = study.best_params
best_value = study.best_value
print("\n\nbest_value = "+str(best_value))
print("best_params:")
print(best_params)
best_value = 0.9763214030683023
best_params:
{'mlp': 93, 'svc': 81, 'tree': 1}
# 五, 评估模型融合效果

preds_test = {name:(eval(name)).predict_proba(x_test)[:,1] for name in ['mlp','tree','svc']}
def test_score(weights):
    probs = sum([weights[name]*preds_test[name] for name in ['mlp','tree','svc']])/sum(
        [weights[name] for name in ['mlp','tree','svc']])
    test_auc = roc_auc_score(y_test,probs)
    return test_auc
print('optuna_ensemble_score:',test_score(best_params))
optuna_ensemble_score: 0.955444558287796

比单模型的最优值svc的得分(0.9501)有些许提升。

以下的范例为基础特性范例讲解,方便大家了解optuna的各种特性以及API使用方法。

四,单参数空间搜索范例

Optuna支持的调参算法主要包括以下这些:

optuna.samplers.GridSampler(网格搜索采样)
optuna.samplers.RandomSampler(随机搜索采样)
optuna.samplers.TPESampler(贝叶斯优化采样)
optuna.samplers.NSGAIISampler(遗传算法采样)
optuna.samplers.CmaEsSampler(协方差矩阵自适应演化策略采样,非常先进的优化算法)

此外,还可以用以下方法将部分超参固定,仅对其它一些参数进行超参优化。

optuna.samplers.PartialFixedSampler(部分参数固定采样算法)

可以在optuna.create_study时候用sampler参数指定。

如果不指定的话,一般在单目标优化算法中,使用的是optuna.samplers.TPESampler调参算法。

from IPython.display import display 
import optuna
import numpy as np 
import pandas as pd 
import plotly.graph_objs as go 
import plotly.express as px 


optuna.logging.set_verbosity(optuna.logging.WARNING)

# 1, 定义目标函数
def objective(trial:optuna.trial.Trial):
    x = trial.suggest_float("x", -10, 10)
    return (x - 2) ** 2

# 2, 执行搜索过程
study = optuna.create_study(
    sampler=optuna.samplers.CmaEsSampler(),
    direction = "minimize",
    study_name = "simple_task")

study.optimize(objective, n_trials=1000,show_progress_bar = True)

# 3, 获取最优超参
best_params = study.best_params
best_value = study.best_value
print("\n\nbest_value = "+str(best_value))
print("best_params:")
print(best_params)

# 4, 绘制搜索过程

dftrials = study.trials_dataframe()[["number","value"]]
losses = dftrials["value"].tolist()

minlosses = [np.min(losses[0:i+1]) for i in range(len(losses))] 
steps = range(len(losses))

dflog = pd.DataFrame({"steps":steps,"losses":losses,"minlosses":minlosses})
fig = px.scatter(data_frame=dflog,x = "steps",y = "losses", size_max = 500,log_y=True)
fig.update_traces(marker = dict(size = 20, color = "rgba(0,0,255,0.4)"),name = "all",showlegend = True)
fig.add_traces(go.Scatter(x=list(steps), y=minlosses, name = "best", showlegend=True)) 
fig.update_layout(legend=dict(orientation="v"))
fig.show()
best_value = 0.0013535850035239266
best_params:
{'x': 2.0367910995150176}
 

86f8c2f90a3841386e79f1dd69686f95.png

 

五,网格参数空间搜索范例

多个参数可以用字典表述成网格参数空间形式。

optuna支持各种各样的输入参数类型。常见的有以下一些

trail = optuna.trial.Trial
trail.suggest_categorical
trail.suggest_discrete_uniform
trail.suggest_float
trail.suggest_int
trail.suggest_loguniform
from IPython.display import display 
import numpy as np
import matplotlib.pyplot as plt 
import optuna 

import plotly.graph_objs as go 
import plotly.express as px 


optuna.logging.set_verbosity(optuna.logging.WARNING)

# 1, 定义目标函数
def objective(trial:optuna.trial.Trial):
    x = trial.suggest_float("x", -1, 1)
    f = trial.suggest_categorical("f",['sin','sinh','cos','cosh'])
    dic = {'sin':np.sin,'cos':np.cos,'sinh':np.sinh,'cosh':np.cosh}
    fn = dic[f]
    return fn(x)


# 2, 执行搜索过程
study = optuna.create_study(
    sampler=optuna.samplers.TPESampler(seed=123),
    direction = "minimize",
    study_name = "grid_task")

study.optimize(objective, n_trials=100,show_progress_bar = True)

# 3, 获取最优超参
best_params = study.best_params
best_value = study.best_value
print("\n\nbest_value = "+str(best_value))
print("best_params:")
print(best_params)

# 4, 绘制搜索过程
dftrials = study.trials_dataframe()[["number","value"]]
display(dftrials)
losses = dftrials["value"].tolist()

minlosses = [np.min(losses[0:i+1]) for i in range(len(losses))] 
steps = range(len(losses))

dflog = pd.DataFrame({"steps":steps,"losses":losses,"minlosses":minlosses})
fig = px.scatter(data_frame=dflog,x = "steps",y = "losses", size_max = 500)
fig.update_traces(marker = dict(size = 20, color = "rgba(0,0,255,0.4)"),name = "all",showlegend = True)
fig.add_traces(go.Scatter(x=list(steps), y=minlosses, name = "best", showlegend=True)) 
fig.update_layout(legend=dict(orientation="v"))
fig.show()

六,断点续搜范例

有时候超参搜索过程中有可能中间机器会死掉,可以使用sqlite/mysql等存储方式存储搜索结果到数据库文件。

这样便可以读取历史搜索结果,继续搜索。

import sys
import optuna
optuna.logging.set_verbosity(optuna.logging.ERROR)

# 1, 定义目标函数
def objective(trial):
    x = trial.suggest_float("x", -10, 10)
    return (x - 2) ** 2


# 2, 执行搜索过程
study_name = "example-study"  
storage_name = "sqlite:///{}.db".format(study_name)

#period0
study0 = optuna.create_study(study_name=study_name, storage=storage_name, load_if_exists=True)
study0.optimize(objective, n_trials=10)

#period1
study1 = optuna.create_study(study_name=study_name, storage=storage_name, load_if_exists=True)
study1.optimize(objective, n_trials=10)

#period2
study2 = optuna.create_study(study_name=study_name, storage=storage_name, load_if_exists=True)
dftrials = study2.trials_dataframe(attrs=("number", "value", "params", "state"))

# 3, 获取最优超参
best_params = study2.best_params
best_value = study2.best_value
print("\n\nbest_value = "+str(best_value))
print("best_params:")
print(best_params)

display(dftrials)


# 4, 绘制搜索过程
fig = optuna.visualization.plot_optimization_history(study2)
#fig.layout.yaxis.type = 'log'
fig.update_layout({"yaxis.type":"log"})

七,剪枝策略范例

optuna支持多种剪枝策略,如果某个超参采样点返回的中间结果和之前采样点相比表现得没有希望,optuna可以提前结束这个采样点的训练,从而节约时间。

  • optuna.pruners.HyperbandPruner: pruner refers to http://www.jmlr.org/papers/volume18/16-558/16-558.pdf

  • optuna.pruners.MedianPruner: Prune if the trial's best intermediate result is worse than median of intermediate results of previous trials at the same step.

  • optuna.pruners.ThresholdPruner: Pruner to detect outlying metrics of the trials

import optuna
from optuna.visualization import plot_optimization_history

from sklearn.datasets import load_iris 
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
optuna.logging.set_verbosity(optuna.logging.ERROR)

def objective(trial):

    
    iris = load_iris() 
    data,target = iris["data"],iris["target"]

    x_train, x_valid, y_train, y_valid = train_test_split(data, target)
    classes = list(set(target))

    clf = MLPClassifier(
        hidden_layer_sizes=tuple(
            [trial.suggest_int("n_units_l{}".format(i), 32, 64) for i in range(3)]
        ),
        learning_rate_init=trial.suggest_float("lr_init", 1e-5, 1e-1, log=True),
    )

    for step in range(100):
        clf.partial_fit(x_train, y_train, classes=classes)
        value = clf.score(x_valid, y_valid)

        # Report intermediate objective value.
        trial.report(value, step)

        # Handle pruning based on the intermediate value.
        if trial.should_prune():
            raise optuna.TrialPruned()

    return value


if __name__ == "__main__":

    study = optuna.create_study(direction="maximize", pruner=optuna.pruners.MedianPruner())
    study.optimize(objective, n_trials=100, timeout=600)
    plot_optimization_history(study).show()

八,各种调参可视化函数范例

import optuna
from optuna.visualization import plot_contour
from optuna.visualization import plot_intermediate_values
from optuna.visualization import plot_optimization_history
from optuna.visualization import plot_parallel_coordinate
from optuna.visualization import plot_param_importances
from optuna.visualization import plot_slice

from sklearn.datasets import load_iris 
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
optuna.logging.set_verbosity(optuna.logging.ERROR)

def objective(trial):

    
    iris = load_iris() 
    data,target = iris["data"],iris["target"]

    x_train, x_valid, y_train, y_valid = train_test_split(data, target)
    classes = list(set(target))

    clf = MLPClassifier(
        hidden_layer_sizes=tuple(
            [trial.suggest_int("n_units_l{}".format(i), 32, 64) for i in range(3)]
        ),
        learning_rate_init=trial.suggest_float("lr_init", 1e-5, 1e-1, log=True),
    )

    for step in range(100):
        clf.partial_fit(x_train, y_train, classes=classes)
        value = clf.score(x_valid, y_valid)

        # Report intermediate objective value.
        trial.report(value, step)

        # Handle pruning based on the intermediate value.
        if trial.should_prune():
            raise optuna.TrialPruned()

    return value


if __name__ == "__main__":

    study = optuna.create_study(direction="maximize", pruner=optuna.pruners.MedianPruner())
    study.optimize(objective, n_trials=100, timeout=600)

    # Visualize the optimization history.
    plot_optimization_history(study).show()

    # Visualize the learning curves of the trials.
    plot_intermediate_values(study).show()

    # Visualize high-dimensional parameter relationships.
    plot_parallel_coordinate(study).show()

    # Select parameters to visualize.
    plot_parallel_coordinate(study, params=["lr_init", "n_units_l0"]).show()

    # Visualize hyperparameter relationships.
    plot_contour(study).show()

    # Select parameters to visualize.
    plot_contour(study, params=["n_units_l0", "n_units_l1"]).show()

    # Visualize individual hyperparameters.
    plot_slice(study).show()

    # Select parameter
    # Visualize parameter importances.
    plot_param_importances(study).show()

九,手动添加超参数采样点范例

有时候,我们在使用特定的采样算法之前,想尝试一些人工指定的超参采样点,在Optuna中我们可以用

study.enqueue_trial 将这些人工指定超参采样点推入测试队列。

另外,如果我们已经手动执行了一些超参采样点,并获得了结果,我们可以用 study.add_trail的方法

将这些结果添加到已评估的超参采样点列表中。后续的超参数采样将会考虑这些采样点。

1,指定手工采样点

import lightgbm as lgb
import numpy as np
import sklearn.datasets
import sklearn.metrics
from sklearn.model_selection import train_test_split

import optuna

def objective(trial):
    data, target = sklearn.datasets.load_breast_cancer(return_X_y=True)
    train_x, valid_x, train_y, valid_y = train_test_split(data, target, test_size=0.25)
    dtrain = lgb.Dataset(train_x, label=train_y)
    dvalid = lgb.Dataset(valid_x, label=valid_y)

    param = {
        "objective": "binary",
        "metric": "auc",
        "verbosity": -1,
        "boosting_type": "gbdt",
        "bagging_fraction": min(trial.suggest_float("bagging_fraction", 0.4, 1.0 + 1e-12), 1),
        "bagging_freq": trial.suggest_int("bagging_freq", 0, 7),
        "min_child_samples": trial.suggest_int("min_child_samples", 5, 100),
    }

    # Add a callback for pruning.
    pruning_callback = optuna.integration.LightGBMPruningCallback(trial, "auc")
    gbm = lgb.train(
        param, dtrain, valid_sets=[dvalid], verbose_eval=False, callbacks=[pruning_callback]
    )

    preds = gbm.predict(valid_x)
    pred_labels = np.rint(preds)
    accuracy = sklearn.metrics.accuracy_score(valid_y, pred_labels)
    return accuracy

study = optuna.create_study(direction="maximize", pruner=optuna.pruners.MedianPruner())

study.enqueue_trial(
    {
        "bagging_fraction": 1.0,
        "bagging_freq": 0,
        "min_child_samples": 20,
    }
)

study.enqueue_trial(
    {
        "bagging_fraction": 0.75,
        "bagging_freq": 5,
        "min_child_samples": 20,
    }
)

import logging
import sys

# Add stream handler of stdout to show the messages to see Optuna works expectedly.
optuna.logging.get_logger("optuna").addHandler(logging.StreamHandler(sys.stdout))
study.optimize(objective, n_trials=100, timeout=600)

2,添加已评估采样点

import lightgbm as lgb
import numpy as np
import sklearn.datasets
import sklearn.metrics
from sklearn.model_selection import train_test_split

import optuna

def objective(trial):
    data, target = sklearn.datasets.load_breast_cancer(return_X_y=True)
    train_x, valid_x, train_y, valid_y = train_test_split(data, target, test_size=0.25)
    dtrain = lgb.Dataset(train_x, label=train_y)
    dvalid = lgb.Dataset(valid_x, label=valid_y)

    param = {
        "objective": "binary",
        "metric": "auc",
        "verbosity": -1,
        "boosting_type": "gbdt",
        "bagging_fraction": min(trial.suggest_float("bagging_fraction", 0.4, 1.0 + 1e-12), 1),
        "bagging_freq": trial.suggest_int("bagging_freq", 0, 7),
        "min_child_samples": trial.suggest_int("min_child_samples", 5, 100),
    }

    # Add a callback for pruning.
    pruning_callback = optuna.integration.LightGBMPruningCallback(trial, "auc")
    gbm = lgb.train(
        param, dtrain, valid_sets=[dvalid], verbose_eval=False, callbacks=[pruning_callback]
    )

    preds = gbm.predict(valid_x)
    pred_labels = np.rint(preds)
    accuracy = sklearn.metrics.accuracy_score(valid_y, pred_labels)
    return accuracy

study = optuna.create_study(direction="maximize", pruner=optuna.pruners.MedianPruner())
study.add_trial(
    optuna.trial.create_trial(
        params={
            "bagging_fraction": 1.0,
            "bagging_freq": 0,
            "min_child_samples": 20,
        },
        distributions={
            "bagging_fraction": optuna.distributions.UniformDistribution(0.4, 1.0 + 1e-12),
            "bagging_freq": optuna.distributions.IntUniformDistribution(0, 7),
            "min_child_samples": optuna.distributions.IntUniformDistribution(5, 100),
        },
        value=0.94,
    )
)
study.add_trial(
    optuna.trial.create_trial(
        params={
            "bagging_fraction": 0.75,
            "bagging_freq": 5,
            "min_child_samples": 20,
        },
        distributions={
            "bagging_fraction": optuna.distributions.UniformDistribution(0.4, 1.0 + 1e-12),
            "bagging_freq": optuna.distributions.IntUniformDistribution(0, 7),
            "min_child_samples": optuna.distributions.IntUniformDistribution(5, 100),
        },
        value=0.95,
    )
)
study.optimize(objective, n_trials=100, timeout=600)

1ae76425b00ae22db7aad0c819937836.png

超参数调优框架optuna(可配合pytorch) 全自动超参数调优框架——optuna 阅读详情

相关推荐

【超参数调优】Optuna

Optuna 允许用户灵活地定义超参数的搜索空间,包括连续型、离散型和条件型超参数。目标函数需要接受一个对象,并返回一个需要最小化(或最大化)的值。# 加载数据集# 定义目标函数# 定义超参数搜索空间param = {# 创建 LightGBM 数据集# 训练模型# 预测y_pred = [list(x).index(max(x)) for x in y_pred] # 获取每行最大值的索引作为预测类别# 计算准确率# 创建研究对象。

藓类少女的博客 5642

Optuna:高效易用的超参优化利器

Optuna是一个用于超参数优化的Python库,可以帮助我们自动化地选择最优的超参数组合,从而提高机器学习模型的性能。Optuna使用贝叶斯优化算法来搜索超参数空间,可以支持大部分机器学习框架,如TensorFlow、PyTorch、scikit-learn等。

酒酿小圆子呀~ 4364

Python数据科学生产级工具链:Polars/Vaex/Optuna/Darts/Datasets实战选型指南

在现代数据科学中,高效处理大规模、多源异构、高时效性数据已成为核心能力。传统工具如Pandas和GridSearchCV在内存占用、执行效率与建模灵活性上已显疲态,难以支撑金融风控、IoT时序诊断、电商用户行为分析等真实生产场景。基于Apache Arrow内存模型、延迟计算、顺序模型优化(SMBO)和声明式数据抽象等关键技术原理,新一代库正重塑数据流水线——Polars以Rust引擎实现列式计算跃迁,Vaex通过内存映射与WebGL可视化突破单机极限,Optuna借助TPE算法与Pruner机制让超参搜索

android_mylove的专栏 401

Optuna:带仪表盘的可视化的超参数优化

熟悉寻找最优超参数的一个可视化工具

深度学习领域优质创作者,优快云博客专家 4803

超参数调优不是调参,是带约束的工程决策系统

超参数调优本质上是机器学习模型在真实生产环境中的多目标优化问题,其核心原理在于将业务指标(如AUC、F1)、资源约束(延迟、内存、显存)与稳定性要求(验证波动、收敛鲁棒性)统一建模。区别于传统网格搜索的暴力穷举,现代方法如贝叶斯优化、Hyperband和早停机制,通过概率建模、预算分配与动态剪枝,在有限算力下逼近帕累托最优解。该技术价值在于支撑MLOps闭环——让模型迭代可度量、可复现、可审计。典型应用场景涵盖电商CTR预估、医疗影像轻量化部署、金融风控可解释建模等对延迟敏感、数据偏斜、更新频繁的工业级任务

anjueci1221的博客 320

超参数优化实战指南:从贝叶斯优化到工业级HPO工程落地

超参数优化(HPO)是机器学习模型从‘能用’迈向‘可交付’的关键工程环节,其本质是在高维、非凸、计算昂贵的黑箱函数中,以有限资源定位帕累托最优解。不同于模型参数的自动学习,超参数控制整个训练过程,直接影响收敛性、泛化能力与线上SLO。主流方法如网格搜索易陷维度灾难,随机搜索依赖先验分布,而贝叶斯优化(如Optuna)通过代理模型与期望提升策略实现高效探索;进化算法(如TPOT)则适用于pipeline级自动发现。在金融科技、医疗AI等强约束场景中,HPO必须与早停机制、学习率调度、计算资源约束深度耦合,才能

weixin_34166472的博客 334

Optuna可视化调参魔法指南:PyTorch模型超参数优化终极教程

Optuna是一款强大的开源超参数优化框架,专门为机器学习模型调参设计。本教程将带你深入了解如何使用Optuna进行PyTorch模型调参,并通过可视化工具实时监控优化过程。😊 ## 什么是Optuna调参工具? Optuna是一个基于Python的超参数优化框架,GitHub star数量超过7k,是目前最受欢迎的调参工具之一。它采用先进的优化算法如贝叶斯优化和遗传算法采样,能够在几十上百

gitblog_00300的博客 591

AI调参实战:40分钟实现PID控制器从震荡到稳定

PID控制器作为工业自动化的核心算法,其参数整定长期依赖工程师经验,过程繁琐且难以复现。其原理是通过比例、积分、微分三个环节的协同,实现对系统误差的快速、精准调节。传统手动调参方法效率低下,而AI技术的引入,特别是强化学习和贝叶斯优化等算法,将参数整定转化为一个自动化寻优问题,显著提升了调参效率和结果的一致性。这项技术的核心价值在于,它能够基于明确的性能指标(如积分误差、超调量),在仿真环境中自动搜索最优参数组合,为电机控制、温控系统等经典场景提供高质量的初始参数方案。本文即以一个直流电机控制仿真为例,详细

weixin_33923762的博客 452

PyTorch超参优化实战:用Optuna实现智能自适应调参

超参数优化是深度学习模型落地的关键瓶颈,其本质是在高维非凸空间中寻找泛化性能最优的配置组合。传统网格搜索与随机搜索缺乏记忆性与自适应能力,难以应对learning_rate、weight_decay等参数的强耦合与对数敏感特性。基于贝叶斯优化的Optuna通过trial动态采样、早停剪枝(pruning)和代码即搜索空间(Code-as-Space)设计,显著提升PyTorch模型调参效率与可靠性。它支持多指标监控、跨会话增量优化及可视化归因分析,已在CIFAR-10、ViT等典型任务中验证可减少50%以上

weixin_30617695的博客 386

博途的HMI(触摸屏)的应用

触摸屏(HMI):用于控制PLC,可认为是小型上位机(用于控制PLC的都可认为是上位机)上位机(PC Station):将触摸屏升级为电脑----工控机(工业控制的机器)用博途编写西门子的触摸屏和上位机。

王阿妹小天才的博客 2677

MATLAB算法实战应用案例精讲-【数模应用】装箱问题

装箱问题可以根据不同的维度进行分类。以下是一些常见的装箱问题二维装箱问题:二维装箱问题假设所有物品都是平面上的矩形,并且需要将它们放入平面上的容器中。这个问题的目标是找到一种装箱方案,使得物品不重叠并占据的总面积最小。三维装箱问题:三维装箱问题考虑到物品可以具有高度,并且需要将它们放入三维容器(如箱子或货柜)中。目标是找到一种装箱方案,使得物品不重叠且总体积最小。多维装箱问题:多维装箱问题是指在更高维度空间中进行装箱的问题。除了长度和宽度之外,物品可能具有其他属性,如高度、重量、形状等。

qq_36130719的博客 1572

Optuna:下一代超参数调优利器,用起来像魔法一样丝滑!

Optuna是一个自动化超参数优化框架,具有高效、灵活、可扩展等优点。分布式计算早停机制(Pruning)动态空间搜索(search space 可以随 trial 动态变化)集成可视化工具与 PyTorch、LightGBM、XGBoost、CatBoost、Scikit-learn 等无缝集成优点说明易用性高接口简洁,文档清晰性能好默认优化器效果佳灵活强大search space 可动态定义可视化完善提供交互式图表拓展性好支持分布式、集群、深度学习。

萧鼎的博客 1790

[Dify实战] 在 Dify 官网环境使用 File Translator 插件实现 Office 文档翻译(支持 DOCX/XLSX/PPTX)

摘要:Dify平台的FileTranslator插件可实现Office文档一键翻译,保留原格式和结构。该插件支持Word、Excel、PPT等文件格式,无需额外密钥,直接复用Dify配置的大模型。安装后,用户可在Workflow中调用插件,设置目标语言等参数完成翻译。输出文件自动命名,保留原格式。适用于跨国协作、海外营销等场景,显著提升多语言办公效率。该插件简化了文档翻译流程,是企业用户和开发者的实用工具。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 544

从原理到实战:用Optuna解锁超参数调优新姿势

本文深入解析Optuna在超参数搜索中的高效应用,从原理到实战全面展示其智能优化能力。通过TPE算法和早停策略,Optuna能显著提升模型调参效率,如在电商预测项目中3天内将AUC从0.81提升至0.85。文章还提供CNN模型调优的代码示例和分布式优化技巧,帮助开发者快速掌握这一超参数调优利器。

weixin_33712987的博客 328

audio语音相关的基础知识-VAD,ASR,AEC,AGC,BF等

有音素之间的间隙,也有静音和语音本身的间隙,为了对数据从时间上进行相对的校准,语音端点检测技术就应运而生了,因此端点检测技术可以决定这种校准的相对精度,使得同一内容的特征更趋于相同,当然,一般情况下是不可能完全相同的。盲源分离的目的是求得源信号的最佳估计,盲辨识的目的是求得传输通道的。这个技术的主要任务是从带有噪声的语音中准确的定位出语音的开始和结束点,因为语音中含有很长的静音,也就是把静音和实际语音分离开来,因为是语音数据的原始处理,所以VAD是语音信号处理过程的关键技术之一。呈现出与会者清晰的声音。

u013250861的博客 1034

K8S部署Java项目 pod的logs报错为:Error: Unable to access jarfile app.jar

每个人都有惰性,但不断学习是好好生活的根本,共勉!

感谢阅读 2600

别再手动调参了!用Optuna+仪表盘,5分钟搞定SVM鸢尾花分类超参数优化

本文介绍如何利用Optuna和可视化仪表盘快速优化SVM鸢尾花分类的超参数,告别传统手动调参的低效模式。通过智能优化算法和实时监控工具,5分钟内即可找到最优参数组合,提升模型性能15-30%。文章详细讲解了环境搭建、参数优化流水线和高级调优策略,适合机器学习从业者快速上手。

weixin_30613343的博客 383

一文掌握DrissionPage的详细使用

是一个基于 Python 的网页自动化工具,主要用于网页数据的抓取、自动化操作和测试。它结合了 Selenium 和 Requests 的优点,提供了更简洁、高效的 API,适用于各种网页自动化任务。DrissionPage 是一个功能强大且易于使用的网页自动化工具,适用于各种网页自动化任务。希望本文的 DrissionPage 的基本使用方法和一些高级功能能够帮助到你。

数据知道的博客 1万+

贝叶斯优化实战:用概率建模替代暴力调参

超参数调优是机器学习落地的关键瓶颈,传统网格搜索与随机搜索在高成本、非线性、噪声目标函数场景下效率低下。贝叶斯优化作为一种序贯决策框架,通过代理模型(如高斯过程)建模目标函数的概率分布,并结合采集函数(如EI、UCB)智能选择最有信息量的评估点,实现‘少试几次、多学一点’的工程化智能试错。它天然支持连续/离散/条件参数空间,可量化不确定性,适配金融风控、工业预测、电商排序等真实业务指标(如F1、AUC)。本文聚焦贝叶斯优化在生产环境中的可复现、可解释、可干预落地路径,覆盖Optuna实操、失败防护、人工协同

wgyyh 406

Android功耗系列专题分析之四:待机概率性功耗高的失效分析

本文分析了Android设备待机功耗异常高的问题。通过日志发现系统休眠失败,原因是PowerManagerService.Display唤醒锁未被释放。进一步排查发现,指纹解锁功能在灭屏时未正确释放屏幕锁定,导致DisplayReady状态异常。解决方案是将指纹功能的背光控制与DisplayReady状态控制分离,使用两个变量独立管理。经验表明,快速定位问题比解决问题更重要,修改原生流程时需谨慎评估风险。

451

机器人视觉联动精度优化:从±2mm到±0.02mm,产线级手眼标定全实战

2025年我接东莞长安Type-C接口分拣项目的时候,就是栽在了手眼标定上:实验室里标定完精度±0.5mm,一到产线直接掉到±2mm,机器人10次有3次抓不住,2000多件Type-C接口直接报废,还撞坏了2套汇川SCARA机器人的吸盘,本来45天的工期拖了3个月,不仅没赚到钱,还倒贴了几万块。手眼标定从来不是简单的跑个demo、算个矩阵就完事了,它是一个系统工程:从硬件选型、安装固定、相机标定、标定流程、算法优化、环境控制、重复验证,每一个环节都会影响最终的联动精度。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 387

【Python数据分析300个实用技巧】290.效率与技巧合集之数据科学必学:用Python征服一切不可能!

从今天起,扔掉那些低效的for循环,忘记手动调参的苦日子。记住:真正的数据高手不是调包侠,而是能用自动化武器武装自己的战术大师。当你掌握这些技巧,会发现曾经需要通宵跑的任务,现在喝杯咖啡的时间就搞定了。编程就像打铁,工具趁手才能事半功倍。保持对效率的极致追求,但别忘记——最好的优化,永远来自对业务逻辑的深刻理解。愿你在数据科学的征途上,既有屠龙技,也有玲珑心。代码之路漫漫,咱们山顶见!

1033

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

贝叶斯优化调参实战:为什么我的XGBoost模型用它比网格搜索快10倍?

本文详细介绍了贝叶斯优化在XGBoost模型调参中的高效应用,相比传统网格搜索可提升10倍速度。通过实战案例和Optuna库的配置演示,帮助数据科学家快速掌握这一先进调参技术,优化模型性能并节省计算资源。

weixin_30325487的博客 239

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

7个AI工程框架实战指南:从数据清洗到模型监控全链路提效

AI工程化不是算法调优,而是构建可复用、可编排、可验证的标准化能力单元。现代机器学习项目中,90%的开发工作本质是框架能力的组合与编排——Dask解决TB级数据IO瓶颈,Featuretools实现特征工程自动化,PyTorch Lightning剥离训练胶水代码,Optuna以贝叶斯优化替代暴力调参,BentoML提供声明式模型服务封装,Weights & Biases构建实验元数据操作系统,Evidently则作为生产环境的数据健康CT扫描仪。这些工具共同构成AI落地的‘确定性流水线’,将POC周期从数

weixin_34341117的博客 381

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

XGBoost调参实战:从核心原理到生产部署的完整指南

梯度提升树(GBDT)是结构化数据建模的核心算法,通过迭代拟合残差逐步逼近目标。XGBoost在GBDT基础上引入二阶泰勒展开、正则化项和并行计算,显著提升了精度与效率。掌握其参数调优方法,能有效控制过拟合与欠拟合,在金融风控、用户流失预警等场景中实现稳定预测。本文围绕XGBoost的参数体系,结合scikit-learn生态,系统讲解从数据预处理、分阶段调参到模型评估与部署的工程实践,帮助读者构建可复用的高效建模流程。

weixin_34203832的博客 322

AI辅助PID调参实战:40分钟从振荡到稳定,告别传统试凑法

PID控制作为经典的控制算法,其核心在于通过比例、积分、微分三个环节的协同作用,实现对系统误差的快速响应、稳态误差消除和超调抑制。然而,面对复杂的非线性系统或难以精确建模的“黑箱”对象,传统基于经验公式或手动试凑的调参方法,往往陷入效率低下、难以平衡多性能指标的困境。其本质是一个在多维参数空间中的优化搜索问题。现代优化算法,如贝叶斯优化和遗传算法,为解决此类问题提供了高效工具。它们通过将工程师对系统性能(如超调量、调节时间)的定性要求,转化为可量化的目标函数(如ITAE),并自动执行迭代搜索,从而在嵌入式电

weixin_33910460的博客 383
上一篇: 炼丹5至7倍速,使用Mac M1 芯片加速pytorch完全指南
下一篇: 超越stacking, 使用optuna对多模型进行加权融合
算法美食屋
博客等级 码龄9年 2万+粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值