【问题标题】:Pass additional parameters to an objective function将附加参数传递给目标函数
【发布时间】:2021-07-26 21:19:46
【问题描述】:

我正在尝试解决以下结构的最小化问题:

res=minimize(objective_fnc, x0, args=param, method='Nelder-Mead)

我需要传递一系列参数,这些参数不是优化变量的一部分,而是参数,以更一般的方式改变问题的条件/边界。例如,变量 param 是一个带有下一个参数的元组:param = (p1,p2,p3)

每当我调用objective_fnc 时,我都需要传递初始条件x0 和带有参数的元组,以便在目标函数中使用这些参数。比如objective_fnc(x0,param)

问题是我得到这个错误:objective_fnc() takes 2 positional arguments but 4 were given

我知道如果我传递初始条件和参数(不是元组的一部分,这种方式:objective_fnc(x0,p1,p2,p3))它可以工作,但我想以更简化的方式编写它以防我需要通过稍后添加其他参数。

这里有minimal reproducible example 有效,所有参数都被一一传递。但是,如果我将 p1,p2,p3 更改为 `param',我会收到错误消息。

import numpy as np
from scipy.optimize import minimize

def objective_fnc(x,p1,p2,p3):
    """The Rosenbrock function"""
    return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)


class CallbackFunctor:
    def __init__(self, obj_fun):
        self.num_calls = 0
        if self.num_calls == 0:
            print('Optimization problem started')
        self.obj_fun = obj_fun
    
    def __call__(self, x):
        fun_val = self.obj_fun(x,p1,p2,p3)
        self.num_calls += 1
        if self.num_calls % 5 == 0:
            print('Work in progress...')
            print(p1)
            print(p2)
            print(p3)
            
cb = CallbackFunctor(objective_fnc)

# Parameters
p1=10
p2=20
p3=30
param=(p1,p2,p3)
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(objective_fnc, x0, args=(p1,p2,p3), method='nelder-mead', callback=cb, options={'xatol': 1e-8, 'disp': True})

print(res.x)

【问题讨论】:

    标签: python tuples minimization scipy-optimize-minimize


    【解决方案1】:

    如果您的函数具有签名objective_func(x, bound_limits),其中bounds_limits 是一个元组,您需要确保解包args 产生一个元组。因此,您需要传递一个元组的 Iterable:

    bound_limits = (param1,param2,param3,param4,param5,param6,param7,param8)
    res = minimize(objective_fnc, x0, args=(bound_limits,), method='Nelder-Mead)
    

    请注意,不需要args 参数。您可以使用 lambda 函数实现相同的目的:

    res = minimize(lambda x: objective_fnc(x, bound_limits), x0, method='Nelder-Mead')
    

    【讨论】:

    • 我没有按照你的建议工作。问题是,当我再次调用目标函数时,它不会在 bound_limits 中传递参数
    • @nekovolta 请提供minimal reproducible example。
    • 我放了一个最小的可重现示例。它按照我的解释工作,但另一方面,如果我将 p1,p2,p3 更改为 param 我会收到我提到的错误
    • @nekovolta 我提出的两种解决方案都适用于def objective_func(x, params)。您是否忽略了args=(bound_limits,) 中多余的逗号? PS:这不是一个最小的例子。回调函数与您的问题无关。
    • 我很抱歉。我在实际问题中尝试了您建议的方式,但没有成功,但这是因为我在再次审查时意识到了一个额外的错误。谢谢你。现在我想了解为什么放置, 会改变一切。最后放了回调函数,因为我真正的问题是相关的,虽然这个简化版不是。
    【解决方案2】:

    尝试使用 unpatch with :

    objective_fnc(Xo, *bound_limits)
    

    https://stackabuse.com/unpacking-in-python-beyond-parallel-assignment

    【讨论】:

      猜你喜欢
      • 2016-04-26
      • 2014-11-27
      • 2021-09-29
      • 2015-07-19
      • 1970-01-01
      • 2013-06-03
      • 2011-12-21
      • 2013-01-09
      • 1970-01-01
      相关资源
      最近更新 更多