5

我正在尝试在回归模型上使用Hyperopt,这样它的一个超参数是按变量定义的,并且需要作为列表传递。例如,如果我有一个包含 3 个自变量(不包括常数)的回归,我会通过hyperparameter = [x, y, z]x, y, z浮点数在哪里)。

无论它们应用于哪个变量,此超参数的值都具有相同的界限。如果将此超参数应用于所有变量,我可以简单地使用hp.uniform('hyperparameter', a, b). 我希望搜索空间是hp.uniform('hyperparameter', a, b)长度的笛卡尔积n,其中n是回归中的变量数(所以,基本上,itertools.product(hp.uniform('hyperparameter', a, b), repeat = n)

我想知道这在 Hyperopt 中是否可行。如果没有,欢迎对可能的优化器提出任何建议。

4

4 回答 4

0

您可以使用此功能来创建空间:

def get_spaces(a, b, num_spaces=9):
    return_set = {}
    for set_num in range(9):
        name = str(set_num)
        return_set = {
                **return_set,
                **{name: hp.uniform(name, a, b)}
                }
                
    return return_set

于 2020-09-11T23:46:35.117 回答
0

我首先将我的预组合空间定义为字典。键是名称。这些值是一个元组。

from hyperopt import hp
space = {'foo': (hp.choice, (False, True)), 'bar': (hp.quniform, 1, 10, 1)}

接下来,使用循环或生成所需的组合变体itertools。每个名称都使用后缀或前缀保持唯一。

types = (1, 2)
space = {f'{name}_{type_}': args for type_ in types for name, args in space.items()}
>>> space 
{'foo_1': (<function hyperopt.pyll_utils.hp_choice(label, options)>,
  (False, True)),
 'bar_1': (<function hyperopt.pyll_utils.hp_quniform(label, *args, **kwargs)>,
  1, 10, 1),
 'foo_2': (<function hyperopt.pyll_utils.hp_choice(label, options)>,
  (False, True)),
 'bar_2': (<function hyperopt.pyll_utils.hp_quniform(label, *args, **kwargs)>,
  1, 10, 1)}

最后,初始化并创建实际hyperopt空间:

space = {name: fn(name, *args) for name, (fn, *args) in space.items()}
values = tuple(space.values())
>>> space
{'foo_1': <hyperopt.pyll.base.Apply at 0x7f291f45d4b0>,
 'bar_1': <hyperopt.pyll.base.Apply at 0x7f291f45d150>,
 'foo_2': <hyperopt.pyll.base.Apply at 0x7f291f45d420>,
 'bar_2': <hyperopt.pyll.base.Apply at 0x7f291f45d660>}

这是使用 hyperopt 0.2.7 完成的。作为免责声明,我强烈建议不要使用 hyperopt,因为根据我的经验,与其他优化器相比,它的性能非常差。

于 2022-02-01T04:48:09.030 回答
0

正如我在评论中指出的,我不是 100% 确定您在寻找什么,但这里有一个使用 hyperopt 优化 3 个变量组合的示例:

import random

# define an objective function
def objective(args):
    v1 = args['v1']
    v2 = args['v2']
    v3 = args['v3']
    result = random.uniform(v2,v3)/v1
    return result

# define a search space
from hyperopt import hp

space = {
    'v1': hp.uniform('v1', 0.5,1.5),
    'v2': hp.uniform('v2', 0.5,1.5),
    'v3': hp.uniform('v3', 0.5,1.5),
}

# minimize the objective over the space
from hyperopt import fmin, tpe, space_eval
best = fmin(objective, space, algo=tpe.suggest, max_evals=100)

print(best)

在这种情况下,它们都有相同的搜索空间(据我所知,这是您的问题定义)。Hyperopt 旨在最小化目标函数,因此运行此函数最终会使 v2 和 v3 接近最小值,而 v1 接近最大值。因为这通常会最小化目标函数的结果。

于 2020-08-15T14:34:09.530 回答
-1

嗨所以我用 optuna 实现了这个解决方案。optuna 的优点是它将为所有单个值创建一个超空间,但以更智能的方式优化这些值,并且只使用一个超参数优化。例如,我使用 Batch-SIze、Learning-rate 和 Dropout-Rate 优化了一个神经网络:在此处输入图像描述

搜索空间远大于所使用的实际值。这可以节省大量时间,而不是网格搜索。

实现的伪代码是:

def function(trial): #trials is the parameter of optuna, which selects the next hyperparameter
    distribution = [0 , 1]
    a = trials.uniform("a": distribution) #this is a uniform distribution
    b = trials.uniform("a": distribution)

    return (a*b)-b
    #This above is the function which optuna tries to optimze/minimze

有关更详细的源代码,请访问Optuna。它为我节省了很多时间,这是一个非常好的结果。

于 2020-08-08T17:45:12.487 回答