如何使用 optuna 搜索一组正态分布的参数?
How to search a set of normally distributed parameters using optuna?
我正在尝试优化具有 13 个参数的自定义模型(没有任何花哨的 ML),我知道其中 12 个是正态分布的。我使用 hyperopt
库得到了不错的结果:
space = {
'B1': hp.normal('B1', B1['mean'], B1['std']),
'B2': hp.normal('B2', B2['mean'], B2['std']),
'C1': hp.normal('C1', C1['mean'], C1['std']),
'C2': hp.normal('C2', C2['mean'], C2['std']),
'D1': hp.normal('D1', D1['mean'], D1['std']),
'D2': hp.normal('D2', D2['mean'], D2['std']),
'E1': hp.normal('E1', E1['mean'], E1['std']),
'E2': hp.normal('E2', E2['mean'], E2['std']),
'F1': hp.normal('F1', F1['mean'], F1['std']),
'F2': hp.normal('F2', F2['mean'], F2['std'])
}
我可以在其中指定每个要正态分布的参数的搜索形状 space。
我有 32 个核心,默认 Trials()
对象只使用其中一个。 Hyperopt
建议了两种并行搜索过程的方法,这两种方法我都无法在我的 windows 机器上工作,所以我放弃了,想尝试不同的框架.
尽管据我所知,贝叶斯超参数优化是基于值根据分布分布的思想,而正态分布非常普遍,以至于字面上称为正态分布。我找不到一种方法来指定 Optuna
我的参数有一个 mean
和一个 standard deviation
.
我如何告诉 Optuna
我的参数的 mean
和 standard deviation
?
我能在文档中找到的唯一发行版是:suggest_uniform()
、suggest_loguniform()
和 suggest_discrete_uniform()
。
请告诉我我是否误解了对数分布(它看起来有点相似,但我不能指定标准偏差?)或修剪过程。
正如您从我的文字中可以看出的那样,我花了很多时间试图解决这个问题,但一无所获,我们将不胜感激任何帮助!
特别感谢 dankal444 提供了这个优雅的解决方案(我将用我自己的值替换均值和标准差):
from scipy.special import erfinv
space = {
'B1': (erfinv(trial.suggest_float('B1', -1, 1))-mean)*std,
'B2': ...
}
你可以欺骗optuna
通过使用均匀分布并将其转化为正态分布。要做到这一点,其中一种方法是 inversed error function 在 scipy
中实现。
函数采用 <-1, 1> 范围内的均匀分布并将其转换为标准正态分布
import matplotlib.pyplot as plt
import numpy as np
from scipy import special
x = np.linspace(-1, 1)
plt.plot(x, special.erfinv(x))
plt.xlabel('$x$')
plt.ylabel('$erf(x)$')
mean = 2
std = 3
random_uniform_data = np.random.uniform(-1 + 0.00001, 1-0.00001, 1000)
random_gaussianized_data = (special.erfinv(random_uniform_data) - mean) * std
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].hist(random_uniform_data, 30)
axes[1].hist(random_gaussianized_data, 30)
axes[0].set_title('uniform distribution samples')
axes[1].set_title('erfinv(uniform distribution samples)')
plt.show()
函数如下所示:
下面是将均匀分布转换为具有自定义均值和标准差的正态分布的示例(参见上面的代码)
我正在尝试优化具有 13 个参数的自定义模型(没有任何花哨的 ML),我知道其中 12 个是正态分布的。我使用 hyperopt
库得到了不错的结果:
space = {
'B1': hp.normal('B1', B1['mean'], B1['std']),
'B2': hp.normal('B2', B2['mean'], B2['std']),
'C1': hp.normal('C1', C1['mean'], C1['std']),
'C2': hp.normal('C2', C2['mean'], C2['std']),
'D1': hp.normal('D1', D1['mean'], D1['std']),
'D2': hp.normal('D2', D2['mean'], D2['std']),
'E1': hp.normal('E1', E1['mean'], E1['std']),
'E2': hp.normal('E2', E2['mean'], E2['std']),
'F1': hp.normal('F1', F1['mean'], F1['std']),
'F2': hp.normal('F2', F2['mean'], F2['std'])
}
我可以在其中指定每个要正态分布的参数的搜索形状 space。
我有 32 个核心,默认 Trials()
对象只使用其中一个。 Hyperopt
建议了两种并行搜索过程的方法,这两种方法我都无法在我的 windows 机器上工作,所以我放弃了,想尝试不同的框架.
尽管据我所知,贝叶斯超参数优化是基于值根据分布分布的思想,而正态分布非常普遍,以至于字面上称为正态分布。我找不到一种方法来指定 Optuna
我的参数有一个 mean
和一个 standard deviation
.
我如何告诉 Optuna
我的参数的 mean
和 standard deviation
?
我能在文档中找到的唯一发行版是:suggest_uniform()
、suggest_loguniform()
和 suggest_discrete_uniform()
。
请告诉我我是否误解了对数分布(它看起来有点相似,但我不能指定标准偏差?)或修剪过程。
正如您从我的文字中可以看出的那样,我花了很多时间试图解决这个问题,但一无所获,我们将不胜感激任何帮助!
特别感谢 dankal444 提供了这个优雅的解决方案(我将用我自己的值替换均值和标准差):
from scipy.special import erfinv
space = {
'B1': (erfinv(trial.suggest_float('B1', -1, 1))-mean)*std,
'B2': ...
}
你可以欺骗optuna
通过使用均匀分布并将其转化为正态分布。要做到这一点,其中一种方法是 inversed error function 在 scipy
中实现。
函数采用 <-1, 1> 范围内的均匀分布并将其转换为标准正态分布
import matplotlib.pyplot as plt
import numpy as np
from scipy import special
x = np.linspace(-1, 1)
plt.plot(x, special.erfinv(x))
plt.xlabel('$x$')
plt.ylabel('$erf(x)$')
mean = 2
std = 3
random_uniform_data = np.random.uniform(-1 + 0.00001, 1-0.00001, 1000)
random_gaussianized_data = (special.erfinv(random_uniform_data) - mean) * std
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].hist(random_uniform_data, 30)
axes[1].hist(random_gaussianized_data, 30)
axes[0].set_title('uniform distribution samples')
axes[1].set_title('erfinv(uniform distribution samples)')
plt.show()
函数如下所示:
下面是将均匀分布转换为具有自定义均值和标准差的正态分布的示例(参见上面的代码)