当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python SciPy optimize.minimize用法及代码示例


本文简要介绍 python 语言中 scipy.optimize.minimize 的用法。

用法:

scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)#

最小化一个或多个变量的标量函数。

参数

fun 可调用的

要最小化的目标函数。

fun(x, *args) -> float

其中 x 是形状为 (n,) 的一维数组,args 是完整指定函数所需的固定参数的元组。

x0 ndarray,形状(n,)

初步猜测。大小为 (n,) 的实数元素数组,其中 n 是自变量的数量。

args 元组,可选

传递给目标函数及其导数(fun、jac 和 hess 函数)的额外参数。

method str 或可调用,可选

求解器的类型。应该是其中之一

如果未给出,则选择为 BFGSL-BFGS-BSLSQP 之一,具体取决于问题是否有约束或界限。

jac {callable, ‘2-point’, ‘3-point’, ‘cs’, bool}, 可选

计算梯度向量的方法。仅适用于 CG、BFGS、Newton-CG、L-BFGS-B、TNC、SLSQP、dogleg、trust-ncg、trust-krylov、trust-exact 和 trust-constr。如果它是可调用的,它应该是一个返回梯度向量的函数:

jac(x, *args) -> array_like, shape (n,)

其中x是一个形状为 (n,) 的数组,并且args是具有固定参数的元组。如果江淮是一个布尔值并且为真,乐趣假定返回一个元组(f, g)包含目标函数和梯度。方法‘Newton-CG’、‘trust-ncg’、‘dogleg’、‘trust-exact’和‘trust-krylov’要求提供可调用对象,或者乐趣返回目标和梯度。如果 None 或 False,梯度将使用绝对步长的 2 点有限差分估计来估计。或者,关键字 {‘2-point’, ‘3-point’, ‘cs’} 可用于选择有限差分方案,用于具有相对步长的梯度数值估计。这些有限差分方案服从任何指定的界限.

hess {callable, ‘2-point’, ‘3-point’, ‘cs’, HessianUpdateStrategy}, 可选

计算 Hessian 矩阵的方法。仅适用于 Newton-CG、dogleg、trust-ncg、trust-krylov、trust-exact 和 trust-constr。如果它是可调用的,它应该返回 Hessian 矩阵:

hess(x, *args) -> {LinearOperator, spmatrix, array}, (n, n)

其中 x 是 (n,) ndarray 并且 args 是具有固定参数的元组。关键字 {‘2-point’, ‘3-point’, ‘cs’} 也可用于选择有限差分方案用于 hessian 的数值估计。或者,实现 HessianUpdateStrategy 接口的对象可用于近似 Hessian。实现此接口的可用 quasi-Newton 方法有:

并非所有选项都可用于每种方法;有关可用性,请参阅注释。

hessp 可调用的,可选的

目标函数的 Hessian 乘以任意向量 p。仅适用于Newton-CG、trust-ncg、trust-krylov、trust-constr。只需要给出 hessp 或 hess 之一。如果提供 hess,则 hessp 将被忽略。 hessp 必须计算 Hessian 乘以任意向量:

hessp(x, p, *args) ->  ndarray shape (n,)

其中 x 是 (n,) ndarray,p 是维度 (n,) 的任意向量,args 是具有固定参数的元组。

bounds 序列或 Bounds ,可选

Nelder-Mead、L-BFGS-B、TNC、SLSQP、Powell、trust-constr 和 COBYLA 方法的变量界限。有两种方法可以指定边界:

  1. Instance of Bounds class.

  2. Sequence of (min, max) pairs for each element in x. None is used to specify no bound.

constraints {Constraint, dict} 或 {Constraint, dict} 列表,可选

约束定义。仅适用于 COBYLA、SLSQP 和 trust-constr。

“trust-constr”的约束被定义为单个对象或指定优化问题约束的对象列表。可用的约束是:

COBYLA、SLSQP 的约束被定义为字典列表。每个带有字段的字典:

type str

Constraint type: ‘eq’ for equality, ‘ineq’ for inequality.

fun callable

The function defining the constraint.

jac callable, optional

The Jacobian of fun (only for SLSQP).

args sequence, optional

Extra arguments to be passed to the function and Jacobian.

等式约束意味着约束函数结果为零,而不等式意味着它是非负的。请注意,COBYLA 仅支持不等式约束。

tol 浮点数,可选

