如何在optuna中对不重复的参数进行采样?
How to sample parameters without duplicates in optuna?
我正在使用 optuna 对我的自定义模型进行参数优化。
在当前参数集之前没有测试之前,有什么方法可以对参数进行采样吗?我的意思是,如果过去曾使用相同的参数集进行过一些试验,请尝试对另一个参数进行采样。
在某些情况下它是 impossible,例如,当存在分类分布并且 n_trials
大于数字 os possible unique sampled值。
我想要的:有一些像 num_attempts
这样的配置参数,以便在 for 循环中对高达 num_attempts
的参数进行采样,直到有一个之前没有测试过的参数集,否则 - 运行 在最后一个采样集上进行试验。
为什么我需要这个:只是因为它 cos 对 运行 重模型在相同的参数上好几次太多了。
我现在做的:只是做这个 "for-loop" 东西,但它很乱。
如果有另一种聪明的方法 - 将非常感谢您提供信息。
谢谢!
据我所知,目前没有直接的方式处理您的案件。
作为解决方法,您可以检查参数重复并跳过评估,如下所示:
import optuna
def objective(trial: optuna.Trial):
# Sample parameters.
x = trial.suggest_int('x', 0, 10)
y = trial.suggest_categorical('y', [-10, -5, 0, 5, 10])
# Check duplication and skip if it's detected.
for t in trial.study.trials:
if t.state != optuna.structs.TrialState.COMPLETE:
continue
if t.params == trial.params:
return t.value # Return the previous value without re-evaluating it.
# # Note that if duplicate parameter sets are suggested too frequently,
# # you can use the pruning mechanism of Optuna to mitigate the problem.
# # By raising `TrialPruned` instead of just returning the previous value,
# # the sampler is more likely to avoid sampling the parameters in the succeeding trials.
#
# raise optuna.structs.TrialPruned('Duplicate parameter set')
# Evaluate parameters.
return x + y
# Start study.
study = optuna.create_study()
unique_trials = 20
while unique_trials > len(set(str(t.params) for t in study.trials)):
study.optimize(objective, n_trials=1)
第二个@sile的代码注释,你可以写一个pruner比如:
from optuna.pruners import BasePruner
from optuna.structs import TrialState
class RepeatPruner(BasePruner):
def prune(self, study, trial):
# type: (Study, FrozenTrial) -> bool
trials = study.get_trials(deepcopy=False)
numbers=np.array([t.number for t in trials])
bool_params= np.array([trial.params==t.params for t in trials]).astype(bool)
#Don´t evaluate function if another with same params has been/is being evaluated before this one
if np.sum(bool_params)>1:
if trial.number>np.min(numbers[bool_params]):
return True
return False
然后将修剪器称为:
study = optuna.create_study(study_name=study_name, storage=storage, load_if_exists=True, pruner=RepeatPruner())
我正在使用 optuna 对我的自定义模型进行参数优化。
在当前参数集之前没有测试之前,有什么方法可以对参数进行采样吗?我的意思是,如果过去曾使用相同的参数集进行过一些试验,请尝试对另一个参数进行采样。
在某些情况下它是 impossible,例如,当存在分类分布并且 n_trials
大于数字 os possible unique sampled值。
我想要的:有一些像 num_attempts
这样的配置参数,以便在 for 循环中对高达 num_attempts
的参数进行采样,直到有一个之前没有测试过的参数集,否则 - 运行 在最后一个采样集上进行试验。
为什么我需要这个:只是因为它 cos 对 运行 重模型在相同的参数上好几次太多了。
我现在做的:只是做这个 "for-loop" 东西,但它很乱。
如果有另一种聪明的方法 - 将非常感谢您提供信息。
谢谢!
据我所知,目前没有直接的方式处理您的案件。 作为解决方法,您可以检查参数重复并跳过评估,如下所示:
import optuna
def objective(trial: optuna.Trial):
# Sample parameters.
x = trial.suggest_int('x', 0, 10)
y = trial.suggest_categorical('y', [-10, -5, 0, 5, 10])
# Check duplication and skip if it's detected.
for t in trial.study.trials:
if t.state != optuna.structs.TrialState.COMPLETE:
continue
if t.params == trial.params:
return t.value # Return the previous value without re-evaluating it.
# # Note that if duplicate parameter sets are suggested too frequently,
# # you can use the pruning mechanism of Optuna to mitigate the problem.
# # By raising `TrialPruned` instead of just returning the previous value,
# # the sampler is more likely to avoid sampling the parameters in the succeeding trials.
#
# raise optuna.structs.TrialPruned('Duplicate parameter set')
# Evaluate parameters.
return x + y
# Start study.
study = optuna.create_study()
unique_trials = 20
while unique_trials > len(set(str(t.params) for t in study.trials)):
study.optimize(objective, n_trials=1)
第二个@sile的代码注释,你可以写一个pruner比如:
from optuna.pruners import BasePruner
from optuna.structs import TrialState
class RepeatPruner(BasePruner):
def prune(self, study, trial):
# type: (Study, FrozenTrial) -> bool
trials = study.get_trials(deepcopy=False)
numbers=np.array([t.number for t in trials])
bool_params= np.array([trial.params==t.params for t in trials]).astype(bool)
#Don´t evaluate function if another with same params has been/is being evaluated before this one
if np.sum(bool_params)>1:
if trial.number>np.min(numbers[bool_params]):
return True
return False
然后将修剪器称为:
study = optuna.create_study(study_name=study_name, storage=storage, load_if_exists=True, pruner=RepeatPruner())