SciPy, optimization

SciPy, optimization

SciPy (antsoina hoe sai pie) dia fonosana fampiharana matematika mifototra amin'ny fanitarana Numpy Python. Miaraka amin'ny SciPy, ny session Python interactive anao dia lasa mitovy amin'ny siansa angon-drakitra feno sy ny tontolo prototyping rafitra sarotra toy ny MATLAB, IDL, Octave, R-Lab, ary SciLab. Androany aho dia te hiresaka fohifohy momba ny fampiasana algorithm optimization malaza ao amin'ny fonosana scipy.optimize. Ny fanampiana amin'ny antsipiriany sy ny vaovao farany momba ny fampiasana asa dia azo alaina amin'ny alΓ lan'ny baiko help() na amin'ny fampiasana Shift+Tab.

fampidirana

Mba hamonjena ny tenanao sy ny mpamaky amin'ny fikarohana sy famakiana loharano fototra, ny rohy mankany amin'ny famaritana ny fomba dia ho ao amin'ny Wikipedia indrindra. Amin'ny ankapobeny, ity fampahalalana ity dia ampy hahatakarana ny fomba amin'ny teny ankapobeny sy ny fepetra fampiharana azy. Mba hahatakarana ny fototry ny fomba matematika, araho ireo rohy mankany amin'ny boky manan-kery kokoa, izay hita any amin'ny faran'ny lahatsoratra tsirairay na ao amin'ny motera fikarohana tianao indrindra.

Noho izany, ny module scipy.optimize dia ahitana ny fampiharana ireto dingana manaraka ireto:

  1. Fanamafisana tsy misy fepetra sy tsy misy fepetra ny fiasan'ny scalar amin'ny variables maromaro (minim) mampiasa algorithm isan-karazany (Nelder-Mead simplex, BFGS, Newton conjugate gradients, COBYLA ΠΈ SLSQP)
  2. Optimization manerantany (ohatra: basinhopping, diff_evolution)
  3. Manamaivana ny sisa MNC (least_squares) sy ny algorithm mifanaraka amin'ny curve amin'ny fampiasana efamira kely indrindra tsy tsipika (curve_fit)
  4. Manamaivana ny fiasan'ny scalar amin'ny fari-piainana iray (minim_scalar) ary mitady faka (root_scalar)
  5. Famahana multidimensional amin'ny rafitry ny fampitoviana (fakan-kevitra) mampiasa algorithm isan-karazany (hybrid Powell, Levenberg-Marquardt na fomba lehibe toy ny Newton-Krylov).

Ato amin'ity lahatsoratra ity isika dia handinika afa-tsy ny singa voalohany amin'ity lisitra manontolo ity.

Fanamaivanana tsy misy fepetra ny fiasan'ny scalar amin'ny fari-piainana maromaro

Ny fiasan'ny minima avy amin'ny fonosana scipy.optimize dia manome interface tsara amin'ny famahana ny olan'ny fampihenana misy fepetra sy tsy misy fepetra amin'ny fiasan'ny scalar amin'ny variables maro. Mba hampisehoana ny fomba fiasan'izy io dia mila fiasa mety amin'ny fari-piainana maromaro isika, izay hahenantsika amin'ny fomba samihafa.

Ho an'ireo tanjona ireo, ny fiasan'ny Rosenbrock amin'ny N variables dia tonga lafatra, izay manana endrika:

SciPy, optimization

Na dia eo aza ny zava-misy fa ny fiasan'ny Rosenbrock sy ny matrices Jacobi sy Hessian (ny derivatives voalohany sy faharoa, tsirairay avy) dia efa voafaritra ao amin'ny fonosana scipy.optimize, dia ny tenantsika no mamaritra izany.

import numpy as np

def rosen(x):
    """The Rosenbrock function"""
    return np.sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0, axis=0)

Mba hanazavana, andao hatao 3D ny soatoavin'ny asan'ny Rosenbrock amin'ny variables roa.

Kaody fanaovana sary

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter

# НастраиваСм 3D Π³Ρ€Π°Ρ„ΠΈΠΊ
fig = plt.figure(figsize=[15, 10])
ax = fig.gca(projection='3d')

# Π—Π°Π΄Π°Π΅ΠΌ ΡƒΠ³ΠΎΠ» ΠΎΠ±Π·ΠΎΡ€Π°
ax.view_init(45, 30)

# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ для Π³Ρ€Π°Ρ„ΠΈΠΊΠ°
X = np.arange(-2, 2, 0.1)
Y = np.arange(-1, 3, 0.1)
X, Y = np.meshgrid(X, Y)
Z = rosen(np.array([X,Y]))

# РисуСм ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
plt.show()

SciPy, optimization

Fantatra mialoha fa ny kely indrindra dia 0 amin'ny SciPy, optimization, andeha hojerentsika ny ohatra momba ny fomba hamaritana ny sanda kely indrindra amin'ny asa Rosenbrock amin'ny fampiasana fomba fiasa scipy.optimize isan-karazany.

Nelder-Mead simplex fomba

Aoka hisy teboka voalohany x0 amin'ny habaka 5 dimensional. Andeha hojerentsika ny teboka farany ambany indrindra amin'ny asa Rosenbrock akaiky indrindra amin'ny fampiasana ny algorithm Nelder-Mead simplex (Ny algorithm dia voatondro ho sandan'ny paramètre methode):

from scipy.optimize import minimize
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(rosen, x0, method='nelder-mead',
    options={'xtol': 1e-8, 'disp': True})
print(res.x)

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 339
         Function evaluations: 571
[1. 1. 1. 1. 1.]

Ny fomba simplex no fomba tsotra indrindra hanamaivanana ny asa voafaritra mazava sy milamina. Tsy mitaky ny kajy ny derivatives amin'ny asa iray, fa ampy ny mamaritra ny sandany. Ny fomba Nelder-Mead dia safidy tsara ho an'ny olana fanalefahana tsotra. Na izany aza, satria tsy mampiasa vinavina mivaingana izy, dia mety haharitra ela kokoa ny fitadiavana ny kely indrindra.

fomba Powell

Algorithm optimization hafa izay kajy ny sandan'ny asa ihany Fomban'i Powell. Mba hampiasana azy dia mila mametraka method = 'powell' ianao amin'ny asa minima.

x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(rosen, x0, method='powell',
    options={'xtol': 1e-8, 'disp': True})
print(res.x)

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 19
         Function evaluations: 1622
[1. 1. 1. 1. 1.]

Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm

Mba hahazoana convergence haingana kokoa ny vahaolana, ny fomba BFGS mampiasa ny gradient ny asa tanjona. Ny gradient dia azo faritana ho asa na kajy amin'ny fampiasana ny fahasamihafan'ny filaharana voalohany. Na izany na tsy izany, ny fomba BFGS dia mitaky fiantsoana asa vitsy kokoa noho ny fomba simplex.

Andeha hojerentsika ny derivative ny asa Rosenbrock amin'ny endrika analytical:

SciPy, optimization

SciPy, optimization

Ity teny ity dia manan-kery ho an'ny derivatives amin'ny variable rehetra afa-tsy ny voalohany sy farany, izay voafaritra ho:

SciPy, optimization

SciPy, optimization

Andeha hojerentsika ny fiasan'ny Python izay manisa ity gradient ity:

def rosen_der (x):
    xm = x [1: -1]
    xm_m1 = x [: - 2]
    xm_p1 = x [2:]
    der = np.zeros_like (x)
    der [1: -1] = 200 * (xm-xm_m1 ** 2) - 400 * (xm_p1 - xm ** 2) * xm - 2 * (1-xm)
    der [0] = -400 * x [0] * (x [1] -x [0] ** 2) - 2 * (1-x [0])
    der [-1] = 200 * (x [-1] -x [-2] ** 2)
    return der

Ny fiasan'ny kajy gradient dia voatondro ho sandan'ny mari-pamantarana jac amin'ny asa kely, araka ny aseho etsy ambany.

res = minimize(rosen, x0, method='BFGS', jac=rosen_der, options={'disp': True})
print(res.x)

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 25
         Function evaluations: 30
         Gradient evaluations: 30
[1.00000004 1.0000001  1.00000021 1.00000044 1.00000092]

Algorithm gradient conjugate (Newton)

algorithm Ny gradient conjugate an'i Newton dia fomban'i Newton novaina.
Ny fomban'i Newton dia mifototra amin'ny fanombantombanana ny asa iray ao amin'ny faritra eo an-toerana amin'ny polynomial amin'ny ambaratonga faharoa:

SciPy, optimization

izay SciPy, optimization dia ny matrix ny derivatives faharoa (Hessian matrix, Hessian).
Raha toa ka voafaritra tsara ny Hessian, dia ny kely indrindra eo an-toerana amin'ity asa ity dia azo jerena amin'ny fampitoviana ny gradient aotra amin'ny endrika quadratic amin'ny aotra. Ny vokatr'izany dia ny fanehoan-kevitra:

SciPy, optimization

Ny Hessian inverse dia kajy amin'ny alΓ lan'ny fomba gradient conjugate. Ohatra iray amin'ny fampiasana ity fomba ity mba hampihenana ny fiasan'ny Rosenbrock dia omena eto ambany. Raha hampiasa ny fomba Newton-CG ianao dia tsy maintsy mamaritra asa iray izay manisa ny Hessian.
Ny Hessian ny asa Rosenbrock amin'ny endrika analytical dia mitovy amin'ny:

SciPy, optimization

SciPy, optimization

