ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Optuna 如何用 enqueue_trial 与 add_trial 指定先评估的超参数组合

Optuna 如何用 enqueue_trial 与 add_trial 指定先评估的超参数组合 Optuna 如何用 enqueue_trial 与 add_trial 指定先评估的超参数组合【免费下载链接】optunaA hyperparameter optimization framework项目地址: https://gitcode.com/GitHub_Trending/op/optuna在做超参数优化时通常有两类现实情况一是手里已经有一组“开箱即用”的参数比如初始学习率、默认配置还没评估过但希望 Optuna 先跑这些组合再自动搜索二是这些组合早就手动评估过了结果不理想想把已有结果登记进 Study让 Optuna 在后续采样时把它们考虑进去。Optuna 为这两种情况各提供一个接口Study.enqueue_trial把参数组合排入队列、由 Optuna 负责评估Study.add_trial把已评估完成的 trial含结果值直接注册进 Study。本文按这两条路径给出可执行的代码和验证方式。准备条件按 安装文档 的说法Optuna 支持 Python 3.9 或更新版本推荐通过 pip 安装pip install optuna也可以用 conda 安装conda install -c conda-forge optuna。如果运行的是文中 LightGBM 完整示例还需要lightgbm、scikit-learn、numpy等依赖见 教程示例 的 import 部分。先明确两个接口的分工源自 Study 参考文档enqueue_trial(params, user_attrsNone, skip_if_existsFalse)把参数值固定为下一次采样的参数即“让 Optuna 去评估这组参数”。实现上它创建一个TrialState.WAITING状态的 trial参数存入system_attrs的fixed_paramsparams必须是字典否则抛出TypeError(params must be a dictionary.)。add_trial(trial)把一个通常已完成评估的trial 加入 Study加入前会先做校验。官方 docstring 明确说排队等待评估应使用enqueue_trialadd_trial面向已评估完的 trial。场景一用 enqueue_trial 让 Optuna 先评估指定参数以官方 docstring 中的最小示例出自 optuna/study/study.py 的enqueue_trial文档只依赖 optuna 本身可直接复制运行import optuna def objective(trial): x trial.suggest_float(x, 0, 10) return x**2 study optuna.create_study() study.enqueue_trial({x: 5}) study.enqueue_trial({x: 0}, user_attrs{memo: optimal}) study.optimize(objective, n_trials2)运行后可用断言核对效果这组断言同样来自 docstring 示例assert study.trials[0].params {x: 5} assert study.trials[1].params {x: 0} assert study.trials[1].user_attrs {memo: optimal}三条断言分别验证排队的参数组合按入队顺序成为前两个被评估的 trialuser_attrs可以附带与params无关的用户属性示例中的{memo: optimal}会原样挂在对应 trial 上。两个可选参数user_attrs字典形式的用户自定义属性除参数值外随 trial 保存。skip_if_existsTrue当 Study 中已存在相同params的 trial 时跳过入队会打印 “Trial with params ... already exists. Skipping enqueue.” 日志。docstring 同时提醒如果多个进程同时用相同的params调用该方法仍可能产生重复入队。真实项目中的用法可参考 教程 tutorial/20_recipes/008_specify_params.py定义一个 LightGBM 目标函数内部通过trial.suggest_float/trial.suggest_int搜索bagging_fraction、bagging_freq、min_child_samples三个参数创建 Study 后排入两组参数再优化study optuna.create_study(directionmaximize, pruneroptuna.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 optuna.logging.get_logger(optuna).addHandler(logging.StreamHandler(sys.stdout)) study.optimize(objective, n_trials100, timeout600)教程中的说明添加 stdout 流 handler 是为了让日志可见从而确认 Optuna 按预期工作前两个 trial 使用排队的参数之后由 sampler 采样。场景二用 add_trial 登记已评估的结果如果参数组合已经跑过、手里有结果值用optuna.trial.create_trial构造一个已完成的 trial再用study.add_trial注册。构造时见 optuna/trial/_frozen.py 的create_trial文档所有参数都是关键字参数state默认是TrialState.COMPLETE当状态为COMPLETE时params、distributions、value或values是必填项且value与values不能同时指定。同样以官方 docstring 中的最小示例出自 optuna/study/study.py 的add_trial文档import optuna from optuna.distributions import FloatDistribution def objective(trial): x trial.suggest_float(x, 0, 10) return x**2 study optuna.create_study() assert len(study.trials) 0 trial optuna.trial.create_trial( params{x: 2.0}, distributions{x: FloatDistribution(0, 10)}, value4.0, ) study.add_trial(trial) assert len(study.trials) 1 study.optimize(objective, n_trials3) assert len(study.trials) 4验证逻辑注册后 Study 里有 1 个 trial再跑 3 次优化后共 4 个。docstring 还给出了跨 Study 迁移的用法对study.trials逐个other_study.add_trial(trial)即可把已评估结果整体搬进另一个 Study。对应教程中 LightGBM 场景的完整写法是参数与分布范围和enqueue_trial场景保持一致value为文档示例中的示例值 0.94 / 0.95study optuna.create_study(directionmaximize, pruneroptuna.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.FloatDistribution(0.4, 1.0 1e-12), bagging_freq: optuna.distributions.IntDistribution(0, 7), min_child_samples: optuna.distributions.IntDistribution(5, 100), }, value0.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.FloatDistribution(0.4, 1.0 1e-12), bagging_freq: optuna.distributions.IntDistribution(0, 7), min_child_samples: optuna.distributions.IntDistribution(5, 100), }, value0.95, ) ) study.optimize(objective, n_trials100, timeout600)教程对这一场景的表述是登记这些结果后“Optuna will sample hyperparameters taking them into account”即后续采样会把已登记的结果纳入考虑。distributions必须与目标函数中suggest_*的搜索范围一致示例中FloatDistribution(0.4, 1.0 1e-12)对应trial.suggest_float(bagging_fraction, 0.4, 1.0 1e-12)否则 trial 在加入时的校验或后续采样语义会对不上。多目标 Study 下要特别注意add_trial会检查 trial 的值数量与 Study 目标数是否一致不一致会抛出ValueError提示 “The added trial has N values, which is different from the number of objectives ...”多目标时请使用values序列而不是value。需要批量登记时可用study.add_trials(trials)它内部就是逐个调用add_trial同样逐个校验。常见限制SQLite 下的并行优化FAQ 中有一条与enqueue_trial直接相关的限制为并发评估已排队的 trialRDBStorage使用SELECT ... FOR UPDATE语法而 SQLite3 不支持该语法因此官方不建议用 SQLite3 做并行优化还可能遇到 “database is locked” 错误。如果必须在文件式存储下做这类场景FAQ 给出的替代方案是 Journal 存储import optuna from optuna.storages import JournalStorage from optuna.storages.journal import JournalFileBackend storage JournalStorage(JournalFileBackend(optuna_journal_storage.log)) study optuna.create_study(storagestorage)单进程串行优化则不受此限制默认 InMemory/RDB 存储都可以正常使用这两个接口。小结与延伸阅读两个接口对应两条清晰的路径还没评估、想让 Optuna 排队先跑的用enqueue_trialWAITING 状态按入队顺序评估已有结果、想让 Optuna 采样时利用这些结果的用add_trialoptuna.trial.create_trialCOMPLETE 状态必须带params、distributions和value/values。验证手段分别是断言 trial 的params顺序与user_attrs、trial 数量变化以及在 LightGBM 教程中用 stdout 日志确认前两组参数被优先评估。完整可运行的教程见 tutorial/20_recipes/008_specify_params.py接口定义与文档可对照 optuna/study/study.py、optuna/trial/_frozen.py 与 Study API 参考、trial API 参考。【免费下载链接】optunaA hyperparameter optimization framework项目地址: https://gitcode.com/GitHub_Trending/op/optuna创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表