scipy 如何在不使用全局变量的情况下显示优化器的进度?

qeeaahzv  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(93)

以MWE为例:

import dlib
from scipy.optimize import rosen
def rosen_f(*x):
    result = rosen((x))
    global OPT_FOUND
    if result < OPT_FOUND:
        OPT_FOUND = result
        print("New min", (x), result)
    return result

dlib.find_min_global(rosen_f, [0]*5, [0.5]*5, 1000)

字符串
如果我设置OPT_FOUND = 2**30,这将打印出find_min_global在优化中找到的所有改进。
我该如何:

  • 避免使用全局变量
  • 将改进添加到我可以在代码的主要部分使用的列表中?
7bsow1i6

7bsow1i61#

下面是一个简单的例子,它使用装饰器来监视优化。我无法安装dlib,所以我只是使用scipy.optimize.minimize,但装饰器应该一样工作。显然,您可以自定义装饰器以满足您的需求,我只是简单地拼凑了一些东西。

import numpy as np
from scipy.optimize import minimize, rosen

def minimizer_monitor(func):
    current_opt = np.inf
    def wrapped(*args, **kwargs):
        result = func(*args, **kwargs)
        if result < current_opt:
            print(f"New min: {result}\t{args=}\t{kwargs=}")
        return result
    return wrapped

@minimizer_monitor
def rosen_f(x):
    return rosen(x)

x0 = np.ones(5)*0.25
res = minimize(rosen_f, x0, bounds=[(0, 0.5)])

字符串
输出量:

New min: 16.3125    args=(array([0.25, 0.25, 0.25, 0.25, 0.25]),)   kwargs={}
New min: 16.3124997975  args=(array([0.25000001, 0.25      , 0.25      , 0.25      , 0.25      ]),) kwargs={}
New min: 16.31250017250001  args=(array([0.25      , 0.25000001, 0.25      , 0.25      , 0.25      ]),) kwargs={}
...
New min: 2.6456658876277777 args=(array([5.00000000e-01, 2.63037401e-01, 7.99623919e-02, 1.62317055e-02,
       2.63535577e-04]),)   kwargs={}
New min: 2.6456658876277817 args=(array([5.00000000e-01, 2.63037401e-01, 7.99623819e-02, 1.62317155e-02,
       2.63535577e-04]),)   kwargs={}
New min: 2.6456658876278407 args=(array([5.00000000e-01, 2.63037401e-01, 7.99623819e-02, 1.62317055e-02,
       2.63545577e-04]),)   kwargs={}

相关问题