[筆記整理] 一維搜索
0x00 摘要
本文是閱讀Alink源碼期間在網上查找資料做的筆記整理,把找到的算法實現加了一些注解。
0x01 概念
1.1 一維搜索
一維搜索是用來求步長的。
Line Search顧名思義就是沿着一個線尋找下一個x_{k+1},
一維搜索的理論是建立在整個最優化理論之下的。如果要理解什么一維搜索,就要理解最優化的目標與形式。
最優化目標: min(f(x)),一般而言f(x)是凸的。
在大多數多變量函數的最優化中,迭代格式為:
其中最為關鍵的就是往哪走的搜索方向 d_k 和走多少的步長因子 alpha_k,如果確定了搜索方向,那么求解步長因子 alpha_k 的問題就是一維優化問題,不妨設:
所謂一維搜索指的就是步驟2 "求取步長"。
為了進行一維搜索,我們首先需要縮小變量所在的變化范圍,然后再用其他方法去求極值。
一維搜索主要結構可作如下概括:
- 首先確定包含問題最優解的搜索區間。
- 然后采用某種分割技術或者插值方法縮小這個區間,進行搜索求解。
一維搜索一般有如下方法,解析法和數值解法。解析法即是按照數學公式求導數求極值。但是一般實際問題中,往往不知道損失函數的數學表達式、或者導數比較難求,這種方法一般應用於科學計算。數值類方法有分為兩類,試探法和插值法。
一維搜索分為兩種:
- 非精確一維搜索,就是找到一個 alpha 滿足一定條件即可,好比Wolfe-Powell,Armijo條件。
- 精確一維搜索,就是找到一個參數 alpha,使得min(f(x))最小,有插值法,黃金分割法,直接法等等。
1.2 不精確一維搜索
-
精確一維搜索往往需要花費很大的時間。
-
- 當迭代點遠離問題的解時,精確求解通常不十分有效。
- 很多最優化方法,如牛頓法和擬牛頓法,其收斂速度並不依賴於精確一維搜索過程。
-
只要保證目標函數有滿意的下降,可大大節省計算量
所以實際計算中,一般做不到精確的一維搜索,實際上也沒有必要做到這一點,因為精確的一維搜索需要付出較高的代價,對加速收斂作用不大,因此花費計算量較少的不精確的一維搜索技術方法受到更為廣泛的重視和歡迎。
確定步長最簡單的方法,就是挨個試。從0開始,每隔一定距離計算一下目標函數的值,找出其中最小的那個,對應的步長就是我們要的結果。
顯然,這種方法太過暴力,試的次數太多,很影響效率。所以有一些原則可以幫助我們提高效率。
一般而言主要有以下兩種准則:Armijo-Goldstein准則 和 Wolf-Powell 准則。
1.2.1 Armijo-Goldstein准則
Armijo-Goldstein准則核心思想就兩點:
- 目標函數值應該有足夠的下降
- 一維搜索的步長 lambda 不應該太小
Armijo 又被稱為充分下降條件(sufficient decrease condition),又稱Armijo condition。
Armijo condition這個約束太簡單了,以至於任意小的步長 alpha 都可以滿足該條件。為了保證每次迭代有充分的下降,我們加上Goldstein conditions。
這是兩個不等式,左右分別對應斜率不同的直線,將可接受區域約束在這兩條直線之間。
如果步長 alpha 太小的話,會導致左邊不等式接近於不成立的邊緣。因此,左邊不等式 就保證了 alpha 不能太小。
Armijo-Goldstein准則有可能把最優步長因子排除在可接受區間外,所以Wolfe-Powell更可以滿足我們需求。
1.2.2 Wolf-Powell 准則
Wolfe conditions實際上規定了兩件事情,
- 函數值必須下降
- 只接受導數較平緩的區域
Wolfe conditions使得目標點處的切線變得“不那么斜”了,這符合實際規律,因為極值點處不應該過於陡峭。
既然和導數大小有關,那么我們可以試着考慮二分點的導數值。如果二分點的導數值很小,直接滿足Wolfe conditions,那就找到了可接受的步長。如果二分點的導數值很大,那么我們就選擇與該點導數符號相反的那個端點,重新組成一個子區間。之所以選擇符號相反的那個端點,是因為對於連續光滑的函數來說,兩個斜率相反的點之間一定存在極值點,也就存在導數值很小的一段區域。按照這種策略,逐步縮小區間范圍,直到某個二分點滿足Wolfe conditions為止。
Wolfe-Powell方法相較於精確一維搜索,不再采用進退法去尋找搜索區間。在進退法里面,是通過慢慢擴展生成區間,然后在在區間中查找合適的,而在Wolfe-Powell中我們可以直接定義步長區間的界限,比如[0,10000],那么其會根據其准則去每次剔除不符合的區間,逐步縮小區間,其能夠較為快速的跳過無用的計算,速度要快很多。
Wolfe-Powell方法計算過程中,也用到了插值方法,用以區間切割剔除。
1.2.3 結合代碼分析
Armijo准則:首先給一個較大的學習率,然后不斷縮減學習率,如果對於函數f(xk+αdk)當前的學習率使函數從當前的位置f(xk)的減小一定程度后還大於預設的期望值,那這個學習率就符合要求了。
什么意思?你看,對於函數f(xk+αdk),既然是求最小值,那對於當前的值f(xk)減小一定程度后就有個新值f(xk+1),於是,如果我們將f(xk+1)作為預設的期望值,即我們希望f(xk)在某個學習率α的情況下減小一定程度后可以到達f(xk+1),那這個α就是我們希望得到的α了對吧。
這個減小程度在Armijo准則中是公式:
c1α▽f(xk)Tdk,c1∈(0, 1)
因為dk一般取梯度負方向,所以用式子表達上面的話的話就是:
f(xk+1)= f(xk) + c1α▽f(xk)Tdk,c1∈(0, 1)
具體分析代碼
function lamda = ArmijoGoldstein(func,gfunc,lamda0,ro,apha,iterNum,plotFlag)
if nargin<7
plotFlag = 1;
end
if nargin<6
iterNum = 100;
end
if nargin<5
apha = 2;
end
if nargin<4
ro = 0.1;
end
if nargin<3
lamda0 = 1;
end
a = 0; %左邊界
b = inf; %右邊界
lamda =lamda0;
f0 = func(0);
g0 = gfunc(0);
while iterNum
flamda = func(lamda);
if flamda<=f0+ro*lamda*g0 %判斷Armijo准則
%滿足充分下降條件
%if flamda>=f0+(1-ro)*lamda*g0 %代碼可以調整為判斷Goldstein
if gfunc(lamda)>=sigma*g0 %判斷曲率條件
%滿足wolf-powell,步長不會太小
break; %找到了可接受的步長,返回即可
else
%不滿足wolf-powell,說明當前步長落在了斜率較大的區域,此時有兩種可能
a = lamda; %左端的a設置為lamda
if isinf(b)
%如果是遠離初始點的區域,那么在初始點和當前點之間一定存在可接受的區域。右端的b為空的時候,說明Armijo准則一直是滿足的,步長太小了,擴大步長
lamda = alpha*lamda;
else
%如果是接近初始點的區域,這一區域不是我們想要的,需要進一步放大步長
lamda = (a+b)/2; %步長設定為區間的中值
end
end
else
%找到了不滿足充分下降條件的步長,因此該步長可以作為右邊界,縮小b和步長
b = lamda; %收縮
lamda = (a+b)/2;
end
iterNum = iterNum - 1;
end
%example
%lamda = WolfPowell(@(x)(sin(-4+x)-1),@(x)(cos(-4+x)),1,0.4,0.45,2,100,1)
0xFF 參考
[原創]用“人話”解釋不精確線搜索中的Armijo-Goldstein准則及Wolfe-Powell准則
https://www.zhihu.com/question/36425542