Die Methode least_squares
tut das mit Parameter . Es ist jedoch kein Allzweck-Minimierer, dessen Zweck es ist, die Summe der Quadrate der gegebenen Funktionen zu minimieren. Beispiel:
least_squares(lambda x: [x[0]*x[1]-6, x[0]+x[1]-5], [0, 0], verbose=2)
Für andere Methoden, wie minimize
, gibt es keine solche Option. Anstatt Callback zu verwenden und die Kostenfunktion neu zu bewerten, können Sie der Funktion selbst einige Protokollfunktionen hinzufügen. Zum Beispiel, hier fun
anhängt die berechneten Werte für die globale Variable cost_values
:
def fun(x):
c = x[0]**2 - 2*x[0] + x[1]**4
cost_values.append(c)
return c
cost_values = []
minimize(fun, [3, 2])
print(cost_values)
In diesem Beispiel gibt es 4 ähnliche Funktionswerte für jeden Iterationsschritt, wie der Minimierungsalgorithmus um sieht, die Berechnung der ungefähren Jacobi und/oder hessischen . Also, print(cost_values[::4])
wäre der Weg, um einen Wert der Kostenfunktion pro Schritt zu erhalten.
Aber es sind nicht immer 4 Werte pro Schritt (hängt von der Dimension und der verwendeten Methode ab). Daher ist es besser, eine Rückruffunktion zu verwenden, um die Kosten nach jedem Schritt zu protokollieren. Die aktuellen Kosten sollten in einer globalen Variablen gespeichert werden, sodass sie nicht neu berechnet werden muss.
def fun(x):
global current_cost
current_cost = x[0]**2 - 2*x[0] + x[1]**4
return current_cost
def log_cost(x):
cost_values.append(current_cost)
cost_values = []
minimize(fun, [3, 2], callback=log_cost)
print(cost_values)
Dieser druckt
[3.5058199763814986, -0.2358850818406083, -0.56104822688320077, -0.88774448831043995, -0.96018358963745964, -0.98750765702936738, -0.99588975368993771, -0.99867208501468863, -0.99956795994852465, -0.99985981414137615, -0.99995446605426996, -0.99998521591611178, -0.99999519917089297, -0.99999844105574265, -0.99999949379700426, -0.99999983560485239, -0.99999994662329761, -0.99999998266175671]
Das ist schlau! – MaxU
Diese Antwort ist sehr clever! Gibt es einen Weg, dies ohne Schließungen zu tun und sich damit zu beschäftigen, immer einen "n-ten" Wert von der Liste zu nehmen? Ich stelle mir vor, dass in einer komplizierten Kostenfunktion ein Schritt gemacht werden kann, der keine Neuberechnung des Jac/Hess entlang einiger Dimensionen erfordert, so dass die "Überspring" -Länge selbst eine Funktion der Iteration sein wird. –
@ 6'whitemale - siehe die Antwort, die ich gepostet habe, gibt es eine Lösung, solange Sie es nicht brauchen, um in IPython zu arbeiten. –