當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。