對於乙個多元函式f(
x)=f
(x1,
x2,⋯
,xn)
,用最速下降法(又稱梯度下降法)求其極小值的迭代格式為 xk
+1=x
k+αk
dk其中dk
=−gk
=−∇f
(xk)
為負梯度方向,即最速下降方向,αk
為搜尋步長。
一般情況下,最優步長αk
的確定要用到線性搜尋技術,比如精確線性搜尋,但是更常用的是不精確線性搜尋,主要是goldstein不精確線性搜尋和wolfe法線性搜尋。
為了呼叫的方便,編寫乙個python檔案,裡面存放線性搜尋的子函式,命名為linesearch.py,這裡先只編寫了goldstein線性搜尋的函式,關於goldstein原則,可以參看最優化課本。
線性搜尋的**如下(使用版本為python3.3):
'''
線性搜尋子函式
'''import numpy as np
import random
defgoldsteinsearch
(f,df,d,x,alpham,rho,t):
flag=0
a=0b=alpham
fk=f(x)
gk=df(x)
phi0=fk
dphi0=np.dot(gk,d)
alpha=b*random.uniform(0,1)
while(flag==0):
newfk=f(x+alpha*d)
phi=newfk
if(phi-phi0<=rho*alpha*dphi0):
if(phi-phi0>=(1-rho)*alpha*dphi0):
flag=1
else:
a=alpha
b=bif(b2
else:
alpha=t*alpha
else:
a=ab=alpha
alpha=(a+b)/2
return alpha
上述函式的輸入引數主要包括乙個多元函式f,其導數df,當前迭代點x和當前搜尋方向d,返回值是根據goldstein準則確定的搜尋步長。
我們仍以rosenbrock函式為例,即有 f(
x)=100(x
2−x2
1)2+
(1−x
1)2
於是可得函式的梯度為 g(
x)=∇
f(x)
=(−400(x
2−x2
1)x1
−2(1
−x1)
,200(x
2−x2
1))t
最速下降法的**如下:
"""
最速下降法
rosenbrock函式
函式 f(x)=100*(x(2)-x(1).^2).^2+(1-x(1)).^2
梯度 g(x)=(-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)),200*(x(2)-x(1)^2))^(t)
"""import numpy as np
import matplotlib.pyplot as plt
import random
import linesearch
from linesearch import goldsteinsearch
defrosenbrock
(x):
return
100*(x[1]-x[0]**2)**2+(1-x[0])**2
defjacobian
(x):
return np.array([-400*x[0]*(x[1]-x[0]**2)-2*(1-x[0]),200*(x[1]-x[0]**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條輪廓線
defsteepest
(x0):
print('初始點為:')
print(x0,'\n')
imax = 20000
w=np.zeros((2,imax))
w[:,0] = x0
i = 1
x = x0
grad = jacobian(x)
delta = sum(grad**2) # 初始誤差
while iand delta>10**(-5):
p = -jacobian(x)
x0=x
alpha = goldsteinsearch(rosenbrock,jacobian,p,x,1,0.1,2)
x = x + alpha*p
w[:,i] = x
grad = jacobian(x)
delta = sum(grad**2)
i=i+1
print("迭代次數為:",i)
print("近似最優解為:")
print(x,'\n')
w=w[:,0:i] # 記錄迭代點
return w
x0 = np.array([-1.2,1])
w=steepest(x0)
plt.plot(w[0,:],w[1,:],'g*',w[0,:],w[1,:]) # 畫出迭代點收斂的軌跡
plt.show()
為了實現不同檔案中函式的呼叫,我們先用import函式匯入了線性搜尋的子函式,也就是下面的2行**
import linesearch
from linesearch import goldsteinsearch
當然,如果把定義goldsteinsearch函式的**直接放到程式裡面,就不需要這麼麻煩了,但是那樣的話,不僅會使程式顯得很長,而且不便於goldsteinsearch函式的重用。
此外,python對函式式程式設計也支援的很好,在定義goldsteinsearch函式時,可以允許抽象的函式f,df作為其輸入引數,只要在呼叫時例項化就可以了。與matlab不同的是,傳遞函式作為引數時,python是不需要使用@將其變為函式控制代碼的。
執行結果為
初始點為:
[-1.2 1. ]
迭代次數為: 1504
近似最優解為:
[ 1.00318532 1.00639618]
迭代點的軌跡為
初始點為:
[-1.2 1. ]
迭代次數為: 1994
近似最優解為:
[ 0.99735222 0.99469882]
所得影象為
機器學習 最速下降法和牛頓下降法
入門教材常用二分法來求解實數求根的問題。我們現在來用普通迭代法 下降法來求解實數開立方根的問題。設當前實數為n,求根次數為k,根為s,那麼有s k n。所得偏差函式為f s s k n。顯然當代價函式f s 0時,我們便求出了n的k次根。現在我們開立方根,那麼k 3,代價函式為f s s 3 n。普...
最速下降法 and 共軛梯度法
註明 程式中呼叫的函式jintuifa.m golddiv.m我在之前的筆記中已貼出 最速下降法 最速下降法求解f 1 2 x1 x1 9 2 x2 x2的最小值,起始點為x0 9 1 演算法根據最優化方法 天津大學出版社 97頁演算法3.2.1編寫 v1.0 author liuxi bit fo...
最速下降法與Newton法
乙個簡單的最優化問題如下 在二維空間上尋找函式的最大值。一般我們常見的解析法,是求導,得極值點。這裡不再討論。很多情況下解析法很難求解,常會用到一種迭代慢慢逼近的方法,就是迭代法。如下圖。迭代法由乙個基本的可行點出發,依次產生乙個可行點列,x1,x2,xk,f xk 1 迭代法基本步驟如下 1.乙個...