【问题标题】:Python / GPyOpt: Optimizing only one argumentPython / GPyOpt:仅优化一个参数
【发布时间】:2018-07-30 14:19:14
【问题描述】:

我目前正在尝试使用 GPyOpt 模块通过高斯优化找到某些函数 f(arg1, arg2, arg3, ...) 的最小值。虽然f(...) 需要许多输入参数,但我只想优化其中一个。你是怎么做到的?

我目前的“解决方案”是将f(...) 放在一个虚拟类中,并在初始化时指定不可优化的参数。虽然这可以说是解决这个问题的最蟒蛇式的方法,但它也比它有任何权利要复杂得多。

在优化 x 时,具有固定 y(数字)和 method(字符串)的函数 f(x, y, method) 的简短工作示例:

import GPyOpt
import numpy as np

# dummy class
class TarFun(object):
    # fix y while initializing the object
    def __init__(self, y, method):
        self.y = y
        self.method = method
    # actual function to be minimized
    def f(self, x):
        if self.method == 'sin':
            return np.sin(x-self.y)
        elif self.method == 'cos':
            return np.cos(x-self.y)

# create TarFun object with y fixed to 2 and use 'sin' method
tarFunObj = TarFun(y=2, method='sin')
# describe properties of x
space = [{'name':'x', 'type': 'continuous', 'domain': (-5,5)}]
# create GPyOpt object that will only optimize x
optObj = GPyOpt.methods.BayesianOptimization(tarFunObj.f, space)

肯定有一个更简单的方法。但是我发现的所有示例都优化了所有参数,我无法通过阅读 github 上的代码来弄清楚(我虽然可以在 GPyOpt.core.task.space 中找到信息,但没有运气)。

【问题讨论】:

    标签: python machine-learning optimization hyperparameters gpyopt


    【解决方案1】:

    GPyOpt 通过上下文原生支持这一点。您描述函数的整个域,然后在调用优化例程时使用上下文字典修复一些变量的值。 API 看起来像这样:

    myBopt.run_optimization(..., context={'var1': .3, 'var2': 0.4})
    

    更多细节可以在tutorial notebook中找到关于上下文优化的信息。

    【讨论】:

      【解决方案2】:

      我会从functools 标准库中查看partial 函数。它允许您部分指定一个函数,例如:

      import GPyOpt
      import numpy as np
      from functools import partial
      
      
      def f(x, y=0):
          return np.sin(x - y)
      
      
      objective = partial(f, y=2)
      space = [{'name': 'x', 'type': 'continuous', 'domain': (-5, 5)}]
      
      opt = GPyOpt.methods.BayesianOptimization(
          objective, domain=space
      )
      

      【讨论】:

      • 绝对是比我所做的更干净的解决方法,但我仍然认为必须有一种方法可以直接在 GPyOpt 对象中指定它(修复参数似乎太重要了,不需要外部模块)
      • 您也可以简单地将discrete 类型的变量添加到您的空间中,如下所示:{'name': 'y', 'type': 'discrete', 'domain': (2,)}
      • 这在这个特定的例子中可以工作,但是例如如果一个函数将一个字符串作为参数,这将不起作用。当然,您可以将字符串编码为整数,但这又非常混乱。
      猜你喜欢
      • 1970-01-01
      • 2017-09-04
      • 2022-01-20
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-25
      相关资源
      最近更新 更多