PKU-DAIR / open-box

Generalized and Efficient Blackbox Optimization System
https://open-box.readthedocs.io
Other
356 stars 52 forks source link

参数取值为集合中的数据 #45

Closed nebula303 closed 1 year ago

nebula303 commented 1 year ago

我想使参数C1 在集合 {3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0, 8.0}中任取一个,我尝试这样写:C1 = sp.Categorical("C1", [3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0, 8.0]),但应该出问题了,想请问下应该如何书写

jhj0411jhj commented 1 year ago

我尝试了您的定义方式,没有遇到问题,请问出现了什么问题?代码如下:

from openbox import space as sp

cs = sp.Space()
C1 = sp.Categorical("C1", [3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0, 8.0])
cs.add_variable(C1)
print(cs.sample_configuration(3))

此外,由于您的数值可能存在偏序关系,我建议您尝试用Int定义超参数,然后在objective_function中解析该参数,可能模型会获得更好的拟合效果:

from openbox import space as sp

cs = sp.Space()
C1_idx = sp.Int("C1_idx", 0, 8)
cs.add_variable(C1_idx)

for i in range(10):
    config = cs.sample_configuration()
    # parse config in objective function
    C1_values = [3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0, 8.0]
    c1 = C1_values[config['C1_idx']]
    print(c1)
nebula303 commented 1 year ago

感谢,第二种方法成功了,我意识到,第一种方法报错是因为我尝试使用config['C1']来获取C1,有什么方法可以直接获取吗

jhj0411jhj commented 1 year ago

以下代码不会产生问题,建议您提供错误代码:

from openbox import space as sp

cs = sp.Space()
C1 = sp.Categorical("C1", [3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0, 8.0])
cs.add_variable(C1)
for i in range(10):
    config = cs.sample_configuration()
    print(config['C1'])
nebula303 commented 1 year ago

抱歉,我缺少这句config = cs.sample_configuration( )(😂),因为以往我直接用的sp.Real( ),没有注意这一点,再次感谢

jhj0411jhj commented 1 year ago

我对您的说法感到疑惑,objective_function传入的参数即为config ,这与Real还是Categorical并无关系。

nebula303 commented 1 year ago

是这样,以下是我原先的代码 ` import matplotlib.pyplot as plt import numpy as np from openbox import sp from openbox import sp

space=sp.ConditionedSpace() C1 = sp.Categorical("C1", [3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0, 8.0]) C2 = sp.Categorical("C2", [3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 7.0]) C3 = sp.Categorical("C3", [3.6, 4.0, 4.4, 4.8, 5.2, 5.6]) space.add_variables([C1,C2,C3])

def f(config): C1, C2, C3 = config['C1'], config['C2'], config['C3'] print(C1) return C1+C2+C3

from openbox import Optimizer

opt = Optimizer( f, space, num_constraints=1, num_objs=1, surrogate_type='prf', acq_optimizer_type='random_scipy', max_runs=50, time_limit_per_trial=10, task_id='soc', random_state=42, ) history = opt.run() history = opt.get_history() print(history) history.plot_convergence() plt.show() 而这样会报错,因为我在 f 函数中没有写config = space.sample_configuration( ) ![image](https://user-images.githubusercontent.com/72639142/204503147-cc020d9a-4084-40cf-8bac-b8850021ee8e.png) 而如果使用sp.Real( ),则不需写config = space.sample_configuration(),而这也是我一直以来的操作,如以下代码,就不会报错 import matplotlib.pyplot as plt import numpy as np from openbox import sp from openbox import sp

space=sp.ConditionedSpace() C1 = sp.Real("C1", 3.6, 8) C2 = sp.Real("C2", 3.6, 7) C3 = sp.Real("C3", 3.6, 5.6) space.add_variables([C1,C2,C3])

def f(config): C1, C2, C3 = config['C1'], config['C2'], config['C3'] print(C1) return C1+C2+C3

from openbox import Optimizer

opt = Optimizer( f, space, num_constraints=1, num_objs=1, surrogate_type='prf', acq_optimizer_type='random_scipy', max_runs=50, time_limit_per_trial=10, task_id='soc', random_state=42, ) history = opt.run() history = opt.get_history() print(history) history.plot_convergence() plt.show()`

jhj0411jhj commented 1 year ago

注意:不要在目标函数f中加入config = space.sample_configuration(),这句话的意思是进行随机采样,会导致目标函数评估了一个任意的config。

以上代码有如下问题:

  1. 在Optimizer中设置了num_constraints=1,而评估时并未返回约束值。如需定义约束,请返回字典:dict(objs=[c1+c2+c3], constraints=[...])
  2. 使用acq_optimizer_type='random_scipy'时,根据错误提示,该优化器不支持Categorical类型变量!建议使用上面的Int方式进行定义,或者使用acq_optimizer_type='local_random'
nebula303 commented 1 year ago

感谢提醒,第一处是因为我复制的源代码作为例子,没有完全更改,现在我是这样写的 image 如果不能在目标函数f 中加入config = space.sample_configuration(),该如何进行修改呢

jhj0411jhj commented 1 year ago

请务必删除config = space.sample_configuration()。 按照上面的这种Int定义方式,应该不会出现问题。如果使用Categorical定义变量,目前需要设置acq_optimizer_type'local_random''auto',后续我们可能会对'random_scipy'进行改进以支持Categorical

nebula303 commented 1 year ago

明白,感谢