保存最小化问题的中间结果

Save intermediate results in minimization problem

我是运行一个使用下一个代码的最小化问题:

import numpy as np
from scipy.optimize import minimize

Nfeval = 1

def objective_fnc(x):
    ....
    return y

def callbackF(x):
    global Nfeval
    print('{0:4d}   {1: 3.6f}   {2: 3.6f}   {3: 3.6f}   {4: 3.6f}   {5: 3.6f}'.format(Nfeval, x[0], x[1], x[2], x[3], objective_fnc(x)))
    Nfeval += 1

res=minimize(objective_fnc, x0, method='Nelder-Mead', bounds=bnds, callback=callbackF, options={'disp': True})

我想将中间结果保存在 txt 文件中,以防优化过程因任何原因停止。这个想法是在优化过程中只保存那些比以前更好或更好的结果。

我可以使用之前定义的 callbackF 函数访问变量和 objective 函数。但是,我仍在尝试弄清楚如何在方便时保存最佳结果。

我建议这样:

import numpy as np

class CallbackFunctor:
    def __init__(self, obj_fun):
        self.best_fun_vals = [np.inf]
        self.best_sols = []
        self.num_calls = 0
        self.obj_fun = obj_fun
    
    def __call__(self, x):
        fun_val = self.obj_fun(x)
        self.num_calls += 1
        if fun_val < self.best_fun_vals[-1]:
            self.best_sols.append(x)
            self.best_fun_vals.append(fun_val)
   
    def save_sols(self, filename):
        sols = np.array([sol for sol in self.best_sols])
        np.savetxt(filename, sols)

在这里,您不需要丑陋的全局变量,回调会保存每个现在找到的解决方案,即函数值比上次找到的解决方案低 objective 的解决方案。用法示例:

cb = CallbackFunctor(objective_fun)
res = minimize(objective_fun, x0=x0, callback=cb)

print(cb.best_sols)       # contains all your collected solutions
print(cb.best_fun_vals)   # contains the corresponding objective function values
cb.save_sols("dummy.txt") # writes all solutions to a file 'dummy.txt'

但是,如果您真的想为每个新找到的解决方案将所有解决方案写入一个文件,您可以修改回调,使其在每个新解决方案之后调用 save_sol

import numpy as np

class CallbackFunctor:
    def __init__(self, obj_fun, filename):
        self.best_fun_vals = [np.inf]
        self.best_sols = []
        self.num_calls = 0
        self.obj_fun = obj_fun
        self.filename = filename
    
    def __call__(self, x):
        fun_val = self.obj_fun(x)
        self.num_calls += 1
        if fun_val < self.best_fun_vals[-1]:
            self.best_sols.append(x)
            self.best_fun_vals.append(fun_val)
            self.save_sols(self.filename)
   
    def save_sols(self, filename):
        sols = np.array([sol for sol in self.best_sols])
        np.savetxt(filename, sols)

cb = CallbackFunctor(objective_fun, "dummy.txt")
res = minimize(objective_fun, x0=x0, callback=cb)