如何修复错误“'_BaseUniformDistribution' 对象没有属性 'to_internal_repr'”- optuna 中的奇怪行为

How to fix error "'_BaseUniformDistribution' object has no attribute 'to_internal_repr'" - strange behaviour in optuna

我正在尝试使用 Python 中的 optuna 库来优化推荐系统模型的参数。这些模型是自定义的,看起来像标准的拟合预测 sklearn 模型(方法 get/set 参数)。

我所做的:简单的 objective 函数,从均匀的 int 分布中选择两个参数,将这些参数设置为模型,预测模型(没有拟合阶段,因为它只是在预测阶段使用参数的简单模型) 并计算一些指标。

我得到的结果:第一次试验 运行 正常,它对参数进行采样并将结果打印到日志中。但是在第二次和下一次试验中,我遇到了一些我无法解决或 google 的奇怪错误(请看下面的代码)。当我 运行 只研究 1 次试验时,一切都很好。

我尝试了什么:重新排列 objective 函数的各个部分,将 fit 阶段放在里面,尝试计算更简单的指标 - 没有任何帮助。

这是我的 objective 函数:

# getting train, test
# fitting model
self.model = SomeRecommender()
self.model.fit(train, some_other_params)

def objective(trial: optuna.Trial):
    # save study
    if path is not None:
        joblib.dump(study, some_path)

    # sampling params
    alpha = trial.suggest_uniform('alpha', 0, 100)
    beta = trial.suggest_uniform('beta', 0, 100)

    # setting params to model
    params = {'alpha': alpha,
              'beta': beta}
    self.model.set_params(**params)

    # getting predict
    recs = self.model.predict(some_other_params)

    # metric computing
    metric_result = Metrics.hit_rate_at_k(recs, test, k=k)

    return metric_result

# starting study
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=3, n_jobs=1)

这就是我在三个试验中得到的结果:

[I 2019-10-01 12:53:59,019] Finished trial#0 resulted in value: 0.1. Current best value is 0.1 with parameters: {'alpha': 59.6135986324444, 'beta': 40.714559720597585}.
[W 2019-10-01 13:39:58,140] Setting status of trial#1 as TrialState.FAIL because of the following error: AttributeError("'_BaseUniformDistribution' object has no attribute 'to_internal_repr'")
Traceback (most recent call last):
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/study.py", line 448, in _run_trial
    result = func(trial)
  File "/Users/roseaysina/code/project/model.py", line 100, in objective
    'alpha', 0, 100)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/trial.py", line 180, in suggest_uniform
    return self._suggest(name, distribution)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/trial.py", line 453, in _suggest
    self.study, trial, name, distribution)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/samplers/tpe/sampler.py", line 127, in sample_independent
    values, scores = _get_observation_pairs(study, param_name)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/samplers/tpe/sampler.py", line 558, in _get_observation_pairs
    param_value = distribution.to_internal_repr(trial.params[param_name])
AttributeError: '_BaseUniformDistribution' object has no attribute 'to_internal_repr'
[W 2019-10-01 13:39:58,206] Setting status of trial#2 as TrialState.FAIL because of the following error: AttributeError("'_BaseUniformDistribution' object has no attribute 'to_internal_repr'")
Traceback (most recent call last):
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/study.py", line 448, in _run_trial
    result = func(trial)
  File "/Users/roseaysina/code/project/model.py", line 100, in objective
    'alpha', 0, 100)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/trial.py", line 180, in suggest_uniform
    return self._suggest(name, distribution)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/trial.py", line 453, in _suggest
    self.study, trial, name, distribution)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/samplers/tpe/sampler.py", line 127, in sample_independent
    values, scores = _get_observation_pairs(study, param_name)
  File "/Users/roseaysina/anaconda3/envs/sauvage/lib/python3.7/site-packages/optuna/samplers/tpe/sampler.py", line 558, in _get_observation_pairs
    param_value = distribution.to_internal_repr(trial.params[param_name])
AttributeError: '_BaseUniformDistribution' object has no attribute 'to_internal_repr'

我不明白问题出在哪里,为什么第一次试用有效。请帮忙。

谢谢!

你的代码好像没有问题。

我 运行 您的代码的简化版本(见下文),它在我的环境中运行良好:

import optuna

def objective(trial: optuna.Trial):
    # sampling params
    alpha = trial.suggest_uniform('alpha', 0, 100)
    beta = trial.suggest_uniform('beta', 0, 100)

    # evaluating params
    return alpha + beta

# starting study
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=3, n_jobs=1)

您能告诉我您的环境以便调查问题吗? (例如,OS、Python 版本、Python 解释器(CPython、PyPy、IronPython 或 Jython)、Optuna 版本)

why the first trial is working.

此错误由 optuna/samplers/tpe/sampler.py#558 引发,仅当研究中完成的试验数大于零时才执行此行。

顺便说一句,您可以使用 RandomSampler 来避免这个问题,如下所示:

sampler = optuna.samplers.RandomSampler()
study = optuna.create_study(direction='maximize', sampler=sampler)

请注意 RandomSampler 的优化性能往往比 Optuna 默认采样器 TPESampler 差。