Следуя примеру @ joel, существует аккуратный и эффективный способ сделать аналогичную вещь. В следующем примере показано, как мы можем избавиться от переменных global
, call_back
и повторной оценки целевой функции несколько раз.
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,
)
Это будет генерировать выходной сигнал, как
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
Однако нет свободного запуска, здесь я использовал function evaluation times
вместо algorithmic iteration times
в качестве счетчика. Некоторые алгоритмы могут оценивать целевую функцию несколько раз за одну итерацию.
Вы проверили параметр 'callback' вашей функции минимизации? – mg007
Для другого подхода без «обратного вызова» см. [Funcgradmon] (http://stackoverflow.com/questions/40002172/resuming-an-optimization-in-scipy-optimize/40059852#40059852). Он сохраняет все значения 'x f g', а затем записывает их в файл для построения. – denis