用Python實現最速下降法求極值

2021-07-04 07:22:52 字數 3707 閱讀 5287

對於乙個多元函式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.乙個...