scipy最小化函数的输入结构

v6ylcynt  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(139)

我继承了一些试图使用scipy.optimize.minimize最小化函数的代码。我在理解funjac参数的一些输入时遇到了麻烦。
最小化的调用看起来像这样:

result = minimize(func, jac=jac_func, args=(D_neg, D, C), method = 'TNC' ...other arguments)

func看起来像这样:

def func(G, D_neg, D, C):
    #do stuff

jac_func具有以下结构:

def jac_func(G, D_neg, D, C):
    #do stuff

我不明白的是funcjac_funcG输入是从哪里来的。这是在minimize函数中以某种方式指定的,还是method被指定为TNC的事实?我试图对这个优化函数的结构做一些研究,但我很难找到我需要的答案。

8ehkhllq

8ehkhllq1#

简短的回答是,G由优化器作为最小化过程的一部分进行维护,而(D_neg, D, and C)参数则从args元组按原样传递。
默认情况下,scipy.optimize.minimize接受一个接受一个参数x的函数fun(x)``scipy.optimize.minimize然后找到一个参数值xp,使得对于x的其他值,fun(xp)小于fun(x)。优化器负责创建x的值,并将其传递给fun进行计算。
但是,如果你碰巧有一个函数fun(x, y),它有一些额外的参数y需要单独传入(但为了优化的目的,它被认为是一个常量)?这就是args元组的用途。文档试图解释如何使用args元组,但它可能有点难以解析:
args:tuple,optional
传递给目标函数及其导数的额外参数(雅可比矩阵、Hessian矩阵)。
实际上,scipy.optimize.minimize会将args中的任何内容作为参数的剩余部分传递给fun,使用星号参数表示法:然后在优化过程中,函数被称为fun(x, *args)x部分由优化器传入,args元组作为剩余的参数。
因此,在您的代码中,G元素的值由优化器维护,同时评估G的可能值,(D_neg, D, C)元组按原样传递。

tzcvj98z

tzcvj98z2#

为了便于说明,我们可以打印Gminimize迭代到局部最小值时的变化。(在x=1处达到最小值)。请注意,函数的参数(2,-4和7)作为参数提供给下面的obj_func
必须提供初始猜测以启动算法。
如输出所示,从初始值10开始,函数变量G下降到最小值。

from scipy.optimize import minimize

def obj_func(G, a, b, c):
    print(G)
    return a*G**2 + b*G + c

initial_guess = 10
a, b, c = 2, -4, 7

result = minimize(obj_func, x0=initial_guess, args=(a, b, c))

print(f"\nMinimizer = {result.x}")
print(f"  Minimum = {result.fun}")

其输出如下:

[10.]
[10.00000001]
[8.99]
[8.99000001]
[6.82085113]
[6.82085114]
[1.62275043]
[1.62275045]
[1.]
[1.00000001]

Minimizer = [1.]
  Minimum = 5.0

另一个例子:考虑一个二元函数f(x, y) = (x - 1)**2 + (y - 2)**2,该函数在(x, y) = (1, 2)处达到最小值(最小值为0)。
然后从(x, y) = (0, 3)的初始点开始,函数如下收敛到最小值。

def obj_func(variable, x_offset, y_offset):
    x, y = variable
    print(f"x={x:.3f}, y={y:.3f}")
    return (x - x_offset)**2 + (y - y_offset)**2

initial_guess = [0, 3]
result = minimize(obj_func, initial_guess, args=(1, 2))

这将打印以下内容,显示变量收敛到最小值。

x=0.000, y=3.000
x=0.000, y=3.000
x=0.000, y=3.000
x=0.714, y=2.286
x=0.714, y=2.286
x=0.714, y=2.286
x=1.000, y=2.000
x=1.000, y=2.000
x=1.000, y=2.000

关于minimize的一个重要注意事项是,初始猜测必须是受过教育的,特别是如果目标函数很复杂,否则算法可能不会收敛。我发现这是不成功的优化运行的主要来源。

相关问题