容忍终止。当指定 tol 时,选定的最小化算法将一些相关的 solver-specific 容差设置为等于 tol。如需详细控制,请使用solver-specific 选项。

options 字典,可选

求解器选项字典。除 TNC 之外的所有方法均接受以下通用选项:

maxiter int

Maximum number of iterations to perform. Depending on the method each iteration may use several function evaluations.

For TNC use maxfun instead of maxiter.

disp bool

Set to True to print convergence messages.

对于 method-specific 选项,请参阅 show_options

callback 可调用的,可选的

每次迭代后调用的可调用对象。

除 TNC、SLSQP 和 COBYLA 之外的所有方法都支持带有签名的可调用函数:

callback(OptimizeResult: intermediate_result)

其中 intermediate_result 是关键字参数,包含带有属性 xfun OptimizeResult ,即参数向量和目标函数的当前值。请注意,参数的名称必须是 intermediate_result 以便回调传递 OptimizeResult 。如果回调引发 StopIteration ,这些方法也将终止。

除了 trust-constr 之外的所有方法(也)都支持如下签名:

callback(xk)

其中xk 是当前参数向量。

内省用于确定调用上面的哪个签名。

返回

res OptimizeResult

优化结果表示为 OptimizeResult 对象。重要的属性是:x 解决方案数组,success 指示优化器是否成功退出的布尔标志和说明终止原因的 message。有关其他属性的说明,请参见 OptimizeResult

注意

本节介绍可通过 ‘method’ 参数选择的可用求解器。默认方法是 BFGS。

无约束最小化

方法 CG 使用 Polak 和 Ribiere 的非线性共轭梯度算法,它是 [5] pp.120-122 中说明的Fletcher-Reeves 方法的一种变体。仅使用一阶导数。

方法BFGS使用 Broyden、Fletcher、Goldfarb 和 Shanno (BFGS) 的 quasi-Newton 方法[5]pp. 136. 它只使用一阶导数。即使对于非平滑优化,BFGS 也证明了良好的性能。此方法还返回 Hessian 逆的近似值,存储为hess_inv在OptimizeResult 对象中。

方法Newton-CG使用 Newton-CG 算法[5]第 168 页(也称为截断牛顿法)。它使用CG方法来计算搜索方向。也可以看看TNC使用类似算法进行框约束最小化的方法。适合large-scale问题。

方法 dogleg 使用 dog-leg trust-region 算法 [5] 进行无约束最小化。该算法需要梯度和Hessian;此外,Hessian 必须是正定的。

方法 trust-ncg 使用牛顿共轭梯度 trust-region 算法 [5] 进行无约束最小化。该算法需要梯度和 Hessian 矩阵或计算 Hessian 矩阵与给定向量的乘积的函数。适用于large-scale 问题。

方法trust-krylov使用牛顿 GLTR trust-region 算法[14],[15]用于无约束的最小化。该算法需要梯度和 Hessian 矩阵或计算 Hessian 矩阵与给定向量的乘积的函数。适用于large-scale 问题。在不确定的问题上,它通常需要的迭代次数少于trust-ncg方法,建议用于中等和large-scale 问题。

方法trust-exact是一种用于无约束最小化的trust-region 方法,其中几乎完全解决了二次子问题[13].该算法需要梯度和 Hessian(即不是必须是正定的)。在许多情况下,牛顿法在较少的迭代中收敛,最推荐用于小问题和medium-size 问题。

Bound-Constrained 最小化

方法 Nelder-Mead 使用单纯形算法 [1]、[2]。该算法在许多应用中都很稳健。但是,如果可以信任导数的数值计算,那么使用一阶和/或二阶导数信息的其他算法可能会更受欢迎,因为它们通常具有更好的性能。

方法 L-BFGS-B 使用 L-BFGS-B 算法 [6]、[7] 进行有界约束最小化。

方法鲍威尔是鲍威尔方法的修改[3],[4]这是一种共轭方向方法。它沿方向集的每个向量执行顺序一维最小化(直接字段选项信息),在主最小化循环的每次迭代中更新。该函数不需要是可微的,并且不采取任何导数。如果未提供边界,则将使用无界线搜索。如果提供了界限并且初始猜测在界限内,那么整个最小化过程中的每个函数评估都将在界限内。如果提供了边界,则初始猜测在边界之外,并且直接是满秩(默认为满秩),则第一次迭代期间的某些函数评估可能超出界限,但第一次迭代后的每个函数评估都将在界限内。如果直接未满秩,则某些参数可能未优化,并且无法保证解决方案在范围内。

