python - roots - ¿Cómo mostrar el progreso de la función scipy.optimize?
scipy.optimize python (4)
Uso scipy.optimize
para minimizar una función de 12 argumentos.
Comencé la optimización hace un tiempo y aún esperaba resultados.
¿Hay alguna manera de forzar scipy.optimize
para que muestre su progreso (como cuánto se ha hecho, cuál es el mejor punto actual)?
¿Qué función de minimización estás usando exactamente?
La mayoría de las funciones tienen un informe de progreso incorporado, que incluye varios niveles de informes que muestran exactamente los datos que desea, utilizando el indicador disp
(por ejemplo, consulte scipy.optimize.fmin_l_bfgs_b ).
Como sugirió mg007, algunas de las rutinas scipy.optimize permiten una función de devolución de llamada (desafortunadamente, leastsq no permite esto en este momento). A continuación se muestra un ejemplo utilizando la rutina "fmin_bfgs" donde utilizo una función de devolución de llamada para mostrar el valor actual de los argumentos y el valor de la función objetivo en cada iteración.
import numpy as np
from scipy.optimize import fmin_bfgs
Nfeval = 1
def rosen(X): #Rosenbrock function
return (1.0 - X[0])**2 + 100.0 * (X[1] - X[0]**2)**2 + /
(1.0 - X[1])**2 + 100.0 * (X[2] - X[1]**2)**2
def callbackF(Xi):
global Nfeval
print ''{0:4d} {1: 3.6f} {2: 3.6f} {3: 3.6f} {4: 3.6f}''.format(Nfeval, Xi[0], Xi[1], Xi[2], rosen(Xi))
Nfeval += 1
print ''{0:4s} {1:9s} {2:9s} {3:9s} {4:9s}''.format(''Iter'', '' X1'', '' X2'', '' X3'', ''f(X)'')
x0 = np.array([1.1, 1.1, 1.1], dtype=np.double)
[xopt, fopt, gopt, Bopt, func_calls, grad_calls, warnflg] = /
fmin_bfgs(rosen,
x0,
callback=callbackF,
maxiter=2000,
full_output=True,
retall=False)
La salida se ve así:
Iter X1 X2 X3 f(X)
1 1.031582 1.062553 1.130971 0.005550
2 1.031100 1.063194 1.130732 0.004973
3 1.027805 1.055917 1.114717 0.003927
4 1.020343 1.040319 1.081299 0.002193
5 1.005098 1.009236 1.016252 0.000739
6 1.004867 1.009274 1.017836 0.000197
7 1.001201 1.002372 1.004708 0.000007
8 1.000124 1.000249 1.000483 0.000000
9 0.999999 0.999999 0.999998 0.000000
10 0.999997 0.999995 0.999989 0.000000
11 0.999997 0.999995 0.999989 0.000000
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 11
Function evaluations: 85
Gradient evaluations: 17
Al menos de esta manera puede ver como el optimizador rastrea el mínimo
Intenta usar:
options={''disp'': True}
para forzar scipy.optimize.minimize
para imprimir resultados intermedios.
Siguiendo el ejemplo de @ joel, hay una forma ordenada y eficiente de hacer algo similar. El siguiente ejemplo muestra cómo podemos deshacernos de global
variables global
, call_back
funciones call_back
y la reevaluación de la función objetivo varias veces .
import numpy as np
from scipy.optimize import fmin_bfgs
def rosen(X, info): #Rosenbrock function
res = (1.0 - X[0])**2 + 100.0 * (X[1] - X[0]**2)**2 + /
(1.0 - X[1])**2 + 100.0 * (X[2] - X[1]**2)**2
# display information
if info[''Nfeval'']%100 == 0:
print ''{0:4d} {1: 3.6f} {2: 3.6f} {3: 3.6f} {4: 3.6f}''.format(info[''Nfeval''], X[0], X[1], X[2], res)
info[''Nfeval''] += 1
return res
print ''{0:4s} {1:9s} {2:9s} {3:9s} {4:9s}''.format(''Iter'', '' X1'', '' X2'', '' X3'', ''f(X)'')
x0 = np.array([1.1, 1.1, 1.1], dtype=np.double)
[xopt, fopt, gopt, Bopt, func_calls, grad_calls, warnflg] = /
fmin_bfgs(rosen,
x0,
args=({''Nfeval'':0},),
maxiter=1000,
full_output=True,
retall=False,
)
Esto generará resultados como
Iter X1 X2 X3 f(X)
0 1.100000 1.100000 1.100000 2.440000
100 1.000000 0.999999 0.999998 0.000000
200 1.000000 0.999999 0.999998 0.000000
300 1.000000 0.999999 0.999998 0.000000
400 1.000000 0.999999 0.999998 0.000000
500 1.000000 0.999999 0.999998 0.000000
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 0.000000
Iterations: 12
Function evaluations: 502
Gradient evaluations: 98
Sin embargo, no hay lanzamiento libre, aquí utilicé function evaluation times
lugar de function evaluation times
de algorithmic iteration times
como contador. Algunos algoritmos pueden evaluar la función objetivo varias veces en una única iteración.