ich habe einen Algorithmus in Python 3 geschrieben, in welchem die Gauß-Newton-Methode und die Wolfe Bedinungen implementiert sind. Es handelt sich hierbei um eine Fitting-Methode um die optimalen Parameter eines mathematischen Models zu finden.
Mein Code funktioniert für das angegebene Beispiel in Gauß-Newton-Methode
Code: Alles auswählen
from numpy import array, zeros, dot, sqrt
from numpy.linalg import inv
# Data from Wiki
x = array([0.038, 0.194, 0.425, 0.626, 1.253, 2.5, 3.74])
y = array([0.05, 0.127, 0.094, 0.2122, 0.2729, 0.2665, 0.3317])
c = array([1000, 40]).astype(float) # initial parameters
accuracy = 10**(-8)
maxiter = 10**3
def model(x,c):
return (c[0] * x) / (c[1] + x)
def residual(c):
return y - model(x,c)
def jacobi(c):
jac = zeros((len(x), len(c0)))
jac[:,0] = -x/(c[1] + x) # partial derivatives
jac[:,1] = (c[0] * x)/(c[1] + x)**2
return jac
def squares(c):
return sum(residual(c)**2)
def grad(c):
val = jacobi(c).T.dot(residual(c))
return sqrt(val[0]**2 + val[1]**2)
# main loop
counter = 0
for i in range(maxiter):
r = residual(c)
Jf = jacobi(c) # Jacobi and its Transpose
Jft = Jf.T
for j in range(1,100):
c_old = c
c_new = c - 1/j * dot(dot(inv(dot(Jft,Jf)),Jft),r)
# Compute values to apply the wolfe conditions, 0.9 and 0.0001 from wiki
old = squares(c_old) + 0.0001*1/j*grad(c_old).dot(dot(dot(inv(dot(Jft,Jf)),Jft),r))
new = squares(c_new)
ka1 = -grad(c_new).dot(dot(dot(inv(dot(Jft,Jf)),Jft),r))
ka2 = -0.9 * grad(c_old).dot(dot(dot(inv(dot(Jft,Jf)),Jft),r))
if new <= old and ka1 <= ka2: # Armijo rule and curvature condition
c = c_new
break
change = grad_abs(c)
counter +=1
if change < accuracy:
break
print('Iterations = ' +str(counter))
print('Parameter = ' +str(c))
Wenn ich diesen Algorithmus für ein anderes simples Beispiel verwende:
Code: Alles auswählen
x = array([1,2,3,4,5,6,7,8]).astype(float)
y = array([8.3, 11.0, 14.7, 19.7, 26.7, 35.2, 44.4, 55.9]).astype(float)
c = array([10, 7]) #optimal paramerets are: c_0 = 0.751, c_1=7.82
Code: Alles auswählen
def model(x,c):
return c[0] * x**2 + c[1]
def jacobi(c):
jac = zeros((len(x), len(c)))
jac[:,0] = x**2
jac[:,1] = 1
return jac
Die Wolfe Bedingungen sind höchstwahrscheinlich falsch, aber ich finde den Fehler nicht. Hat jemand von euch eine Idee, wo der Fehler liegt?