方法TNC使用截断牛顿算法[5],[8]最小化变量受限制的函数。该算法使用梯度信息;它也称为牛顿共轭梯度。它不同于Newton-CG上面说明的方法,因为它包装了一个 C 实现并允许为每个变量指定上限和下限。

约束最小化

方法 COBYLA 使用约束优化线性近似 (COBYLA) 方法 [9]、[10]、[11]。该算法基于对目标函数和每个约束的线性逼近。该方法包装了算法的 FORTRAN 实现。约束函数‘fun’ 可以返回单个数字或数组或数字列表。

方法 SLSQP 使用顺序最小二乘规划来最小化具有边界、等式和不等式约束的任意组合的多个变量的函数。该方法包装了最初由 Dieter Kraft [12] 实现的 SLSQP 优化子程序。请注意,包装器通过将无限值转换为大的浮点值来处理边界中的无限值。

方法trust-constr 是用于约束优化的trust-region 算法。它根据问题定义在两种实现之间切换。它是 SciPy 中实现的最通用的约束最小化算法,最适合 large-scale 问题。对于等式约束问题,它是[17]和[5]第1页中说明的Byrd-Omojokun Trust-Region SQP方法的实现。 549. 当也施加不等式约束时,它会切换到[16]中说明的trust-region内点方法。反过来,该内点算法通过引入松弛变量并解决一系列逐渐变小的障碍参数值的equality-constrained障碍问题来解决不等式约束。前面说明的等式约束 SQP 方法用于解决子问题,随着迭代越来越接近解决方案,精度水平会不断提高。

有限差分选项

对于方法trust-constr,可以使用三种有限差分方案来近似梯度和Hessian:{‘2-point’、‘3-point’、‘cs’}。 ‘cs’ 方案可能是最准确的,但它要求函数正确处理复杂输入并在复杂平面中可微分。 “3 点”方案比“2 点”方案更准确,但需要两倍的运算量。如果通过 finite-differences 估计梯度,则必须使用 quasi-Newton 策略之一来估计 Hessian 矩阵。

方法特定的选项 赫斯 关键词

方法/赫斯

None

可调用的

‘2-point/‘3-point’/‘cs’

HUS

Newton-CG

x

(n, n) 低

x

x

dogleg

(n, n)

trust-ncg

(n, n)

x

x

trust-krylov

(n, n)

x

x

trust-exact

(n, n)

trust-constr

x

(n, n) LO sp

x

x

其中 LO=LinearOperator,sp=稀疏矩阵,HUS=HessianUpdateStrategy

自定义最小化器

传递自定义最小化方法可能很有用,例如在使用此方法的前端时,例如 scipy.optimize.basinhopping 或不同的库。您可以简单地将可调用对象作为method 参数传递。

可调用的被称为method(fun, x0, args, **kwargs, **options)其中kwargs对应于传递给的任何其他参数minimize(如打返回,赫斯等),除了选项dict,其内容也传递为方法成对成对的参数。另外,如果江淮已作为布尔类型传递,江淮乐趣被破坏,使得乐趣只返回函数值和江淮转换为返回雅可比矩阵的函数。该方法应返回一个OptimizeResult对象。

提供的方法callable 必须能够接受(并且可能忽略)任意参数;接受的参数集minimize可能会在未来的版本中扩展,然后这些参数将传递给该方法。您可以在 scipy.optimize 教程中找到一个示例。

参考

[1]

Nelder、J A 和 R 米德。 1965. 函数最小化的单纯形法。计算机杂志 7:308-13。

[2]

Wright M H. 1996. 直接搜索方法:曾经被轻视,现在受人尊敬,在 1995 年数值分析:1995 年邓迪数值分析双年会议论文集(D F Griffiths 和 G A Watson 编辑)。 Addison Wesley Longman,英国哈洛。 191-208。

[3]

Powell, M J D. 1964。一种无需计算导数即可找到多个变量的函数最小值的有效方法。计算机杂志 7:155-162。

[4]

按 W、SA Teukolsky、W T Vetterling 和 B P Flannery。数字食谱(任何版本),剑桥大学出版社。

[5] (1,2,3,4,5,6,7,8)

Nocedal、J 和 S J 赖特。 2006.数值优化。施普林格纽约。

[6]

Byrd、R H 和 P Lu 和 J. Nocedal。 1995. 一种用于有界约束优化的有限内存算法。 SIAM 科学与统计计算杂志 16 (5): 1190-1208。

