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
是完全指定函数所需的固定参数的元组。假设可调用对象的签名是
f0(x, *my_args, **my_kwargs)
,其中my_args
和my_kwargs
是必需的位置参数和关键字参数。与其将f0
作为可调用对象传递,不如将其包装为仅接受x
;例如,传递fun=lambda x: f0(x, *my_args, **my_kwargs)
作为可调用对象,其中my_args
(元组) 和my_kwargs
(字典) 已在此函数调用之前收集。- x0ndarray,形状 (n,)
初始猜测。大小为 (n,) 的实数元素数组,其中
n
是自变量的数量。- argstuple,可选
传递给目标函数及其导数(fun、jac 和 hess 函数)的额外参数。
- methodstr 或 可调用对象,可选
求解器类型。应为以下之一
‘Nelder-Mead’ (请参阅此处)
‘Powell’ (请参阅此处)
‘CG’ (请参阅此处)
‘BFGS’ (请参阅此处)
‘Newton-CG’ (请参阅此处)
‘L-BFGS-B’ (请参阅此处)
‘TNC’ (请参阅此处)
‘COBYLA’ (请参阅此处)
‘COBYQA’ (请参阅此处)
‘SLSQP’ (请参阅此处)
‘trust-constr’(请参阅此处)
‘dogleg’ (请参阅此处)
‘trust-ncg’ (请参阅此处)
‘trust-exact’ (请参阅此处)
‘trust-krylov’ (请参阅此处)
custom - 一个可调用对象,请参阅下面的描述。
如果未给出,则根据问题是否具有约束或边界,选择为
BFGS
、L-BFGS-B
、SLSQP
之一。- jac{可调用对象, ‘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
是包含固定参数的元组。如果 jac 是一个布尔值并且为 True,则假定 fun 返回一个包含目标函数和梯度的元组(f, g)
。方法 ‘Newton-CG’、‘trust-ncg’、‘dogleg’、‘trust-exact’ 和 ‘trust-krylov’ 要求提供可调用对象,或 fun 返回目标函数和梯度。如果为 None 或 False,则将使用绝对步长的 2 点有限差分估计来估计梯度。或者,可以使用关键字 {‘2-point’,‘3-point’,‘cs’} 来选择有限差分方案,以使用相对步长数值估计梯度。这些有限差分方案服从任何指定的 bounds。- hess{可调用对象, ‘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。实现此接口的可用拟牛顿方法是并非所有选项都适用于每种方法;有关可用性,请参阅说明。
- 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 和 COBYQA 方法的变量边界。有两种方法可以指定边界
Bounds
类的实例。对于 x 中的每个元素的
(min, max)
对的序列。None 用于指定无边界。
- constraints{Constraint, dict} 或 {Constraint, dict} 的列表,可选
约束定义。仅适用于 COBYLA、COBYQA、SLSQP 和 trust-constr。
‘trust-constr’ 和 ‘cobyqa’ 的约束定义为指定优化问题的约束的单个对象或对象列表。可用的约束是
COBYLA、SLSQP 的约束定义为字典列表。每个字典具有以下字段
- typestr
约束类型:‘eq’ 表示相等,‘ineq’ 表示不等。
- fun可调用对象
定义约束的函数。
- jac可调用对象,可选
fun 的 Jacobian (仅适用于 SLSQP)。
- args序列,可选
要传递给函数和 Jacobian 的额外参数。
等式约束意味着约束函数结果为零,而不等约束意味着它为非负数。请注意,COBYLA 仅支持不等式约束。
- tolfloat,可选
终止容差。当指定 tol 时,所选的最小化算法会将某些相关的特定于求解器的容差设置为等于 tol。要进行详细控制,请使用特定于求解器的选项。
- options字典,可选
求解器选项的字典。除了 TNC 之外的所有方法都接受以下通用选项
- maxiterint
要执行的最大迭代次数。根据方法,每次迭代可能使用多个函数评估。
对于 TNC,请使用 maxfun 代替 maxiter。
- dispbool
设置为 True 以打印收敛信息。
有关特定于方法的选项,请参阅
show_options
。- callbackcallable,可选
每次迭代后调用的可调用对象。
除了 TNC、SLSQP 和 COBYLA 之外的所有方法都支持具有以下签名的可调用对象
callback(intermediate_result: OptimizeResult)
其中
intermediate_result
是一个关键字参数,包含一个具有属性x
和fun
的OptimizeResult
,即参数向量和目标函数的当前值。请注意,为了将OptimizeResult
传递给回调,参数的名称必须为intermediate_result
。如果回调引发StopIteration
,这些方法也会终止。除了 trust-constr 之外的所有方法(也)支持类似以下的签名
callback(xk)
其中
xk
是当前的参数向量。使用自省来确定调用上述哪个签名。
- 返回:
- resOptimizeResult
优化结果表示为
OptimizeResult
对象。重要的属性有:x
解数组,success
一个布尔标志,指示优化器是否成功退出,以及message
,它描述了终止的原因。有关其他属性的说明,请参阅OptimizeResult
。
另请参阅
minimize_scalar
标量单变量函数最小化算法的接口
show_options
求解器接受的其他选项
说明
本节介绍可通过“method”参数选择的可用求解器。默认方法是 *BFGS*。
无约束最小化
方法 CG 使用 Polak 和 Ribiere 的非线性共轭梯度算法,是 [5] 第 120-122 页中描述的 Fletcher-Reeves 方法的变体。仅使用一阶导数。
方法 BFGS 使用 Broyden、Fletcher、Goldfarb 和 Shanno (BFGS) 的拟牛顿方法 [5] 第 136 页。它仅使用一阶导数。事实证明,即使对于非平滑优化,BFGS 也具有良好的性能。此方法还会返回 Hessian 逆的近似值,作为 hess_inv 存储在 OptimizeResult 对象中。
方法 Newton-CG 使用 Newton-CG 算法 [5] 第 168 页(也称为截断牛顿法)。它使用 CG 方法来计算搜索方向。另请参阅 TNC 方法,用于使用类似算法进行箱约束最小化。适用于大规模问题。
方法 dogleg 使用狗腿信任域算法 [5] 进行无约束最小化。此算法需要梯度和 Hessian;此外,Hessian 需要是正定的。
方法 trust-ncg 使用牛顿共轭梯度信任域算法 [5] 进行无约束最小化。此算法需要梯度和 Hessian,或者计算 Hessian 与给定向量的乘积的函数。适用于大规模问题。
方法 trust-krylov 使用牛顿 GLTR 信任域算法 [14]、[15] 进行无约束最小化。此算法需要梯度和 Hessian,或者计算 Hessian 与给定向量的乘积的函数。适用于大规模问题。在不确定问题上,它通常比 trust-ncg 方法需要更少的迭代次数,建议用于中大型问题。
方法 trust-exact 是一种用于无约束最小化的信任域方法,其中二次子问题几乎精确地求解 [13]。此算法需要梯度和 Hessian(不 需要是正定的)。在许多情况下,它是牛顿方法,在更少的迭代中收敛,并且最推荐用于中小型问题。
有界约束最小化
方法 Nelder-Mead 使用单纯形算法 [1]、[2]。此算法在许多应用中都很强大。但是,如果可以信任导数的数值计算,则最好选择使用一阶和/或二阶导数信息的其他算法,因为它们通常具有更好的性能。
方法 L-BFGS-B 使用 L-BFGS-B 算法 [6]、[7] 用于有界约束最小化。
方法 Powell 是对 Powell 方法的修改 [3]、[4],这是一种共轭方向方法。它沿方向集的每个向量(options 和 info 中的 direc 字段)执行连续的一维最小化,该方向集在主最小化循环的每次迭代中更新。该函数不需要可微,并且不进行导数运算。如果没有提供边界,则将使用无界线搜索。如果提供了边界并且初始猜测在边界内,则整个最小化过程中的每次函数评估都将在边界内。如果提供了边界,初始猜测在边界之外,并且 direc 是满秩的(默认具有满秩),则第一次迭代期间的一些函数评估可能在边界之外,但第一次迭代后的每次函数评估都将在边界内。如果 direc 不是满秩的,则某些参数可能不会被优化,并且不能保证解在边界内。
方法 TNC 使用截断的牛顿算法 [5]、[8] 来最小化一个函数,其中变量受边界约束。此算法使用梯度信息;它也称为牛顿共轭梯度。它与上面描述的 Newton-CG 方法不同,因为它包装了 C 实现,并允许为每个变量指定上限和下限。
约束最小化
方法 COBYLA 使用线性逼近约束优化 (COBYLA) 方法 [9]、[10]、[11]。该算法基于目标函数和每个约束的线性近似。该方法包装了该算法的 FORTRAN 实现。约束函数“fun”可以返回单个数字或数字的数组或列表。
方法 COBYQA 使用二次逼近约束优化 (COBYQA) 方法 [18]。该算法是一种基于目标函数和每个非线性约束的二次逼近的无导数信任域 SQP 方法。边界被视为不可松弛的约束,因为算法始终在整个优化过程中尊重它们。
方法 SLSQP 使用顺序最小二乘规划来最小化具有任何边界、相等和不等式约束组合的多个变量的函数。该方法包装了最初由 Dieter Kraft [12] 实现的 SLSQP 优化子例程。请注意,包装器通过将边界中的无限值转换为大的浮点值来处理它们。
方法 trust-constr 是一种用于约束优化的信任域算法。它根据问题定义在两种实现之间切换。它是 SciPy 中实现的最通用的约束最小化算法,并且最适合大规模问题。对于等式约束问题,它是 Byrd-Omojokun 信任域 SQP 方法的实现,如 [17] 和 [5] 第 549 页中所述。当也施加不等式约束时,它会切换到 [16] 中描述的信任域内点方法。反过来,这种内点算法通过引入松弛变量并针对渐小的障碍参数值求解一系列等式约束障碍问题来求解不等式约束。随着迭代更接近解,使用先前描述的等式约束 SQP 方法来求解具有越来越高精度的子问题。
有限差分选项
对于方法 trust-constr,可以使用三种有限差分方案来近似梯度和 Hessian:{‘2-point’、‘3-point’、‘cs’}。方案 'cs' 可能是最准确的,但它要求该函数正确处理复数输入并在复平面中可微。方案 '3-point' 比 '2-point' 更准确,但需要两倍的操作。如果梯度是通过有限差分估计的,则必须使用准牛顿策略之一来估计 Hessian。
hess 关键字的方法特定选项
方法/Hess
无
可调用对象
“2-point/”3-point/“cs”
HUS
Newton-CG
x
(n, n) LO
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
的任何其他参数(例如 callback、hess 等),但 options 字典除外,其内容也会成对地作为 method 参数传递。此外,如果 jac 已作为布尔类型传递,则会对 jac 和 fun 进行处理,以便 fun 仅返回函数值,而 jac 将转换为返回雅可比矩阵的函数。该方法应返回一个OptimizeResult
对象。提供的 method 可调用对象必须能够接受(并可能忽略)任意参数;
minimize
接受的参数集可能会在未来的版本中扩展,届时这些参数将传递给该方法。您可以在 scipy.optimize 教程中找到示例。参考文献
[1]Nelder, J A, 和 R Mead. 1965. A Simplex Method for Function Minimization. The Computer Journal 7: 308-13.
[2]Wright M H. 1996. Direct search methods: Once scorned, now respectable, in Numerical Analysis 1995: Proceedings of the 1995 Dundee Biennial Conference in Numerical Analysis (Eds. D F Griffiths and G A Watson). Addison Wesley Longman, Harlow, UK. 191-208.
[3]Powell, M J D. 1964. An efficient method for finding the minimum of a function of several variables without calculating derivatives. The Computer Journal 7: 155-162.
[4]Press W, S A Teukolsky, W T Vetterling 和 B P Flannery. Numerical Recipes (any edition), Cambridge University Press.
[6]Byrd, R H 和 P Lu 和 J. Nocedal. 1995. A Limited Memory Algorithm for Bound Constrained Optimization. SIAM Journal on Scientific and Statistical Computing 16 (5): 1190-1208.
[7]Zhu, C 和 R H Byrd 和 J Nocedal. 1997. L-BFGS-B: Algorithm 778: L-BFGS-B, FORTRAN routines for large scale bound constrained optimization. ACM Transactions on Mathematical Software 23 (4): 550-560.
[8]Nash, S G. Newton-Type Minimization Via the Lanczos Method. 1984. SIAM Journal of Numerical Analysis 21: 770-778.
[9]Powell, M J D. A direct search optimization method that models the objective and constraint functions by linear interpolation. 1994. Advances in Optimization and Numerical Analysis, eds. S. Gomez and J-P Hennart, Kluwer Academic (Dordrecht), 51-67.
[10]Powell M J D. Direct search algorithms for optimization calculations. 1998. Acta Numerica 7: 287-336.
[11]Powell M J D. A view of algorithms for optimization without derivatives. 2007.Cambridge University Technical Report DAMTP 2007/NA03
[12]Kraft, D. A software package for sequential quadratic programming. 1988. Tech. Rep. DFVLR-FB 88-28, DLR German Aerospace Center – Institute for Flight Mechanics, Koln, Germany.
[13]Conn, A. R., Gould, N. I., 和 Toint, P. L. Trust region methods. 2000. Siam. pp. 169-200.
[14]F. Lenders, C. Kirches, A. Potschka: “trlib: A vector-free implementation of the GLTR method for iterative solution of the trust region problem”, arXiv:1611.04718
[15]N. Gould, S. Lucidi, M. Roma, P. Toint: “Solving the Trust-Region Subproblem using the Lanczos Method”, SIAM J. Optim., 9(2), 504–525, (1999).
[16]Byrd, Richard H., Mary E. Hribar, 和 Jorge Nocedal. 1999. An interior point algorithm for large-scale nonlinear programming. SIAM Journal on Optimization 9.4: 877-900.
[17]Lalee, Marucha, Jorge Nocedal, 和 Todd Plantenga. 1998. On the implementation of an algorithm for large-scale equality constrained optimization. SIAM Journal on Optimization 8.3: 682-706.
[18]Ragonneau, T. M. Model-Based Derivative-Free Optimization Methods and Software. PhD thesis, Department of Applied Mathematics, The Hong Kong Polytechnic University, Hong Kong, China, 2022. URL: https://theses.lib.polyu.edu.hk/handle/200/12294.
示例
让我们考虑最小化 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)。