izay SciPy, optimization ΠΈ SciPy, optimization, mamaritra ny matrix SciPy, optimization.

Ny singa tsy aotra sisa amin'ny matrix dia mitovy amin'ny:

SciPy, optimization

SciPy, optimization

SciPy, optimization

SciPy, optimization

Ohatra, ao amin'ny habaka dimy dimensions N = 5, ny matrix Hessian ho an'ny asa Rosenbrock dia manana endrika tarika:

SciPy, optimization

Kaody izay manisa ity Hessian ity miaraka amin'ny kaody mba hampihenana ny fiasan'ny Rosenbrock amin'ny alΓ lan'ny fomba gradient conjugate (Newton):

def rosen_hess(x):
    x = np.asarray(x)
    H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1)
    diagonal = np.zeros_like(x)
    diagonal[0] = 1200*x[0]**2-400*x[1]+2
    diagonal[-1] = 200
    diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:]
    H = H + np.diag(diagonal)
    return H

res = minimize(rosen, x0, method='Newton-CG', 
               jac=rosen_der, hess=rosen_hess,
               options={'xtol': 1e-8, 'disp': True})
print(res.x)

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 24
         Function evaluations: 33
         Gradient evaluations: 56
         Hessian evaluations: 24
[1.         1.         1.         0.99999999 0.99999999]

Ohatra iray amin'ny famaritana ny fiasan'ny vokatra Hessian sy ny vector tsy misy dikany

Amin'ny olan'ny tontolo tena izy, ny kajy sy ny fitehirizana ny matrix Hessian manontolo dia mety mitaky fotoana sy loharanon-tadidy lehibe. Amin'ity tranga ity, dia tsy ilaina ny mamaritra ny Hessian matrix mihitsy, satria ny fomba fampihenana dia tsy mitaky afa-tsy vector mitovy amin'ny vokatry ny Hessian miaraka amin'ny vector tsy ara-dalΓ na hafa. Noho izany, amin'ny fomba fijery kajy, dia tsara kokoa ny mamaritra avy hatrany ny asa izay mamerina ny vokatry ny vokatra Hessian miaraka amin'ny vector tsy mety.

Hevero ny fiasan'ny hess, izay maka ny vΓ©ctor minimization ho tohan-kevitra voalohany, ary ny vector tsy misy dikany ho toy ny hevitra faharoa (miaraka amin'ireo tohan-kevitra hafa amin'ny asa ho ahena). Amin'ity tranga ity, ny kajy ny vokatry ny Hessian ny asa Rosenbrock amin'ny arbitrary vector tsy dia sarotra. RAHA p dia vector tsy misy dikany, avy eo ny vokatra SciPy, optimization mitovy amin'ny:

SciPy, optimization

Ny asa izay manisa ny vokatry ny Hessian sy ny vΓ©ctor arbitraire dia alefa amin'ny sandan'ny hessp argument amin'ny fampihenana ny asa:

def rosen_hess_p(x, p):
    x = np.asarray(x)
    Hp = np.zeros_like(x)
    Hp[0] = (1200*x[0]**2 - 400*x[1] + 2)*p[0] - 400*x[0]*p[1]
    Hp[1:-1] = -400*x[:-2]*p[:-2]+(202+1200*x[1:-1]**2-400*x[2:])*p[1:-1] 
    -400*x[1:-1]*p[2:]
    Hp[-1] = -400*x[-2]*p[-2] + 200*p[-1]
    return Hp

res = minimize(rosen, x0, method='Newton-CG',
               jac=rosen_der, hessp=rosen_hess_p,
               options={'xtol': 1e-8, 'disp': True})

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 24
         Function evaluations: 33
         Gradient evaluations: 56
         Hessian evaluations: 66

Conjugate gradient fitokisana faritra algorithm (Newton)

Ny tsy fahampian'ny matrices Hessian sy ny toromarika fikarohana diso dia mety hahatonga ny algorithm gradient conjugate an'i Newton ho tsy mahomby. Amin'ny toe-javatra toy izany, ny safidy dia omena fomba fitokisana faritra (faritra fitokisana) conjugate ny gradients Newton.

Ohatra amin'ny famaritana ny matrix Hessian:

res = minimize(rosen, x0, method='trust-ncg',
               jac=rosen_der, hess=rosen_hess,
               options={'gtol': 1e-8, 'disp': True})
print(res.x)

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 20
         Function evaluations: 21
         Gradient evaluations: 20
         Hessian evaluations: 19
[1. 1. 1. 1. 1.]

Ohatra miaraka amin'ny fiasan'ny vokatra Hessian sy vector tsy misy dikany:

res = minimize(rosen, x0, method='trust-ncg', 
                jac=rosen_der, hessp=rosen_hess_p, 
                options={'gtol': 1e-8, 'disp': True})