[7]

朱,C 和 R H 伯德和 J Nocedal。 1997.L-BFGS-B:算法 778:L-BFGS-B,用于大规模约束优化的 FORTRAN 例程。 ACM 数学软件交易 23 (4): 550-560。

[8]

Nash, S G. Newton-Type 通过 Lanczos 方法进行最小化。 1984. SIAM 数值分析杂志 21: 770-778。

[9]

Powell, M J D. 一种直接搜索优化方法,通过线性插值对目标函数和约束函数进行建模。 1994. 优化和数值分析的进展,编辑。 S. Gomez 和J-P Hennart,Kluwer Academic (Dordrecht),51-67。

[10]

Powell M J D. 优化计算的直接搜索算法。 1998. 数字学报 7: 287-336。

[11]

Powell M J D. 无导数优化算法的观点。 2007.剑桥大学技术报告DAMPP 2007/NA03

[12]

Kraft, D. 用于顺序二次规划的软件包。 1988. 技术。 Rep. DFVLR-FB 88-28,DLR 德国航空航天中心 - 德国科隆飞行力学研究所。

[13]

Conn, A. R.、Gould, N. I. 和 Toint, P. L. 信任区域方法。 2000. 暹罗。第 169-200 页。

[14]

F. Lenders、C. Kirches、A. Potschka:“trlib:用于迭代解决信任域问题的 GLTR 方法的 vector-free 实现”,arXiv:1611.04718

[15]

N. Gould, S. Lucidi, M. Roma, P. Toint:“使用 Lanczos 方法解决 Trust-Region 子问题”,SIAM J. Optim., 9(2), 504-525, (1999)。

[16]

Byrd、Richard H.、Mary E. Hribar 和 Jorge Nocedal。 1999.large-scale 非线性规划的内点算法。 SIAM 优化杂志 9.4:877-900。

[17]

Lalee、Marucha、Jorge Nocedal 和 Todd Plantega。 1998.关于large-scale等式约束优化算法的实现。 SIAM 优化杂志 8.3:682-706。

例子

让我们考虑最小化 Rosenbrock 函数的问题。该函数(及其各自的派生词)在 rosen (分别为 rosen_der rosen_hess )中的 scipy.optimize 中实现。

>>> from scipy.optimize import minimize, rosen, rosen_der

Nelder-Mead 方法的一个简单应用是:

>>> x0 = [1.3, 0.7, 0.8, 1.9, 1.2]
>>> res = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6)
>>> res.x
array([ 1.,  1.,  1.,  1.,  1.])

现在使用 BFGS 算法,使用一阶导数和几个选项:

>>> res = minimize(rosen, x0, method='BFGS', jac=rosen_der,
...                options={'gtol': 1e-6, 'disp': True})
Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 26
         Function evaluations: 31
         Gradient evaluations: 31
>>> res.x
array([ 1.,  1.,  1.,  1.,  1.])
>>> print(res.message)
Optimization terminated successfully.
>>> res.hess_inv
array([[ 0.00749589,  0.01255155,  0.02396251,  0.04750988,  0.09495377],  # may vary
       [ 0.01255155,  0.02510441,  0.04794055,  0.09502834,  0.18996269],
       [ 0.02396251,  0.04794055,  0.09631614,  0.19092151,  0.38165151],
       [ 0.04750988,  0.09502834,  0.19092151,  0.38341252,  0.7664427 ],
       [ 0.09495377,  0.18996269,  0.38165151,  0.7664427,   1.53713523]])

接下来,考虑一个具有多个约束的最小化问题(即 [5] 中的示例 16.4)。目标函数为:

>>> fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2

定义了三个约束:

>>> cons = ({'type': 'ineq', 'fun': lambda x:  x[0] - 2 * x[1] + 2},
...         {'type': 'ineq', 'fun': lambda x: -x[0] - 2 * x[1] + 6},
...         {'type': 'ineq', 'fun': lambda x: -x[0] + 2 * x[1] + 2})

并且变量必须是正数,因此有以下界限:

>>> bnds = ((0, None), (0, None))

使用 SLSQP 方法求解优化问题:

>>> res = minimize(fun, (2, 0), method='SLSQP', bounds=bnds,
...                constraints=cons)

它应该收敛到理论解 (1.4 ,1.7)。

相关用法


注:本文由纯净天空筛选整理自scipy.org大神的英文原创作品 scipy.optimize.minimize。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。