牛頓法
牛頓法是爲了求解函數值爲零的時候變量的取值問題的,具體地,當要求解 f(θ)=0時,如果 f可導,那麼可以通過迭代公式。
當θ是向量時,牛頓法可以使用下面式子表示:
其中H叫做海森矩陣,H (-1) 表示的是海森矩陣的逆矩陣 ,其實就是目標函數對參數θ的二階導數。
牛頓法的優點:
牛頓法收斂速度相比梯度下降法很快,而且由於海森矩陣的的逆在迭代中不斷減小,起到逐漸縮小步長的效果。
缺點:
牛頓法的缺點就是計算海森矩陣的逆比較困難,消耗時間和計算資源。因此有了擬牛頓法。
-
網上一個牛頓法求解的例子:
海森矩陣的定義:
- 代碼實現:
用牛頓法求解 f = 100 * (x2-x1** 2) ** 2 + (1-x1)**2
import numpy as np
import matplotlib.pyplot as plt
#梯度的公式
def tidu(x):
return np.array([-400*x[0]*(x[1]-x[0]**2)-2*(1-x[0]),200*(x[1]-x[0]**2)])
#海森矩陣的公式
def hessian(x):
return np.array([[-400*(x[1]-3*x[0]**2)+2,-400*x[0]],[-400*x[0],200]])
#牛頓法
def newton(x):
print("初始點爲 : ",x)
res=[]
res.append(x)
i = 1
imax = 1000
delta = 1
#迭代的條件是小於imax,或者是更新的距離小於一個很小的數值
while i<imax and delta>10**(-5):
p = -np.dot(np.linalg.inv(hessian(x)),tidu(x))
x_new = x + p
res.append(x_new)
delta = sum((x-x_new)**2) # 更新的距離
print("初始點爲 : ",x_new)
i=i+1
x=x_new # 更新x
return np.array(res)
if __name__ =="__main__":
# 用牛頓法求解 f=100*(x2-x1**2)**2+(1-x1)**2
X1=np.arange(-1.5,1.5+0.05,0.05)
X2=np.arange(-3.5,2+0.05,0.05)
[x1,x2]=np.meshgrid(X1,X2)
f=100*(x2-x1**2)**2+(1-x1)**2; # 給定的函數
plt.contour(x1,x2,f,20) # 畫出函數的20條輪廓線
x0 = np.array([-1.2,1])
res=newton(x0)
res_x=res[:,0]
res_y=res[:,1]
plt.plot(res_x,res_y)
plt.show()
作者:zhaozhengcoder
鏈接:https://www.jianshu.com/p/0f864a4c3b38
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
由於牛頓法是基於當前位置的切線來確定下一次的位置,所以牛頓法又被很形象地稱爲是"切線法"。牛頓法的搜索路徑(二維情況)如下圖所示: