name: optuna-hyperparameter-tuner description: 用于自动化超参数优化的Optuna集成技能,具备高级搜索策略、剪枝、多目标优化和可视化能力。 allowed-tools: Read, Grep, Write, Bash, Edit, Glob, WebFetch
Optuna超参数调优器
使用Optuna进行超参数优化,支持高级搜索策略、剪枝和可视化。
概述
本技能提供使用Optuna(最先进的超参数优化框架)进行超参数优化的全面能力。它支持多种采样器、剪枝器、多目标优化以及与流行机器学习框架的集成。
能力
搜索策略
- 树结构Parzen估计器(TPE)- 默认,高效
- CMA-ES - 适用于连续参数
- 网格搜索 - 穷举
- 随机搜索 - 基线
- NSGAII - 多目标优化
- QMC(准蒙特卡洛)- 低差异采样
剪枝策略
- 中位数剪枝 - 提前停止表现不佳的试验
- Hyperband(ASHA)- 激进资源分配
- 百分位数剪枝 - 基于阈值
- 连续减半 - 高效资源利用
- Wilcoxon剪枝 - 统计比较
多目标优化
- 帕累托前沿优化
- 多目标函数
- 约束处理
- 权衡可视化
研究管理
- 研究持久化(SQLite、PostgreSQL、MySQL)
- 研究恢复
- 并行/分布式优化
- 试验重要性分析
- 参数关系分析
可视化
- 优化历史
- 参数重要性
- 平行坐标图
- 切片图
- 等高线图
先决条件
安装
pip install optuna>=3.0.0
可选依赖
# 数据库后端
pip install optuna[mysql] # MySQL支持
pip install optuna[postgresql] # PostgreSQL支持
# 可视化
pip install optuna-dashboard # Web仪表板
pip install plotly # 交互式图表
# 框架集成
pip install optuna-integration[sklearn]
pip install optuna-integration[pytorch]
pip install optuna-integration[tensorflow]
使用模式
基础优化
import optuna
def objective(trial):
# 建议超参数
learning_rate = trial.suggest_float('learning_rate', 1e-5, 1e-1, log=True)
n_estimators = trial.suggest_int('n_estimators', 50, 500)
max_depth = trial.suggest_int('max_depth', 3, 15)
subsample = trial.suggest_float('subsample', 0.5, 1.0)
# 训练模型
model = XGBClassifier(
learning_rate=learning_rate,
n_estimators=n_estimators,
max_depth=max_depth,
subsample=subsample,
random_state=42
)
# 交叉验证
score = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy').mean()
return score
# 创建研究
study = optuna.create_study(
direction='maximize',
study_name='xgboost-tuning',
storage='sqlite:///optuna.db',
load_if_exists=True
)
# 优化
study.optimize(objective, n_trials=100, timeout=3600)
# 最佳结果
print(f"最佳试验: {study.best_trial.number}")
print(f"最佳值: {study.best_value:.4f}")
print(f"最佳参数: {study.best_params}")
使用剪枝
import optuna
from optuna.pruners import MedianPruner
def objective_with_pruning(trial):
# 建议超参数
learning_rate = trial.suggest_float('learning_rate', 1e-5, 1e-1, log=True)
n_epochs = trial.suggest_int('n_epochs', 10, 100)
# 创建模型
model = create_model(learning_rate)
# 带剪枝的训练循环
for epoch in range(n_epochs):
train_loss = train_one_epoch(model)
val_accuracy = evaluate(model)
# 报告中间值
trial.report(val_accuracy, epoch)
# 如果无望则剪枝
if trial.should_prune():
raise optuna.TrialPruned()
return val_accuracy
# 创建带剪枝器的研究
study = optuna.create_study(
direction='maximize',
pruner=MedianPruner(n_startup_trials=5, n_warmup_steps=10)
)
study.optimize(objective_with_pruning, n_trials=100)
多目标优化
import optuna
def multi_objective(trial):
# 超参数
learning_rate = trial.suggest_float('learning_rate', 1e-5, 1e-1, log=True)
model_size = trial.suggest_categorical('model_size', ['small', 'medium', 'large'])
# 训练模型
model = create_model(learning_rate, model_size)
train(model)
# 多目标
accuracy = evaluate_accuracy(model)
inference_time = measure_inference_time(model)
return accuracy, inference_time # 最大化准确率,最小化时间
# 创建多目标研究
study = optuna.create_study(
directions=['maximize', 'minimize'],
study_name='pareto-optimization'
)
study.optimize(multi_objective, n_trials=100)
# 获取帕累托前沿
pareto_front = study.best_trials
for trial in pareto_front:
print(f"准确率: {trial.values[0]:.4f}, 时间: {trial.values[1]:.4f}")
Scikit-learn集成
import optuna
from optuna.integration import OptunaSearchCV
# 定义参数分布
param_distributions = {
'n_estimators': optuna.distributions.IntDistribution(50, 500),
'max_depth': optuna.distributions.IntDistribution(3, 15),
'learning_rate': optuna.distributions.FloatDistribution(1e-5, 1e-1, log=True),
'subsample': optuna.distributions.FloatDistribution(0.5, 1.0)
}
# 创建搜索
search = OptunaSearchCV(
XGBClassifier(random_state=42),
param_distributions,
n_trials=100,
cv=5,
scoring='accuracy',
study=study, # 可选:使用现有研究
n_jobs=-1
)
# 拟合
search.fit(X_train, y_train)
# 结果
print(f"最佳分数: {search.best_score_:.4f}")
print(f"最佳参数: {search.best_params_}")
PyTorch集成
import optuna
from optuna.integration import PyTorchLightningPruningCallback
def objective(trial):
# 超参数
lr = trial.suggest_float('lr', 1e-5, 1e-1, log=True)
hidden_size = trial.suggest_int('hidden_size', 32, 256)
dropout = trial.suggest_float('dropout', 0.1, 0.5)
# 创建模型
model = LightningModel(
hidden_size=hidden_size,
dropout=dropout,
lr=lr
)
# 创建带剪枝回调的训练器
trainer = pl.Trainer(
max_epochs=100,
callbacks=[
PyTorchLightningPruningCallback(trial, monitor='val_accuracy')
]
)
trainer.fit(model, train_loader, val_loader)
return trainer.callback_metrics['val_accuracy'].item()
分布式优化
import optuna
# 创建带数据库存储的共享研究
study = optuna.create_study(
study_name='distributed-study',
storage='postgresql://user:pass@host:5432/optuna',
direction='maximize',
load_if_exists=True
)
# 在多个工作节点上运行(每个工作节点运行此代码)
study.optimize(objective, n_trials=25) # 每个工作节点执行25个试验
# 结果自动聚合
print(f"总试验数: {len(study.trials)}")
与Babysitter SDK集成
任务定义示例
const hyperparameterTuningTask = defineTask({
name: 'optuna-hyperparameter-tuning',
description: '使用Optuna优化超参数',
inputs: {
studyName: { type: 'string', required: true },
direction: { type: 'string', default: 'maximize' },
nTrials: { type: 'number', default: 100 },
timeout: { type: 'number' },
parameterSpace: { type: 'object', required: true },
objectiveScript: { type: 'string', required: true },
sampler: { type: 'string', default: 'tpe' },
pruner: { type: 'string', default: 'median' }
},
outputs: {
bestValue: { type: 'number' },
bestParams: { type: 'object' },
nTrialsCompleted: { type: 'number' },
studyPath: { type: 'string' }
},
async run(inputs, taskCtx) {
return {
kind: 'skill',
title: `优化: ${inputs.studyName}`,
skill: {
name: 'optuna-hyperparameter-tuner',
context: {
operation: 'optimize',
studyName: inputs.studyName,
direction: inputs.direction,
nTrials: inputs.nTrials,
timeout: inputs.timeout,
parameterSpace: inputs.parameterSpace,
objectiveScript: inputs.objectiveScript,
sampler: inputs.sampler,
pruner: inputs.pruner
}
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/result.json`
}
};
}
});
MCP服务器集成
使用optuna-mcp(官方)
{
"mcpServers": {
"optuna": {
"command": "uvx",
"args": ["optuna-mcp"],
"env": {
"OPTUNA_STORAGE": "sqlite:///optuna.db"
}
}
}
}
可用的MCP工具
optuna_create_study- 创建新的优化研究optuna_get_study- 检索研究信息optuna_list_studies- 列出所有研究optuna_get_best_trial- 从研究中获取最佳试验optuna_get_trials- 列出研究中的试验optuna_visualize- 生成可视化optuna_suggest_params- 获取参数建议
采样器选择指南
| 采样器 | 使用场景 | 优点 | 缺点 |
|---|---|---|---|
TPESampler |
默认,大多数情况 | 高效,处理条件参数 | 可能错过全局最优 |
CmaEsSampler |
连续参数 | 适合相关参数 | 仅连续 |
GridSampler |
小型离散空间 | 穷举 | 指数复杂度 |
RandomSampler |
基线,并行 | 简单,易并行 | 效率低 |
NSGAIISampler |
多目标 | 帕累托优化 | 收敛较慢 |
QMCSampler |
空间探索 | 低差异 | 非自适应 |
剪枝器选择指南
| 剪枝器 | 使用场景 | 激进程度 |
|---|---|---|
MedianPruner |
默认,安全 | 中等 |
HyperbandPruner |
深度学习 | 激进 |
SuccessiveHalvingPruner |
资源高效 | 高 |
PercentilePruner |
可配置阈值 | 可变 |
NopPruner |
无需剪枝 | 无 |
可视化
生成可视化
import optuna.visualization as vis
# 优化历史
fig = vis.plot_optimization_history(study)
fig.write_html('optimization_history.html')
# 参数重要性
fig = vis.plot_param_importances(study)
fig.write_html('param_importance.html')
# 平行坐标
fig = vis.plot_parallel_coordinate(study)
fig.write_html('parallel_coordinate.html')
# 等高线图(2个参数)
fig = vis.plot_contour(study, params=['learning_rate', 'max_depth'])
fig.write_html('contour.html')
# 切片图
fig = vis.plot_slice(study)
fig.write_html('slice.html')
Optuna仪表板
# 启动仪表板
optuna-dashboard sqlite:///optuna.db
# 访问 http://localhost:8080
最佳实践
- 从TPE开始:除非有特定需求,否则使用默认采样器
- 使用剪枝:为迭代算法启用提前停止
- 持久化研究:使用数据库存储以实现可恢复性
- 记录中间值:启用剪枝和进度跟踪
- 设置超时:防止优化失控
- 分析重要性:关注高影响参数
- 使用条件参数:建模参数间的依赖关系