print(res.x)

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 20
         Function evaluations: 21
         Gradient evaluations: 20
         Hessian evaluations: 0
[1. 1. 1. 1. 1.]

Krylov karazana fomba

Tahaka ny fomba fitokisana-ncg, ny fomba Krylov-karazana dia mety tsara amin'ny famahana olana goavana satria tsy mampiasa afa-tsy vokatra matrix-vector izy ireo. Ny votoatin'izy ireo dia ny famahana olana ao amin'ny faritra matoky tena voafetra amin'ny habakabaka Krylov tapaka. Ho an'ny olana tsy azo antoka dia tsara kokoa ny mampiasa an'io fomba io, satria mampiasa isa kely kokoa amin'ny famerenam-bidy tsy an-tariby noho ny fahavitsian'ny vokatra matrix-vector isaky ny subproblem, raha oharina amin'ny fomba fitokisana-ncg. Ankoatra izany, ny vahaolana amin'ny subproblem quadratic dia hita tsara kokoa noho ny fampiasana ny fomba fitokisana-ncg.
Ohatra amin'ny famaritana ny matrix Hessian:

res = minimize(rosen, x0, method='trust-krylov',
               jac=rosen_der, hess=rosen_hess,
               options={'gtol': 1e-8, 'disp': True})

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 19
         Function evaluations: 20
         Gradient evaluations: 20
         Hessian evaluations: 18

print(res.x)

    [1. 1. 1. 1. 1.]

Ohatra miaraka amin'ny fiasan'ny vokatra Hessian sy vector tsy misy dikany:

res = minimize(rosen, x0, method='trust-krylov',
               jac=rosen_der, hessp=rosen_hess_p,
               options={'gtol': 1e-8, 'disp': True})

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 19
         Function evaluations: 20
         Gradient evaluations: 20
         Hessian evaluations: 0

print(res.x)

    [1. 1. 1. 1. 1.]

Algorithm ho an'ny vahaolana eo amin'ny faritra fahatokisana

Ny fomba rehetra (Newton-CG, trust-ncg ary trust-krylov) dia mety tsara amin'ny famahana olana lehibe (miaraka amin'ny variables an'arivony). Izany dia noho ny zava-misy fa ny algorithm gradient conjugate fototra dia midika famaritana eo ho eo ny matrix Hessian inverse. Ny vahaolana dia hita miverimberina, tsy misy fanitarana mazava ny Hessian. Satria mila mamaritra asa ho an'ny vokatry ny Hessian sy ny vector tsy misy dikany ianao, ity algorithm ity dia tsara indrindra amin'ny fiasana amin'ny matrices sparse (band diagonal). Izany dia manome vidiny fitadidiana ambany sy mitsitsy fotoana lehibe.

Ho an'ny olana antonony, ny vidin'ny fitahirizana sy ny faktiora ny Hessian dia tsy mitsikera. Midika izany fa azo atao ny mahazo vahaolana amin'ny famerimberenana vitsy kokoa, mamaha ny olana amin'ny faritra azo antoka. Mba hanaovana izany, dia voavaha tsikelikely ho an'ny zana-olana quadratic tsirairay ny equations tsy an-linear sasany. Ny vahaolana toy izany matetika dia mitaky 3 na 4 Cholesky decompositions ny Hessian matrix. Vokatr'izany, ny fomba dia mifamatotra amin'ny famerimberenana vitsy kokoa ary mitaky kajy asa tanjona vitsy kokoa noho ireo fomba hafa azo ampiharina amin'ny faritra fahatokisana. Ity algorithm ity dia tsy misy afa-tsy ny famaritana ny matrix Hessian feno ary tsy manohana ny fahafahana mampiasa ny asan'ny vokatra Hessian sy ny vector tsy misy dikany.

Ohatra amin'ny fampihenana ny fiasan'ny Rosenbrock:

res = minimize(rosen, x0, method='trust-exact',
               jac=rosen_der, hess=rosen_hess,
               options={'gtol': 1e-8, 'disp': True})
res.x

Optimization terminated successfully.
         Current function value: 0.000000
         Iterations: 13
         Function evaluations: 14
         Gradient evaluations: 13
         Hessian evaluations: 14

array([1., 1., 1., 1., 1.])

Mety hijanona eo isika. Ao amin'ny lahatsoratra manaraka dia hiezaka aho ny hilaza ny zavatra mahaliana indrindra momba ny fampihenana ny fepetra, ny fampiharana ny fanamaivanana amin'ny famahana ny olan'ny approximation, ny fampihenana ny asan'ny variable iray, ny fanamafisam-peo tsy misy dikany, ary ny fitadiavana ny fakan'ny rafitra equation amin'ny fampiasana ny scipy.optimize. fonosana.

Source: https://docs.scipy.org/doc/scipy/reference/

Source: www.habr.com

Add a comment