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
是完全指定函数所需的固定参数的元组。- x0ndarray,形状(n,)
初步猜测是这样的。大小为(n,)的实数元素数组,其中
n
是自变量的个数。- args元组,可选
传递给目标函数及其派生函数的额外参数 (fun , jac 和 hess 函数)。
- method字符串或可调用,可选
求解器的类型。应该是
“南德-米德” (see here)
“鲍威尔” (see here)
“CG” (see here)
“BFGS” (see here)
“牛顿-CG” (see here)
‘L-BFGS-B’ (see here)
“TNC” (see here)
“COBYLA” (see here)
“SLSQP” (see here)
‘Trust-Constr’:ref:(参见此处)
“狗腿” (see here)
“信任-NCG” (see here)
“信任-精确” (see here)
“信任-克里洛夫” (see here)
自定义-可调用对象(在版本0.14.0中添加),说明见下文。
如果没有给予,则选择成为
BFGS
,L-BFGS-B
,SLSQP
,取决于问题是否有约束或边界。- jac{Callable,‘2-point’,‘3-point’,‘cs’,bool},可选
梯度矢量的计算方法。仅适用于CG、BFGS、Newton-CG、L-BFGS-B、TNC、SLSQP、DOGLEG、TRUST-NCG、TRUST-Krylov、TRUST-EXCECT和TRUST-CONTR。如果它是可调用的,则它应该是返回渐变向量的函数:
jac(x, *args) -> array_like, shape (n,)
哪里
x
是形状为(n,)的数组,并且args
是具有固定参数的元组。如果 jac 是布尔值并且为True, fun 假定返回元组(f, g)
包含目标函数和梯度。方法“Newton-CG”、“Trust-NCG”、“Dogleg”、“Trust-Exact”和“Trust-Krylov”要求提供Callable或 fun 返回目标和渐变。如果没有或为假,将使用绝对步长的两点有限差分估计来估计梯度。或者,关键字{‘2-point’,‘3-point’,‘cs’}可以用来选择用于具有相对步长的梯度的数值估计的有限差分格式。这些有限差分格式服从任何指定的 bounds 。- hess{Callable,‘2-point’,‘3-point’,‘cs’,HessianUpdateStrategy},可选
计算黑森矩阵的方法。仅适用于牛顿-CG、狗腿、信任-NCG、信任-克里洛夫、信任-精确和信任-构造。如果它是可调用的,则应返回Hessian矩阵:
hess(x, *args) -> {LinearOperator, spmatrix, array}, (n, n)
哪里
x
是一条(n,)ndarrayargs
是具有固定参数的元组。只允许“”Trust-Constr“”方法返回LinearOperator和稀疏矩阵。“”或者(对于Newton-CG或Dogleg不可用),关键字{‘2-point’,‘3-point’,‘cs’}选择用于数值估计的有限差分格式。或者,实现HessianUpdateStrategy
界面可以用来近似黑森语。实现此接口的可用的拟牛顿方法包括:无论何时通过有限差分来估计梯度,都不能使用选项{‘2点’,‘3点’,‘cs’}来估计黑森函数,而需要使用拟牛顿策略中的一种来估计。“Trust-Exact”不能使用有限差分方案,必须与返回(n,n)数组的可调用一起使用。
- hessp可调用,可选
目标函数的Hessian乘以任意向量p。仅对于牛顿-CG、信任-NCG、信任-克里洛夫、信任-构造。只有一个 hessp 或 hess 需要给予。如果 hess 被提供,则 hessp 将被忽略。 hessp 必须计算任意向量的黑森乘积:
hessp(x, p, *args) -> ndarray shape (n,)
哪里
x
是一条(n,)ndarray,p
是维数为(n,)的任意向量,并且args
是具有固定参数的元组。- 边界 :序列或
Bounds
,可选序列或 内尔德-米德方法、L-BFGS-B方法、TNC方法、SLSQP方法、Powell方法和TRUST-CONSTR方法的变量界限。有两种方式可以指定边界:
实例
Bounds
班级。序列
(min, max)
中每个元素的对 x 。None用于指定无边界。
- constraints{约束,判定}或{约束,判定}列表,可选
约束定义。仅适用于COBYLA、SLSQP和信任构造。
“Trust-Constr”的约束被定义为指定对优化问题的约束的单个对象或对象列表。可用的约束包括:
COBYLA、SLSQP的约束定义为字典列表。每个带有字段的字典:
- 类型应力
约束类型:‘EQ’表示相等,‘ineq’表示不平等。
- 有趣的可调用
定义约束的函数。
- JAC可调用,可选
的雅可比 fun (仅适用于SLSQP)。
- 参数序列,可选
要传递给函数和雅可比的额外参数。
等式约束表示约束函数结果为零,而不等式表示约束函数结果为非负。请注意,COBYLA仅支持不等式约束。
- tol浮动,可选
对终止的容忍度。什么时候 tol 时,选定的最小化算法会将一些相关的求解器特定容差设置为等于 tol 。有关详细控制,请使用解算器特定的选项。
- optionsDICT,可选
求解器选项词典。所有方法都接受以下常规选项:
- 最大值集成
要执行的最大迭代次数。根据方法的不同,每次迭代可能使用多个函数求值。
- 显示布尔尔
设置为True可打印收敛消息。
有关特定于方法的选项,请参见
show_options
。- callback可调用,可选
在每次迭代之后调用。对于‘Trust-Constr’,它是一个可调用的签名:
callback(xk, OptimizeResult state) -> bool
哪里
xk
是当前参数向量。和state
是一种OptimizeResult
对象,其字段与返回中的字段相同。如果回调返回True,则终止算法执行。对于所有其他方法,签名为:callback(xk)
哪里
xk
是当前参数向量。
- 退货
- resOptimizeResult
优化结果表示为
OptimizeResult
对象。重要属性包括:x
解决方案阵列,success
指示优化器是否成功退出的布尔标志message
它描述了终止的原因。看见OptimizeResult
有关其他属性的说明,请参见。
参见
minimize_scalar
与单变量标量函数极小化算法的接口
show_options
求解程序接受的其他选项
注意事项
本节介绍可通过‘method’参数选择的可用求解器。默认方法为 BFGS 。
无约束极小化
方法 CG 使用Polak和Ribiere提出的非线性共轭梯度算法,该算法是 [5] 第120-122页。只使用一阶导数。
方法 BFGS 使用Broyden,Fletcher,Goldfarb和Shanno(BFGS)的拟牛顿法 [5] 第136页。它只使用一阶导数。事实证明,即使对于非平滑的优化,BFGS也具有良好的性能。此方法还返回Hessian逆的近似值,存储为 hess_inv 在OptimizeResult对象中。
方法 Newton-CG 使用牛顿-CG算法 [5] 第168页(也称为截断牛顿法)。它使用CG方法来计算搜索方向。另请参阅 TNC 具有类似算法的箱式约束最小化的方法。适用于大型问题。
方法 dogleg 使用狗腿信任域算法 [5] 用于无约束最小化。该算法要求梯度和Hessian,并且要求Hessian是正定的。
方法 trust-ncg 使用牛顿共轭梯度信赖域算法 [5] 用于无约束最小化。此算法需要梯度和黑森函数或计算黑森函数与给定向量的乘积的函数。适用于大型问题。
方法 trust-krylov 使用牛顿GLTR信赖域算法 [14], [15] 用于无约束最小化。此算法需要梯度和黑森函数或计算黑森函数与给定向量的乘积的函数。适用于大型问题。对于不确定问题,它需要的迭代次数通常比 trust-ncg 方法,适用于中、大型问题。
方法 trust-exact 是一种求解无约束极小化问题的信赖域方法,其中的二次子问题几乎可以精确求解。 [13]. 该算法需要梯度和黑森(即 not 要求是肯定的)。在许多情况下,牛顿法收敛的迭代次数较少,是中小型问题最推荐使用的方法。
Bound-Constrained minimization
方法 Nelder-Mead 使用单纯形算法 [1], [2]. 该算法在许多应用中都是健壮的。然而,如果导数的数值计算是可信的,则使用一阶和/或二阶导数信息的其他算法通常可能因其更好的性能而被优选。
方法 L-BFGS-B 使用L-BFGS-B算法 [6], [7] 用于有界约束最小化。
方法 Powell 是对鲍威尔方法的修正 [3], [4] 这是一种共轭方向法。它沿着方向集的每个矢量执行顺序的一维最小化 (direc 字段输入 options 和 info ),它在主最小化循环的每次迭代时更新。该函数不需要是可微的,也不需要求导。如果未提供界限,则将使用无界线搜索。如果提供了界限并且初始猜测在界限内,那么在最小化过程中的每个函数计算都将在界限内。如果提供了界限,则初始猜测超出界限,并且 direc 为FULL RANK(默认为FULL RANK),则第一次迭代期间的某些函数求值可能超出界限,但第一次迭代后的每个函数求值都在界限之内。如果 direc 如果不是满秩,则某些参数可能不会优化,也不能保证解在界内。
方法 TNC 使用截断牛顿算法 [5], [8] 使变量受限的函数最小化。该算法利用梯度信息,也称为牛顿共轭梯度。它不同于 Newton-CG 方法,因为它包装了一个C实现,并允许给每个变量指定上下限。
约束极小化
方法 COBYLA 使用线性逼近约束优化(COBYLA)方法 [9], [10], [11]. 该算法基于对目标函数和每个约束的线性近似。该方法包装了算法的FORTRAN实现。约束函数‘FUN’可以返回单个数字,也可以返回数字的数组或列表。
方法 SLSQP 使用顺序最小二乘编程来最小化具有边界、等式和不等式约束的任意组合的多变量函数。该方法包装了最初由Dieter Kraft实现的SLSQP优化子例程 [12]. 请注意,包装器通过将无限值转换为大的浮点值来处理边界中的无限值。
方法 trust-constr 是一种求解约束优化的信赖域算法。它根据问题定义在两种实现之间切换。它是SciPy中实现的最通用的约束最小化算法,也是最适合大规模问题的算法。对于等式约束问题,它是中描述的Byrd-Omojokun信任域SQP方法的一种实现 [17] 以及在 [5], 第549页。当同样施加不等式约束时,它将切换到中描述的信赖域内点方法。 [16]. 这个内点算法反过来通过引入松弛变量并解决一系列等式约束的屏障问题来解决不等式约束,使屏障参数的值逐渐变小。前面描述的等式约束SQP方法被用来求解这些子问题,并且随着迭代越来越接近解的精度水平不断提高。
Finite-Difference Options
FOR方法 trust-constr 梯度和黑森可以用三种有限差分格式来近似:{‘2点’,‘3点’,‘cs’}。潜在地,方案‘CS’是最精确的,但是它要求函数正确地处理复数输入并且在复数平面中是可微分的。“3点”方案比“2点”方案更精确,但需要的运算量是“2点”方案的两倍。
自定义最小化程序
传递自定义最小化方法可能很有用,例如在使用此方法的前端时,例如
scipy.optimize.basinhopping
或者是不同的类库。您可以简单地将可调用对象作为method
参数。该可调用对象称为
method(fun, x0, args, **kwargs, **options)
哪里kwargs
对应于传递给minimize
(例如 callback , hess 等),但 options dict,它的内容也作为 method 每对参数。另外,如果 jac 已作为bool类型传递, jac 和 fun 都被损毁了,以至于 fun 仅返回函数值和 jac 转换为返回雅可比的函数。该方法应返回一个OptimizeResult
对象。提供的 method Callable必须能够接受(并可能忽略)任意参数;
minimize
可以在将来的版本中扩展,然后这些参数将传递给该方法。您可以在scipy.Optimize教程中找到一个示例。0.11.0 新版功能.
参考文献
- 1
内尔德,J·A和R·米德。1965年。函数极小化的单纯形法。“计算机杂志”7:308-13。
- 2
莱特·M·H·1996。直接搜索法:在“1995年数值分析:1995年邓迪数值分析双年会议论文集”(EDS)中,曾经被鄙视过,现在却是受人尊敬的。D·F·格里菲斯和G·A·沃森)。艾迪森·韦斯利·朗曼(Addison Wesley Longman),英国哈洛。191-208。
- 3
鲍威尔,医学博士,1964年。求多元函数最小值而不计算导数的一种有效方法。“计算机杂志”7:155-162。
- 4
按W、S A Teukolsky、W T Vetterling和B P Flannery。“数字食谱”(任一版),剑桥大学出版社。
- 5(1,2,3,4,5,6,7,8)
Nocedal,J和S·J·赖特(SJ Wright)。2006年。数值优化。纽约斯普林格。
- 6
Byrd,R H和P Lu和J.Nocedal.1995年。一种求解有界约束优化的有限内存算法。“暹罗科学与统计计算学报”16(5):1190-1208。
- 7
Ju,C和R H.Byrd和J Nocedal.1997年。L-BFGS-B:算法778:L-BFGS-B,用于大规模边界约束优化的FORTRAN例程。ACM数学软件学报23(4):550-560。
- 8
基于Lanczos方法的牛顿型极小化。1984年。暹罗数值分析学报21:770-778。
- 9
一种通过线性插值对目标函数和约束函数建模的直接搜索优化方法。1994年。最优化与数值分析进展,主编。S·戈麦斯和J-P·亨纳特,克鲁沃学院(多德雷希特),51-67。
- 10
鲍威尔·M·J·D。用于优化计算的直接搜索算法。1998年。“数字学报”7:287-336。
- 11
鲍威尔·M·J·D。不含导数的最优化算法的观点。2007.剑桥大学技术报告DAMTP 2007/NA03
- 12
序列二次规划软件包。1988年。技术部。代表DFVLR-FB88-28,德国航空航天中心--飞行力学研究所,德国科隆。
- 13
Conn,A.R.,Gould,N.I.和Toint,P.L.信赖域方法。2000年。暹罗。第169-200页。
- 14
F.Lender,C.Kirches,A.Potschka:“trlib:迭代求解信赖域问题的GLTR方法的无向量实现”, arXiv:1611.04718
- 15
古尔德,S.Lucidi,M.Roman,P.Toint:“使用Lanczos方法解决信任域子问题”,SIAM J.Optim,9(2),504-525,(1999)。
- 16
题名/责任者:The First,and and Jorge Nocedal.1999年。大规模非线性规划的一种内点算法。暹罗优化杂志9.4:877-900。
- 17
Lalee,Marucha,Jorge Nocedal和Todd Plantega。1998年。关于大规模等式约束优化算法的实现。暹罗优化期刊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]])
接下来,考虑一个具有几个约束的最小化问题(即示例16.4,来自 [5]) 。目标函数为:
>>> 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)。