Hyperopt自动化调参工具实践-1

hyperopt

Hyperopt的任务是在一组可能的参数上找到标量值的最佳值,该标量值可能是随机的。

与许多优化包假定这些输入来自向量空间不同,Hyperopt是不同的,因为它鼓励使用者更详细地描述搜索空间。通过提供关于函数定义在哪里以及认为最佳值在哪里的更多信息,可以使Hyperopt中的算法更有效地搜索。

使用Hyperopt的方式是描述:

  • 要最小化的目标函数
  • 要搜索的空间
  • 用于存储搜索的所有点评估的数据库
  • 要使用的搜索算法

基础教程

在这个教程中,可以学习如何:

  1. 定义搜索空间
  2. 优化目标函数

本教程描述了如何使用HyperOpt优化超参数,而无需对HyperOpt中实现的任何算法具有数学理解。

# Import HyperOpt Library
from hyperopt import fmin, tpe, space_eval

声明一个要进行优化的目标函数。在本教程中,我们将优化一个名为"objective"的简单函数,这是一个简单的二次函数。

y = ( x − 3 ) 2 + 2 y = (x-3)^2 + 2 y=(x3)2+2

objective = lambda x: (x-3)**2 + 2

现在,让我们可视化这个目标函数。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-10, 10, 100)
y = objective(x)

fig = plt.figure()
plt.plot(x, y)
plt.show()

hnb9U.png

我们试图通过改变超参数 x x x 来优化这个目标函数。因此,将为 x x x 声明一个搜索空间。与搜索空间相关的函数是在 hyperopt.hp 中实现的,列表如下:

  • hp.randint(label, upper)hp.randint(label, low, high)
  • hp.uniform(label, low, high)
  • hp.loguniform(label, low, high)
  • hp.normal(label, mu, sigma)
  • hp.lognormal(label, mu, sigma)
  • hp.quniform(label, low, high, q)
  • hp.qloguniform(label, low, high, q)
  • hp.qnormal(label, mu, sigma, q)
  • hp.qlognormal(label, mu, sigma, q)
  • hp.choice(label, list)
  • hp.pchoice(label, p_list),其中 p_list 是概率和选项对的列表
  • hp.uniformint(label, low, high, q)hp.uniformint(label, low, high),因为当 q = 1.0 时,等同于 uniformint(label, low, high)

在本教程中,将使用最基本的 hp.uniform

# Define the search space of x between -10 and 10.
space = hp.uniform('x', -10, 10)

现在只剩下最后一步了。到目前为止,已经定义了一个目标函数,也为 x x x 定义了一个搜索空间。现在,可以在搜索空间 x x x 中搜索,并找到能够优化目标函数的 x x x 的值。HyperOpt 使用 fmin 来执行这个过程。

best = fmin(
    fn=objective,  # Objective Function to optimize
    space=space,  # Hyperparameter's Search Space
    algo=tpe.suggest,  # Optimization algorithm
    max_evals=1000  # Number of optimization attempts
)
print(best)
print(space_eval(space, best))
100%|██████████| 1000/1000 [00:04<00:00, 228.56trial/s, best loss: 2.000001036046408]
{'x': 3.0010178636491283}
3.0010178636491283

HyperOpt找到的最优 x x x 值约为3.0。这非常接近min y = ( x − 3 ) 2 + 2 y=(x-3)^2+2 y=(x3)2+2 的一个解。

总的代码如下

# Import HyperOpt Library
from hyperopt import fmin, tpe, space_eval

objective = lambda x: (x-3)**2 + 2

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-10, 10, 100)
y = objective(x)

fig = plt.figure()
plt.plot(x, y)
plt.show()

# Define the search space of x between -10 and 10.
space = hp.uniform('x', -10, 10)

best = fmin(
    fn=objective,  # Objective Function to optimize
    space=space,  # Hyperparameter's Search Space
    algo=tpe.suggest,  # Optimization algorithm
    max_evals=1000  # Number of optimization attempts
)
print(best)
print(space_eval(space, best))

多参数教程

在这个教程中,将学习如何:

  1. 使用多个超参数优化目标函数
  2. 定义不同类型的搜索空间
# Import HyperOpt Library
import numpy as np
from hyperopt import tpe, hp, fmin, space_eval

