scikit-optimize 中的离散实际尺寸间距

问题描述 投票:0回答:3

假设我正在搜索一个维度:

from skopt import space

search_space = [
    space.Real(1, 10, name="my_scale")
]

我怎样才能用离散的步骤搜索这个实数?例如。 0.25。因为就我而言,可以缓存每个实际值的计算数据,并且我知道以 0.00001 等小步长微调值不会带来有意义的改进。但是,如果计算出的值是 1.25、1.50、1.75 等。我可以缓存结果并大大加快优化过程。

例如类似的东西


search_space = [
    space.Real(1, 10, step=0.25, name="my_scale")
]
scikits scikit-optimize
3个回答
0
投票

我对

skopt
没有太多经验,但我想知道这样的事情是否会对你有帮助:

def generate_discrete_values(start, end, step):
    values = []
    while start <= end:
        values.append(round(start, 2))
        start += step
    return values

随后,我会将其输入

skopt
,尽管我正在检查如何做到这一点 - 我正在审查 API。

会更新...


0
投票

生成这些离散值的列表并使用 space.Categorical 而不是 space.Real

from skopt import space, gp_minimize
from skopt.utils import use_named_args

start, end, step = 1, 10, 0.25
discrete_values = [round(start + i * step, 2) for i in range(int((end - start) / step) + 1)]

search_space = [space.Categorical(discrete_values, name="my_scale")]

@use_named_args(search_space)
def objective_function(my_scale):
    return (my_scale - 5) ** 2

result = gp_minimize(objective_function, search_space, n_calls=50, random_state=0)

print(result.x)
print(result.fun)

0
投票

为了确保搜索行为呈线性,同时仍采取离散步骤,您可以创建一个继承自 space.Real 的自定义维度类。

这个自定义类将定义一个空间,其行为类似于真实维度,但采取离散步骤。

您可以按如下方式实现:

from skopt import space, gp_minimize
from skopt.utils import use_named_args
import numpy as np

class DiscreteReal(space.Real):
    def __init__(self, low, high, step, name=None):
        super().__init__(low, high, name=name)
        self.step = step
        self.values = np.arange(low, high + step, step)

    def rvs(self, n_samples=1, random_state=None):
        rng = random_state if random_state is not None else np.random.default_rng()
        return rng.choice(self.values, size=n_samples)

    def _transform(self, X):
        return X

    def _inverse_transform(self, Xt):
        return Xt

    def bounds(self):
        return (self.low, self.high)

    def __repr__(self):
        return f"DiscreteReal(low={self.low}, high={self.high}, step={self.step}, name={self.name})"

# Usage example
search_space = [ DiscreteReal(1, 10, step=0.25, name="my_scale") ]
print(search_space)

@use_named_args(search_space)
def objective_function(my_scale):
     return (my_scale - 5) ** 2
 
result = gp_minimize(objective_function, search_space, n_calls=50, random_state=0)

print(result.x)
print(result.fun)

rvs
方法从可能的值生成随机样本。

transform
inverse_transform
方法保留为恒等函数,因为离散步骤不需要它们。

bounds
方法返回维度的边界。

__repr__
方法提供对象的字符串表示形式。

此自定义维度将在搜索空间中使用,并确保优化过程遵循离散步骤,同时仍然在指定范围内线性运行。

提供的代码输出:

[DiscreteReal(low=1, high=10, step=0.25, name=my_scale)]
/home/o/.local/lib/python3.10/site-packages/skopt/optimizer/optimizer.py:517: UserWarning: The objective has been evaluated at point [5.0] before, using random point [1.0]
  warnings.warn(
[5.0]
0.0
© www.soinside.com 2019 - 2024. All rights reserved.