在scipy.optimize.minimize回调中如何无冗余获取目标函数值?
解决scipy.optimize.minimize回调中获取目标函数值的问题
问题原因
你遇到的AttributeError是因为BFGS优化器的实际实现里,传入回调的OptimizeResult对象并没有填充fun属性——虽然文档说明多数方法支持该签名,但不同优化器的回调参数细节存在差异,BFGS并未在中间结果中存储当前目标函数值。
无冗余计算的解决方案
不需要通过重新计算目标函数值来获取结果,我们可以通过共享状态的方式,在计算目标函数的同时保存当前值,让回调直接读取缓存的值。
方法1:用闭包封装目标函数
直接在目标函数中添加一个属性来记录最新的目标函数值,回调函数直接读取这个属性:
from scipy.optimize import minimize def objective(x): fun_val = x[0]**2 + x[1]**2 # 替换成你的实际目标函数 objective.last_fun = fun_val return fun_val def callback(xk): print(f"当前迭代目标函数值: {objective.last_fun}") # 初始化目标函数的记录属性 objective.last_fun = None x0 = [1.0, 2.0] result = minimize(objective, x0, method='BFGS', callback=callback)
方法2:用类封装状态(更适合复杂场景)
如果你的优化逻辑涉及更多状态需要跟踪,用类来封装目标函数和回调会更清晰:
from scipy.optimize import minimize class OptimizerTracker: def __init__(self): self.last_fun = None def objective(self, x): self.last_fun = x[0]**2 + x[1]**2 # 替换成你的实际目标函数 return self.last_fun def callback(self, xk): print(f"当前迭代目标函数值: {self.last_fun}") tracker = OptimizerTracker() x0 = [1.0, 2.0] result = minimize(tracker.objective, x0, method='BFGS', callback=tracker.callback)
原理说明
这两种方法都是利用Python的作用域特性,在每次计算目标函数时就把结果缓存起来,回调函数直接读取缓存值,完全避免了冗余计算,效率和原优化过程一致。
内容的提问来源于stack exchange,提问作者DonkeyMonkey
相关产品推荐
相关产品推荐