声明一个要进行优化的目标函数。与上次不同,这次将使用两个超参数 x x x y y y 来优化函数。

z = s i n x 2 + y 2 z = sin\sqrt{x^2 + y^2} z=sinx2+y2

def objective(params):
    x, y = params['x'], params['y']
    return np.sin(np.sqrt(x**2 + y**2))

现在尝试将其可视化。但与上次不同的是,这次有两个超参数,因此需要在三维空间中将它们可视化。

import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
x, y = np.meshgrid(x, y)

z = objective({'x': x, 'y': y})

fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(x, y, z, cmap=cm.coolwarm)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

plt.show()

hngPp.png

同样,定义搜索空间。但这次,需要定义两个搜索空间( x , y x, y x,y),所以您将它们分别放在 dict() 中。

space = {
    'x': hp.uniform('x', -6, 6),
    'y': hp.uniform('y', -6, 6)
}
best = fmin(
    fn=objective, # Objective Function to optimize
    space=space, # Hyperparameter's Search Space
    algo=tpe.suggest, # Optimization algorithm (representative TPE)
    max_evals=1000 # Number of optimization attempts
)
print(best)
print(objective(best))
100%|██████████| 1000/1000 [00:07<00:00, 140.14trial/s, best loss: -0.9999998138498082]
{'x': 4.660020883316342, 'y': -0.7030201784219683}
-0.99999993408562725

定义不同类型的搜索空间

  • hp.randint(label, upper) 在区间 [0, upper) 中搜索整数。
  • hp.choice(label, list) 在列表中搜索元素。
def f(params):
    x1, x2 = params['x1'], params['x2']
    if x1 == 'james':
        return -1 * x2
    if x1 == 'max':
        return 2 * x2
    if x1 == 'wansoo':
        return -3 * x2

search_space = {
    'x1': hp.choice('x1', ['james', 'max', 'wansoo']),
    'x2': hp.randint('x2', -5, 5)
}

best = fmin(
    fn=f,
    space=search_space,
    algo=tpe.suggest,
    max_evals=100
)

print(best)
print(f(best))
100%|██████████| 100/100 [00:00<00:00, 396.61trial/s, best loss: -12.0]
{'x1': 2, 'x2': 4}

参考

贝叶斯优化算法是一种基于贝叶斯定理的优化算法,可以用于自动调参。其中,hyperopt是一个使用贝叶斯优化算法的Python包,可以帮助我们自动调整模型的超参数。 使用hyperopt,我们需要定义一个目标函数,这个函数输入超参数的值,输出模型的评分。然后,我们可以使用hyperopt的fmin函数来最小化这个目标函数,以找到最佳的超参数组合。 下面是一个使用hyperopt调参的示例代码: ```python from hyperopt import fmin, tpe, hp from sklearn.datasets import load_iris from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score # 定义目标函数 def objective(params): # 超参数 n_estimators = params['n_estimators'] max_depth = params['max_depth'] min_samples_split = params['min_samples_split'] # 定义模型 clf = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth, min_samples_split=min_samples_split) # 计算交叉验证得分 iris = load_iris() scores = cross_val_score(clf, iris.data, iris.target, cv=5) # 返回平均得分 return 1 - scores.mean() # 定义超参数搜索空间 space = { 'n_estimators': hp.choice('n_estimators', range(10, 1000)), 'max_depth': hp.choice('max_depth', range(1, 20)), 'min_samples_split': hp.choice('min_samples_split', range(2, 10)) } # 使用Tree-structured Parzen Estimator算法搜索最佳超参数 best = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=100) # 输出最佳超参数组合 print(best) ``` 在上面的代码中,我们定义了一个目标函数objective,它的输入是超参数的值,输出是模型的评分。然后,我们定义了超参数的搜索空间space,它包括n_estimators、max_depth和min_samples_split三个超参数。最后,我们使用Tree-structured Parzen Estimator算法搜索最佳超参数,最多进行100次迭代。 执行上述代码后,我们可以得到最佳的超参数组合,输出类似于{'max_depth': 4, 'min_samples_split': 8, 'n_estimators': 315}的结果。这个结果可以用于训练一个随机森林模型,并进行预测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_ll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值