【问题标题】:Hyperopt list of values per hyperparameterHyperopt 每个超参数的值列表
【发布时间】:2020-08-04 17:54:55
【问题描述】:

我正在尝试在回归模型上使用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 中是否可行。如果没有,欢迎对优化器提出任何建议。

【问题讨论】:

  • 所以你想进行网格搜索或者你对笛卡尔积的意思是什么?
  • Gridsearch 只是关于搜索空间的众多优化方法之一,所以我不确定您为什么要专门询问它。您听起来好像搜索空间的选择取决于优化方法。
  • 我很抱歉,但我有点困惑,你想要实现什么。您想要一个动态的 hyperopt 搜索空间,您只需为一个变量定义一个搜索空间,它会自动为您的回归的所有变量实现它?
  • 对,举个例子:假设我们有一个二进制(为简单起见)超参数,它可以是 0 或 1。如果将其应用于所有变量,则搜索空间将为 [[0] , [1]]。我想要的是让它单独和独立地应用于每个变量。假设我们有 2 个变量,那么搜索空间将是 [[0, 0], [0, 1], [1, 0], [1, 1]]。这在使用 gridsearch 时很容易实现(并且您不需要 Hyperopt),但是评估所有点的成本很高,所以我想使用更有效的东西,比如贝叶斯优化(在本例中为 hyperopt.tpe)
  • 换句话说,这就像将多个超参数设置为hp.uniform('hyperparameter', a, b),然后将它们重新组合成一个列表以作为单个超参数提供给回归。我试过了,内核在一段时间后就死了,我不认为这是由于搜索空间爆炸,而是 Hyperopt 无法本地处理此类操作。

标签: python-3.x mathematical-optimization hyperopt


【解决方案1】:

正如我在评论中所指出的,我不是 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 接近最大值。因为这通常会最小化目标函数的结果。

【讨论】:

    【解决方案2】:

    你可以使用这个函数来创建空间:

    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
    
    

    【讨论】:

      【解决方案3】:

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

      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,因为根据我的经验,与其他优化器相比,它的性能非常差。

      【讨论】:

        【解决方案4】:

        您好,所以我使用 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。它为我节省了很多时间,而且效果非常好。

        【讨论】:

          猜你喜欢
          • 2019-12-03
          • 2020-09-10
          • 2020-05-09
          • 1970-01-01
          • 2022-11-10
          • 2020-05-22
          • 1970-01-01
          • 2020-06-05
          • 1970-01-01
          相关资源
          最近更新 更多