Hyperopt 是否支持选择的子集?
Does Hyperopt support subset of choices?
我有一组选择A。我想取回一部分选择 A。这可以用 Hyperopt 实现吗?
输入:
{
'A': hp.choice('A', [0, 1, 2, 3])
}
输出:
{
'A': [0, 2]
}
否,但如果您特别需要该功能,可以通过多种方式实现。
您可以定义一个新表达式并将其添加到 the documentation 中给出的现有 hyperopt 参数表达式中。例如,在你的情况下,你可以这样做:
import hyperopt.pyll
from hyperopt.pyll import scope
from hyperopt.pyll.stochastic import sample
# Add a new method as you want
@scope.define
def foo(choices, num_choices):
return np.random.choice(choices, size=num_choices, replace=False)
choices = [1,2,3,4]
# Define the space like below and use in fmin
space = scope.foo(choices, 2)
# Call this multiple times to see how space behaves
print(sample(space))
查看 documention of numpy.random.choice 了解其工作原理。
注意:
foo
方法将 return 选择的子集(在 numpy 数组中)。因此,请确保在您的 objective 函数中,您使用的是内部多个值,例如 x[0], x[1], ...
等
- 在代码末尾添加
scope.undefine(foo)
,否则每次在 运行 代码之前,您都必须重新启动终端/内核。
- hyperopt wiki specifically prohibits 定义新类型的参数搜索空间,就像我们上面所做的那样,因为这可能会影响搜索策略或执行非最佳。
如果允许您选择两个值进行替换(这意味着有时子集中的两个值将相同。这就是我们使用的原因replace=False
在第 1 点),则可以进行以下操作:
choices = [1,2,3,4]
space = [hp.choice('c1', choices),
hp.choice('c2', choices)]
然后在你的 objective 函数中,你可以访问你的两个值 x[0]
, x[1]
.
但从你的问题来看,你似乎想要子选项,这意味着没有替换,所以 [1,1]
或 [2,2]
等的子集是无效的。在那种情况下,您应该使用 Trials
object to define status
。
第 2 点的示例程序如下:
from hyperopt import fmin, tpe, hp, STATUS_OK, STATUS_FAIL, Trials
def objective(x):
# Check if the supplied choices are valid or not
x1 = x[0]
x2 = x[1]
if x1 == x2:
# If invalid, only return the status and hyperopt will understand
return {'status': STATUS_FAIL}
# Normal flow of objective
# Do your coding here
# In the end, return this
return {
'loss': actual_loss, # Fill the actual loss here
'status': STATUS_OK
}
choices = [1,2,3,4]
space = [hp.choice('c1', choices),
hp.choice('c2', choices)]
trials = Trials()
best = fmin(objective, space=space, algo=tpe.suggest, max_evals=100, trials=trials)
from hyperopt import space_eval
print(space_eval(space, best))
希望对您有所帮助。
是的,虽然代码有点繁琐。分别定义 A 的每个元素作为包含和排除之间的选择。例如:
space = {
"A0": hp.choice("A0", [False, True]),
"A1": hp.choice("A1", [False, True]),
"A2": hp.choice("A2", [False, True]),
...
}
在您的 objective 函数中解释它的代码也非常简单:
A = [i for i in range(num_choices) if space["A"+str(i)]]
# A = [0, 2] for example
这将 return A 的真正随机子集(从空集到整个 A 的任何地方)。
我有一组选择A。我想取回一部分选择 A。这可以用 Hyperopt 实现吗?
输入:
{
'A': hp.choice('A', [0, 1, 2, 3])
}
输出:
{
'A': [0, 2]
}
否,但如果您特别需要该功能,可以通过多种方式实现。
您可以定义一个新表达式并将其添加到 the documentation 中给出的现有 hyperopt 参数表达式中。例如,在你的情况下,你可以这样做:
import hyperopt.pyll from hyperopt.pyll import scope from hyperopt.pyll.stochastic import sample # Add a new method as you want @scope.define def foo(choices, num_choices): return np.random.choice(choices, size=num_choices, replace=False) choices = [1,2,3,4] # Define the space like below and use in fmin space = scope.foo(choices, 2) # Call this multiple times to see how space behaves print(sample(space))
查看 documention of numpy.random.choice 了解其工作原理。
注意:
foo
方法将 return 选择的子集(在 numpy 数组中)。因此,请确保在您的 objective 函数中,您使用的是内部多个值,例如x[0], x[1], ...
等- 在代码末尾添加
scope.undefine(foo)
,否则每次在 运行 代码之前,您都必须重新启动终端/内核。 - hyperopt wiki specifically prohibits 定义新类型的参数搜索空间,就像我们上面所做的那样,因为这可能会影响搜索策略或执行非最佳。
如果允许您选择两个值进行替换(这意味着有时子集中的两个值将相同。这就是我们使用的原因
replace=False
在第 1 点),则可以进行以下操作:choices = [1,2,3,4] space = [hp.choice('c1', choices), hp.choice('c2', choices)]
然后在你的 objective 函数中,你可以访问你的两个值
x[0]
,x[1]
.但从你的问题来看,你似乎想要子选项,这意味着没有替换,所以
[1,1]
或[2,2]
等的子集是无效的。在那种情况下,您应该使用Trials
object to definestatus
。
第 2 点的示例程序如下:
from hyperopt import fmin, tpe, hp, STATUS_OK, STATUS_FAIL, Trials
def objective(x):
# Check if the supplied choices are valid or not
x1 = x[0]
x2 = x[1]
if x1 == x2:
# If invalid, only return the status and hyperopt will understand
return {'status': STATUS_FAIL}
# Normal flow of objective
# Do your coding here
# In the end, return this
return {
'loss': actual_loss, # Fill the actual loss here
'status': STATUS_OK
}
choices = [1,2,3,4]
space = [hp.choice('c1', choices),
hp.choice('c2', choices)]
trials = Trials()
best = fmin(objective, space=space, algo=tpe.suggest, max_evals=100, trials=trials)
from hyperopt import space_eval
print(space_eval(space, best))
希望对您有所帮助。
是的,虽然代码有点繁琐。分别定义 A 的每个元素作为包含和排除之间的选择。例如:
space = {
"A0": hp.choice("A0", [False, True]),
"A1": hp.choice("A1", [False, True]),
"A2": hp.choice("A2", [False, True]),
...
}
在您的 objective 函数中解释它的代码也非常简单:
A = [i for i in range(num_choices) if space["A"+str(i)]]
# A = [0, 2] for example
这将 return A 的真正随机子集(从空集到整个 A 的任何地方)。