资讯动态

Optuna 如何用 best_trial 复用优化得到的最佳超参数做进一步评估

发布时间:2026/9/15 22:18:32 来源:尧图企业网站定制
Optuna 如何用 best_trial 复用优化得到的最佳超参数做进一步评估【免费下载链接】optunaA hyperparameter optimization framework项目地址: https://gitcode.com/GitHub_Trending/op/optuna完成一轮超参数搜索后你经常需要拿着 Optuna 找到的最佳参数再做一次评估比如目标函数只返回了 accuracy但你还想看 recall、precision 和 f1或者搜索阶段为了省时间只用了部分数据调参结束后要用全量数据重新训练。官方教程 Re-use the best trial 给出的做法是不重新采样而是把study.best_trial直接传给目标函数让它用已存储的最佳参数值复算。这篇文章按该教程的完整示例走一遍这条路径并说明best_trial返回对象与普通 trial 的行为差异以及多目标、跨进程复用时该注意什么。准备条件示例代码依赖optuna和scikit-learnmake_classification、LogisticRegression、metrics、train_test_split。教程示例是一个二分类问题单个超参数C在[1e-7, 10.0]区间内按对数刻度搜索study 方向设为maximize优化 10 个 trial。主路径用 best_trial 复算目标函数第一步是正常优化并在结束后打印最佳值from sklearn import metrics from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split import optuna def objective(trial): X, y make_classification(n_features10, random_state1) X_train, X_test, y_train, y_test train_test_split(X, y, random_state1) C trial.suggest_float(C, 1e-7, 10.0, logTrue) clf LogisticRegression(CC) clf.fit(X_train, y_train) return clf.score(X_test, y_test) study optuna.create_study(directionmaximize) study.optimize(objective, n_trials10) print(study.best_trial.value) # Show the best value.接下来定义第二个目标函数detailed_objective。教程强调它要与objective共享大部分代码同样的数据切分和模型训练只是在最后多计算几个指标def detailed_objective(trial): # Use same code objective to reproduce the best model X, y make_classification(n_features10, random_state1) X_train, X_test, y_train, y_test train_test_split(X, y, random_state1) C trial.suggest_float(C, 1e-7, 10.0, logTrue) clf LogisticRegression(CC) clf.fit(X_train, y_train) # calculate more evaluation metrics pred clf.predict(X_test) acc metrics.accuracy_score(pred, y_test) recall metrics.recall_score(pred, y_test) precision metrics.precision_score(pred, y_test) f1 metrics.f1_score(pred, y_test) return acc, f1, recall, precision关键的一步把study.best_trial作为 trial 参数传进去detailed_objective(study.best_trial) # calculate acc, f1, recall, and precisiondetailed_objective返回一个四元组(acc, f1, recall, precision)这就是用最佳超参数C复算出来的评估结果。这里值得解释的是trial.suggest_float(...)在best_trial里不会采样新值。best_trial返回的是一个 FrozenTrial 对象它的文档明确说明will suggest the parameter values stored inparamsand will not sample values from any distributions即按 trial 已记录的参数取值逐个返回。所以第二个函数内部写的是同一个搜索区间实际生效的值只有一个study.best_trial里存的那个C。结果验证复算值应等于 best_valueFrozenTrial文档自带一个可执行的验证写法见 FrozenTrial 文档字符串用最优参数复算目标函数返回值应当等于 study 记录的最佳值def objective(trial): x trial.suggest_float(x, -1, 1) return x**2 study optuna.create_study() study.optimize(objective, n_trials3) assert objective(study.best_trial) study.best_value这条assert就是参数确实被复用了的判定依据。如果你复算得到的值和study.best_value对不上目标函数含随机性时尤其明显说明评估代码路径与原objective不一致而不是best_trial本身的问题。如果只需要参数字典而不需要重新训练可以直接取study.best_params等价于study.best_trial.paramsCLI 教程 和 用户自定义采样器教程 中都是这样打印最佳参数的print(fBest value: {study.best_value} (params: {study.best_params})\n)也可以用命令行查看最佳 trialoptuna best-trial。注意 CLI 实现 标注了这是实验性命令experimentalThe interface can change in the future脚本里依赖其输出格式时要留有余地。FrozenTrial 与普通 Trial 的三处行为差异把best_trial传给目标函数时有三个与 教程注释 和 FrozenTrial 文档 直接相关的行为差异需要知道pruning 不生效。FrozenTrial与普通Trial行为不同FrozenTrial.should_prune总是返回False。如果detailed_objective内部写了剪枝逻辑复算时不会触发。不能持久化写回。FrozenTrial不关联任何Study实例也没有对 storage 的引用因此无法通过这个对象对存储做持久修改文档举的例子是set_user_attr不会落库。对象本身是可变的。尽管名为 Frozen实例的内存属性可以被就地修改。文档给出的例子是复算一次objective(best_trial)后best_trial的user_attrs会被覆盖与复算前深拷贝的对象不再相等。也就是说study.best_trial返回的是深拷贝但复算过程中往 trial 里写的属性会改到这个副本上不影响 storage 中的记录也不应把副本当唯一事实来源。多目标、约束优化与异常Study.best_trial只适用于单目标优化见 属性定义study 是多目标时调用它会抛RuntimeError应改用Study.best_trials它返回 Pareto 前沿上一组FrozenTrial列表教程说明可以对列表中每个 trial 用与上文相同的方式复用还没有任何完成的 trial 时访问best_trial抛ValueError约束优化场景下best trial 是从满足全部约束所有约束值 0.0的 trial 中选出的。可选分支把 study 存到 RDB在另一个进程里复用上面的路径默认优化与复算在同一个进程内完成。如果你的评估必须在另一个会话/机器上跑可以先把 study 落到 RDB 后端如 SQLite之后按名字加载回来再取best_trial。RDB 教程 给出的完整做法study_name example-study # Unique identifier of the study. storage_name fsqlite:///{study_name}.db study optuna.create_study(study_namestudy_name, storagestorage_name) # ... study.optimize(objective, n_trials...) ... # 恢复已有 study 并继续 study optuna.create_study(study_namestudy_name, storagestorage_name, load_if_existsTrue) print(Best params: , study.best_params) print(Best value: , study.best_value) print(Best Trial: , study.best_trial)恢复后同样可以objective(study.best_trial)复算。该教程同时提醒storage 不保存sampler和pruner实例的状态如果复算还要继续调参且需要可复现的采样器需要用pickle另行保存并在加载时通过sampler传回。本文的纯复算场景不依赖采样器这条限制不影响best_trial本身。小结整条路径可以概括为study.optimize结束后取study.best_trial把它当 trial 参数传给一个与原objective同代码路径的新函数即可用最佳超参数复算用objective(study.best_trial) study.best_value这一文档给出的断言验证参数确实被复用。边界上记住三点多目标 study 要用best_trials列表逐个复用FrozenTrial上 pruning 恒为False且无法写回 storage跨进程复用需要先把 study 存到 RDB 后端。【免费下载链接】optunaA hyperparameter optimization framework项目地址: https://gitcode.com/GitHub_Trending/op/optuna创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价