【问题标题】:simulated annealing in python with multiple variables具有多个变量的python中的模拟退火
【发布时间】:2021-12-07 20:11:43
【问题描述】:

我发现这篇旧的 stackoverflow 文章基本上正是我想要的。

Algorithm to optimize multiple variables more efficiently than trial-and-error

不幸的是,我的高级数学有点欠缺,我对 ElKamina 的答案有一些疑问,如果有人可以看看并建议一些这些基本的数学概念,希望它能帮助我。

我指的答案如下:

def simAnneal( w, seed_x, numSteps=100000, sigma=0.01 ):
    optimal_x = [i for i in seed_x]
    optimal_w = w(optimal_x)

    cur_w = w(seed_x)

    for i in range(numSteps):
        new_x = [i+random.gauss(0, sigma) for i in seed_x]
        new_w = w(new_x)

        if (new_w > cur_w) or (random.random() > new_w / cur_w) :
            cur_x = new_x
            cur_w = new_w
            if cur_w > optimal_w:
                optimal_w = cur_w
                optimal_x = cur_x
    return optimal_x

我不熟悉 seed_x、sigma 和高斯分布,所以我不确定他们是如何提出 new_x 的。

我正在尝试根据许多变量 (>10) 求解一个值,并且我正在尝试优化而不是随机猜测,因为这将花费很长时间。

谢谢!

【问题讨论】:

  • 你最好把这个发到math.stackexchange.com
  • 你能分享一个(小例子)你的多变量函数吗?此外,您所知道的所有信息。
  • 您所指的算法是“模拟退火” - 最好先阅读该算法,然后再深入了解实际实现。
  • pypi.org/project/frigidum 是为你做退火的包

标签: python algorithm math multivariate-testing


【解决方案1】:

模拟退火 TLDR: 我们试图找到一组参数,通过向参数添加随机噪声来最大化函数。如果改变导致改进,则接受改变;我们偶尔会接受负面的变化,但随着时间的推移和变化的严重程度,这种可能性会降低。

在上面的 sn-p 中,函数实际上使用了多个参数,但将它们作为一个列表接受:

  • w是参数优化的函数
  • seed_x 是参数的初始猜测 - 可以随机选择,但有根据的猜测会更好
  • 高斯只是噪声的“形状”,因此较小的值更常见。 random.random()*sigma(所有值的可能性都一样)在那里也可以正常工作。
  • sigma 是要注入的噪声大小。它不应超过典型参数值的百分之几。如果参数值的大小差异很大,请考虑使用特定于每个参数的 sigma 列表。
  • 缺失:温度的概念,实际上是模拟退火

用温度、更具描述性的名称和更明确的方式重写它:

def simAnneal(utility_func, initial_params, numSteps=100000,
              noise_magnitude=0.01, cooling_rate=0.999):
    optimal_params = initial_params
    params = initial_params.copy()  # lists are mutable, so .copy()
    best_utility = utility = utility_func(*initial_params)
    temperature = 1.0
    
    for i in range(numSteps):
        temperature *= cooling_rate
        # consider using numpy/scipy for params and noise
        new_params = [param+random.gauss(0, noise_magnitude) 
                      for param in params]
        # explicitly passing multiple parameters
        new_utility = utility_func(*new_params)

        if (new_utility > best_utility 
            or random.random()*temperature > new_utility / best_utility):
            params, utility = new_params, new_utility
            if new_utility > best_utility:
                optimal_params, best_utility = params, utility
    return optimal_params

最后但并非最不重要的一点 - 除非问题非常非凸,否则我敢打赌 SGD 会表现得更好。

【讨论】:

  • 非常感谢,会调查 sdg
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多