Я создаю базовый алгоритм метода Ньютона для задачи неограниченной оптимизации, и мои результаты от алгоритма не соответствуют моим ожиданиям. Это простая целевая функция, поэтому ясно, что алгоритм должен сходиться к (1,1). Это подтверждает алгоритм градиентного спуска, который я создал ранее, здесь:
def grad_descent(x, t, count, magnitude):
xvalues.append(x)
gradvalues.append(np.array([dfx1(x), dfx2(x)]))
fvalues.append(f(x))
temp=x-t*dfx(x)
x = temp
magnitude = mag(dfx(x))
count+=1
return xvalues, gradvalues, fvalues, count
Моя попытка создать алгоритм для метода Ньютона находится здесь:
def newton(x, t, count, magnitude):
xvalues=[]
gradvalues=[]
fvalues=[]
temp=x-f(x)/dfx(x)
while count < 10:
xvalues.append(x)
gradvalues.append(dfx(x))
fvalues.append(f(x))
temp=x-t*f(x)/dfx(x)
x = temp
magnitude = mag(dfx(x))
count+=1
if count > 100:
break
return xvalues, gradvalues, fvalues, count
Вот целевая функция и функция градиента:
f = lambda x: 100*np.square(x[1]-np.square(x[0])) + np.square((1-x[0]))
dfx = lambda x: np.array([-400*x[0]*x[1]+400*np.power(x[0],3)+2*x[0]-2, 200*(x[1]-np.square(x[0]))])
Вот начальные условия. Обратите внимание, что альфа и бета не используются в методе Ньютона.
x0, t0, alpha, beta, count = np.array([-1.1, 1.1]), 1, .15, .7, 1
magnitude = mag(np.array([dfx1(x0), dfx2(x0)]))
Чтобы вызвать функцию:
xvalues, gradvalues, fvalues, iterations = newton(x0, t0, count, magnitude)
Это дает очень странные результаты. Вот первые 10 итераций значений x, значений градиента и решения функции для соответствующего входа x:
[array([-1.1, 1.1]), array([-0.99315589, 1.35545455]), array([-1.11651296, 1.11709035]), array([-1.01732476, 1.35478987]), array([-1.13070578, 1.13125051]), array([-1.03603697, 1.35903467]), array([-1.14368874, 1.14364506]), array([-1.05188162, 1.36561528]), array([-1.15600558, 1.15480705]), array([-1.06599492, 1.37360245])]
[array([-52.6, -22. ]), array([142.64160215, 73.81918332]), array([-62.07323963, -25.90216846]), array([126.11789251, 63.96803995]), array([-70.85773749, -29.44900758]), array([114.31050737, 57.13241151]), array([-79.48668009, -32.87577304]), array([104.93863096, 51.83206539]), array([-88.25737032, -36.308371 ]), array([97.03403558, 47.45145765])]
[5.620000000000003, 17.59584998020613, 6.156932949106968, 14.29937453260906, 6.7080172227439725, 12.305727666787176, 7.297442528545537, 10.926625703722639, 7.944104584786208, 9.89743708419569]
Вот окончательный результат:
final_value = print('Final set of x values: ', xvalues[-1])
final_grad = print('Final gradient values: ', gradvalues[-1])
final_f = print('Final value of the object function with optimized inputs: ', fvalues[-1])
final_grad_mag = print('Final magnitude of the gradient with optimized inputs: ', mag(np.array([dfx1(xvalues[-1]), dfx2(xvalues[-1])])))
total_iterations = print('Total iterations: ', iterations)
здесь показан трехмерный график:
x = np.array([i[0] for i in xvalues])
y = np.array([i[1] for i in xvalues])
z = np.array(fvalues)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.scatter(x, y, z, label='Newton Method')
ax.legend()
Причина этого в том, что начальное предположение так близко к оптимальной точке, или в моем алгоритме есть какая-то ошибка, которую я не улавливаю? Мы будем очень признательны за любые советы. Похоже, что решение может даже колебаться, но трудно сказать
f(x)
иdfx(x)
. Кроме того, какова цель (и ценность)t
в ваших расчетах? Короче говоря, для этого вопроса нужен минимальный воспроизводимый пример. - person user3386109   schedule 11.09.2018