mcpField
H
hyperparameter-tuning

hyperparameter-tuning

github.com/seb1n数据与数据库232115 次安装11 周前更新
代码仓库

关于 hyperparameter-tuning

供 AI Agent 在计算预算内搜索机器学习模型的超参数配置,涵盖搜索空间设计、试验评估与剪枝,以及结果分析,帮助选择最终训练所用参数。

主要功能

  1. 01定义类别、整数和浮点搜索空间
  2. 02网格、随机、贝叶斯与 Hyperband 策略
  3. 03使用交叉验证或留出数据评估
  4. 04提前剪枝表现不佳的试验
  5. 05分析参数重要性及交互作用
  6. 06选定最终模型训练参数

适用场景

  1. 01根据目标指标调整模型超参数
  2. 02在试验预算内比较搜索策略
  3. 03提前终止低效试验以节省计算资源
  4. 04检查哪些参数影响模型表现

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill hyperparameter-tuning

安装后在 Claude Code 中输入/hyperparameter-tuning确认已加载。

详细介绍

超参数调优

此技能可让 AI Agent 系统地搜索机器学习模型的最优超参数配置。它涵盖定义搜索空间、选择搜索策略(网格搜索、随机搜索、贝叶斯优化、Hyperband)、使用交叉验证运行试验、应用提前停止以剪枝表现不佳的配置,以及分析结果以确定表现最佳的参数。Agent 会在探索和利用之间取得平衡,在给定的计算预算内找到效果出色的配置。

工作流

  1. 定义搜索空间: 指定每个超参数的类型(类别、整数、浮点数)和范围。对于跨越多个数量级的参数(例如,学习率范围为 1e-5 到 1e-1),使用对数均匀分布。将相关参数分组,并定义条件搜索空间,使某些参数仅在其他参数取特定值时适用。

  2. 选择搜索策略: 根据计算预算和搜索空间大小选择调优算法。网格搜索会穷举搜索,但仅适用于较小的搜索空间。随机搜索是一个强有力的基线,且可扩展性更好。对于评估成本高昂的情况,贝叶斯优化(树结构 Parzen 估计器或高斯过程)的样本效率最高。Hyperband 和 ASHA 将提前停止与随机搜索结合,适用于深度学习工作负载。

  3. 配置评估: 设置 k 折交叉验证(通常为 5 折),以便在中小型数据集上获得可靠的性能估计。对于大型数据集或计算成本高昂的模型,请使用单个留出验证集。定义要优化的目标指标(例如,验证集 F1、AUC-ROC、RMSE),并指定要最小化还是最大化该指标。

  4. 运行试验并进行剪枝: 执行搜索,并尽可能并行启动试验。启用剪枝,根据中间结果(例如,训练几个轮次后)提前终止表现不佳的试验,从而将计算资源用于更有希望的配置。

  5. 分析并选择结果: 检查优化历史,了解哪些超参数最重要(重要性分析)。通过等高线图或平行坐标图可视化参数之间的交互。选择最佳配置,并使用这些参数在完整训练集上重新训练最终模型。

支持的技术

  • 框架: Optuna、Ray Tune、scikit-learn GridSearchCV/RandomizedSearchCV、Hyperopt、Keras Tuner
  • 剪枝算法: 中位数剪枝、Hyperband(逐次减半)、ASHA
  • 贝叶斯方法: TPE(树结构 Parzen 估计器)、GP(高斯过程)、CMA-ES
  • 可视化: Optuna 可视化(plotly)、TensorBoard HParams、Weights & Biases Sweeps
  • 分布式执行: Ray Tune 集群、使用分布式存储(MySQL、PostgreSQL)的 Optuna

用法

向 Agent 提供模型、数据集、要调优的超参数及其范围、计算预算(试验次数或墙上时钟时间)和目标指标。Agent 将执行调优工作流,并返回最佳超参数配置及性能分析。

示例

示例 1:使用 Optuna Study 调优随机森林
import optuna
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
import numpy as np

X, y = load_breast_cancer(return_X_y=True)

def objective(trial):
    params = {
        "n_estimators": trial.suggest_int("n_estimators", 50, 500, step=50),
        "max_depth": trial.suggest_int("max_depth", 3, 30),
        "min_samples_split": trial.suggest_int("min_samples_split", 2, 20),
        "min_samples_leaf": trial.suggest_int("min_samples_leaf", 1, 10),
        "max_features": trial.suggest_categorical("max_features", ["sqrt", "log2", None]),
        "criterion": trial.suggest_categorical("criterion", ["gini", "entropy"]),
    }
    clf = RandomForestClassifier(**params, random_state=42, n_jobs=-1)
    scores = cross_val_score(clf, X, y, cv=5, scoring="f1")
    return scores.mean()

