Hyperopt 中的 qloguniform 搜索空间设置问题
Posted
技术标签:
【中文标题】Hyperopt 中的 qloguniform 搜索空间设置问题【英文标题】:qloguniform search space setting issue in Hyperopt 【发布时间】:2019-05-16 06:55:36 【问题描述】:我正在使用 hyperopt 来调整我的 ML 模型,但在使用 qloguniform 作为搜索空间时遇到了麻烦。我给出了来自official wiki 的示例并更改了搜索空间。
import pickle
import time
#utf8
import pandas as pd
import numpy as np
from hyperopt import fmin, tpe, hp, STATUS_OK, Trials
def objective(x):
return
'loss': x ** 2,
'status': STATUS_OK,
# -- store other results like this
'eval_time': time.time(),
'other_stuff': 'type': None, 'value': [0, 1, 2],
# -- attachments are handled differently
'attachments':
'time_module': pickle.dumps(time.time)
trials = Trials()
best = fmin(objective,
space=hp.qloguniform('x', np.log(0.001), np.log(0.1), np.log(0.001)),
algo=tpe.suggest,
max_evals=100,
trials=trials)
pd.DataFrame(trials.trials)
但出现以下错误。
ValueError: ('负 arg 到 lognormal_cdf', array([-3.45387764, -3.45387764,-3.45387764,-3.45387764,-3.45387764, -3.45387764,-3.45387764,-3.45387764,-3.45387764,-3.45387764, -3.45387764,-3.45387764,-3.45387764,-3.45387764,-3.45387764, -3.45387764,-3.45387764,-3.45387764,-3.45387764,-3.45387764, -3.45387764, -3.45387764, -3.45387764, -3.45387764]))
我尝试过如下不进行日志转换,但输出值为log transformation(例如 1.017,1.0008,1.02456),这是错误的。与文档一致。
hp.qloguniform('x', 0.001,0.1, 0.001)
谢谢
【问题讨论】:
【参考方案1】:问题似乎在于hp.qloguniform
、q
的最后一个参数以及tpe.suggest
如何使用它。
首先让我们讨论一下q
。根据文档:
hp.qloguniform(标签,低,高,q)
round(exp(uniform(low, high)) / q) * q
适用于目标所涉及的离散变量 “平滑”并且随着值的大小变得更平滑,但是 应该上下都有界。
q
这里是"quantizer"
,它将定义空间的输出限制为q
的倍数。例如,以下是qloguniform
内部发生的情况:
from hyperopt import pyll, hp
n_samples = 10
space = hp.loguniform('x', np.log(0.001), np.log(0.1))
evaluated = [pyll.stochastic.sample(space) for _ in range(n_samples)]
# Output: [0.04645754, 0.0083128 , 0.04931957, 0.09468335, 0.00660693,
# 0.00282584, 0.01877195, 0.02958924, 0.00568617, 0.00102252]
q = 0.005
qevaluated = np.round(np.array(evaluated)/q) * q
# Output: [0.045, 0.01 , 0.05 , 0.095, 0.005, 0.005, 0.02 , 0.03 , 0.005, 0.])
在此处比较 evaluated
和 qevaluated
。 qevaluated
是 q
的倍数,或者我们说它在 q
的“间隔”(或步骤)中量化。您可以尝试更改 q
值以了解更多信息。
与生成的样本范围 (0.001 to 0.1
) 相比,您在问题中定义的 q
非常大:
np.log(0.001)
# Output: -6.907755278982137
所以,这里所有值的输出都是 0。
q = np.log(0.001)
qevaluated = np.round(np.array(evaluated)/q) * q
# Output: [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]
现在来到tpe.suggest
(this paper 的第 4 节):TPE 使用不同估计器的树来优化搜索过程,在此期间它根据空间生成器划分搜索空间(在本例中为 @987654345 @)。有关详细信息,请参阅code here。要将空间分成多个部分,它将使用q
。
但由于您空间中的所有点都是 0.0(如上所述),因此这个负数 q
会为 lognormal_cdf
which is not acceptable 生成无效边界,从而导致错误。
长话短说,您对q
的使用不正确。正如您在评论中已经说过的那样:-
另外
q
值不应该根据round(exp(uniform(low, high)) / q) * q
在log uniform/log normal随机抽样中使用
所以您应该只提供对您所需空间有效的q
值。所以在这里,既然要生成0.001
和0.1
之间的值,那么q
的值应该与它们相当。
我同意您在qloguniform
中提供np.log(0.001)
和np.log(0.1)
,但这是为了使输出值介于0.001 和0.1 之间。所以不要在q
中使用np.log
。 q
应根据生成的值使用。
【讨论】:
感谢您的回复 Vivek。如您所知,对于学习率等超参数,范围将小于 1,因此其对数范围将是负数;您也可以为此添加解释吗?根据 ound(exp(uniform(low, high)) / q) * q,q 值也不应该用在对数均匀/对数正态随机抽样中以上是关于Hyperopt 中的 qloguniform 搜索空间设置问题的主要内容,如果未能解决你的问题,请参考以下文章
机器学习调参与贝叶斯优化及其典型python实现hyperopt
如何保存最佳 hyperopt 优化的 keras 模型及其权重?