study = optuna.create_study(direction="maximize", sampler=optuna.samplers.TPESampler(seed=42))
study.optimize(objective, n_trials=100, show_progress_bar=True)

print(f"Best F1: {study.best_value:.4f}")
print(f"Best params: {study.best_params}")

# Visualization
fig_importance = optuna.visualization.plot_param_importances(study)
fig_history = optuna.visualization.plot_optimization_history(study)
fig_contour = optuna.visualization.plot_contour(study, params=["n_estimators", "max_depth"])
示例 2:使用 Ray Tune 和提前停止调优神经网络
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset, random_split
from ray import tune
from ray.tune.schedulers import ASHAScheduler
from ray.air import session
import numpy as np

def train_nn(config):
    X = torch.randn(2000, 20)
    y = (X[:, 0] + X[:, 1] * 2 > 0).long()
    dataset = TensorDataset(X, y)
    train_set, val_set = random_split(dataset, [1600, 400])
    train_loader = DataLoader(train_set, batch_size=config["batch_size"], shuffle=True)
    val_loader = DataLoader(val_set, batch_size=256)

    model = nn.Sequential(
        nn.Linear(20, config["hidden_size"]),
        nn.ReLU(),
        nn.Dropout(config["dropout"]),
        nn.Linear(config["hidden_size"], config["hidden_size"] // 2),
        nn.ReLU(),
        nn.Linear(config["hidden_size"] // 2, 2),
    )
    optimizer = torch.optim.Adam(model.parameters(), lr=config["lr"], weight_decay=config["weight_decay"])
    criterion = nn.CrossEntropyLoss()

    for epoch in range(50):
        model.train()
        for xb, yb in train_loader:
            loss = criterion(model(xb), yb)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        model.eval()
        correct, total = 0, 0
        with torch.no_grad():
            for xb, yb in val_loader:
                correct += (model(xb).argmax(1) == yb).sum().item()
                total += yb.size(0)
        session.report({"val_accuracy": correct / total})

search_space = {
    "hidden_size": tune.choice([64, 128, 256]),
    "lr": tune.loguniform(1e-4, 1e-1),
    "dropout": tune.uniform(0.1, 0.5),
    "batch_size": tune.choice([32, 64, 128]),
    "weight_decay": tune.loguniform(1e-5, 1e-2),
}

scheduler = ASHAScheduler(max_t=50, grace_period=5, reduction_factor=3)
result = tune.run(
    train_nn,
    config=search_space,
    num_samples=50,
    scheduler=scheduler,
    metric="val_accuracy",
    mode="max",
    resources_per_trial={"cpu": 2},
)

print(f"Best config: {result.best_config}")
print(f"Best val accuracy: {result.best_result['val_accuracy']:.4f}")

最佳实践

  • 对学习率、权重衰减和正则化强度使用对数均匀分布,因为最优值通常跨越多个数量级。
  • 从随机搜索开始,快速找出有希望的搜索空间区域,然后切换到贝叶斯优化进行精细探索。
  • 启用早停/剪枝,避免在训练数轮后明显表现不佳的配置上浪费计算资源。
  • 对于小型数据集(< 50k 个样本),始终使用交叉验证计算目标分数,以降低性能估计的方差,并避免对单次验证集划分过拟合。
  • 调优后运行超参数重要性分析,以了解哪些参数真正重要——通常只有 2~3 个参数决定了大部分性能差异。
  • 预先设定计算预算(试验次数、GPU 小时数或实际运行时间),并选择最能充分利用该预算的搜索策略。

边缘情况

  • 搜索空间巨大(> 10 个维度): 贝叶斯优化在高维情况下会退化。先使用随机搜索或 Hyperband 进行初步搜索,然后针对初步搜索识别出的最重要的 3~5 个参数运行贝叶斯优化。
  • 目标值存在噪声: 当交叉验证分数的方差很大时,单次试验结果并不可靠。增加 CV 折数,使用重复 k 折交叉验证,或在比较配置前对多个随机种子取平均值。
  • 超参数相关: 某些超参数会强烈相互影响(例如,学习率和批次大小)。使用 Optuna 的等高线图或 fANOVA 重要性分析来检测交互作用,并考虑一起调优相关参数组。
  • 评估开销大(每次试验 > 1 小时): 使用 Hyperband 等多保真度方法,先以较小预算训练,只将有希望的配置提升至完整训练。还可考虑使用代理基准或较小的代理数据集进行初步筛选。
  • 类别组合爆炸: 多个类别型超参数会导致组合数量激增时,使用条件搜索空间剪除无效组合,降低有效搜索空间的大小。

评论

支持 Markdown