最优化问题——一维搜索(二)
在前面的的文章最优化问题——一维搜索(一)中,我们主要介绍了一维搜索中精确搜索的缩小区间法,具体的算法包括黄金分割法,斐波那契法,中点法,以及确定初始区间的进退法。
在本篇文章中,我们主要介绍一维搜索的牛顿法和插值法以及非精确的一维搜索。
1. 牛顿法
1.1 牛顿的基本思路
与之前介绍的缩小区间法的思路不同,牛顿法使用的是函数逼近的基本原理,看过之前的非线性规划文章的读者可知,通过泰勒展开式,我们可以将函数变成一阶逼近和二阶逼近的形式。而在一维搜索中,利用插值函数来逼近所需要求解的函数,把插值函数的极小点作为迭代点。常见的算法包括三点二次插值,两点二次插值和三次插值多项式。
1.2 牛顿法的基本思路和公式推导
牛顿法是函数逼近的一个代表算法。首先,对于函数 φ ( λ ) φ(λ) φ(λ)进行二次的泰勒展开式:
φ ( λ ) = φ ( λ k ) + φ ′ ( λ k ) ( λ − λ k ) + 1 2 φ ′ ′ ( λ k ) ( λ − λ k ) 2 + O ( λ − λ k ) 2 φ(λ)=φ(λ_k)+φ'(λ_k)(λ-λ_k)+\frac{1}{2}φ''(λ_k)(λ-λ_k)^2+O(λ-λ_k)^2 φ(λ)=φ(λk)+φ′(λk)(λ−λk)+21φ′′(λk)(λ−λk)2+O(λ−λk)2
这里,我们取二阶导数,省略高次项得到:
q k ( λ ) = φ ( λ k ) + φ ′ ( λ k ) ( λ − λ k ) + 1 2 φ ′ ′ ( λ k ) ( λ − λ k ) 2 q_k(λ)=φ(λ_k)+φ'(λ_k)(λ-λ_k)+\frac{1}{2}φ''(λ_k)(λ-λ_k)^2 qk(λ)=φ(λk)+φ′(λk)(λ−λk)+21φ′′(λk)(λ−λk)2
下一步,我们使用
q
k
(
λ
)
q_k(λ)
qk(λ)作为原函数
φ
(
λ
k
)
φ(λ_k)
φ(λk)的逼近。当
φ
′
′
(
λ
k
)
>
0
φ''(λ_k)>0
φ′′(λk)>0的时候,我们对
q
k
(
λ
)
q_k(λ)
qk(λ)求导,则其驻点就是极小点:
q
k
(
λ
)
q_k(λ)
qk(λ)的一阶导数为:
q
k
′
(
λ
)
=
φ
′
(
λ
k
)
(
λ
−
λ
k
)
+
φ
′
′
(
λ
k
)
(
λ
−
λ
k
)
=
0
q_k'(λ)=φ'(λ_k)(λ-λ_k)+φ''(λ_k)(λ-λ_k)=0
qk′(λ)=φ′(λk)(λ−λk)+φ′′(λk)(λ−λk)=0
进一步,我们给出对于第k+1轮的λ的更新公式为:
λ
k
+
1
=
λ
k
−
φ
′
(
λ
k
)
/
φ
′
′
(
λ
k
)
λ_{k+1}=λ_k-φ'(λ_k)/φ''(λ_k)
λk+1=λk−φ′(λk)/φ′′(λk)
1.3 牛顿法的算法框图
1.4 牛顿法实例
为了更好的理解牛顿法,这里我们给出一个关于牛顿法的例子:
1.5 牛顿法代码实现
'''
原始函数为: φ函数为 φ(λ)= λ*λ-4λ+3
'''
def grad_one_value(lam_k):
return 2 * lam_k - 4
def grad_two_value(lam_k):
return 2.0
def NewtonFunction(lam_k,e1,e2):
while abs(grad_one_value(lam_k)) >= e1:
if grad_two_value(lam_k) > 0:
lam_k1 = lam_k - grad_one_value(lam_k) / grad_two_value(lam_k)
if abs(lam_k1 - lam_k) < e2:
return lam_k
else:
lam_k = lam_k1
else:
return -1
return lam_k
1.6 牛顿法总结
牛顿法的基本思想是在迭代点 x k x_k xk附近使用二阶导数 q k ( s ) = f ( x k ) + g k T s + 1 2 s T G k s q_k(s)=f(x_k)+g_k^Ts+\frac{1}{2}s^TG_ks qk(s)=f(xk)+gkTs+21sTGks来逼近 f ( x ) f(x) f(x),并以 q k ( s ) q_k(s) qk(s)的极小点 s k s_k sk来修正 x k x_k xk,得到下一轮的结果 x k + 1 = x k + s k x_{k+1}=x_k+s_k xk+1=xk+sk
2 插值法
2.1 插值法算法思路
插值法本身也是对于函数的额逼近思路,用函数 φ ( λ ) φ(λ) φ(λ)在2或者3个点的函数值或者导数值,构造2次或者3次多项式最为 φ ( λ ) φ(λ) φ(λ)的近似值,以这多项式的极小点为新的迭代点。常见的包括3点两次,2点2次,4点3次,3点3次,2点3次等等。
以3点两次多项式为例,首先,我们给出两次多项式的基本形式:
设二次插值多项式的基本形式为:
a
λ
2
+
b
λ
+
c
=
φ
(
λ
)
aλ^2+bλ+c=φ(λ)
aλ2+bλ+c=φ(λ)
同时,假设我们在范围内取得的点为
λ
1
,
λ
2
,
λ
3
λ_1,λ_2,λ_3
λ1,λ2,λ3,则将三个点带入到二次的插值多项式中,则有:
{
a
λ
1
2
+
b
λ
1
+
c
=
φ
(
λ
1
)
a
λ
2
2
+
b
λ
2
+
c
=
φ
(
λ
2
)
a
λ
3
2
+
b
λ
3
+
c
=
φ
(
λ
3
)
\begin{cases} aλ_1^2+bλ_1+c=φ(λ_1)\\ aλ_2^2+bλ_2+c=φ(λ_2)\\ aλ_3^2+bλ_3+c=φ(λ_3) \end{cases}
⎩⎪⎨⎪⎧aλ12+bλ1+c=φ(λ1)aλ22+bλ2+c=φ(λ2)aλ32+bλ3+c=φ(λ3)
进而我们根据上面的三个代入式就可以解出a,b的值为:
同时,我们也能够获得二次函数的极值点为 λ ∗ = − b 2 a λ^*=-\frac{b}{2a} λ∗=−2ab
进一步,我们就可以得到四个点,包括
{
λ
1
,
λ
2
,
λ
3
,
λ
∗
}
\{λ_1,λ_2,λ_3,λ^*\}
{λ1,λ2,λ3,λ∗},从而可以根据这四个点获得四个函数值为$
φ
(
λ
1
)
,
φ
(
λ
2
)
,
φ
(
λ
3
)
,
φ
(
λ
∗
)
φ(λ_1),φ(λ_2),φ(λ_3),φ(λ^*)
φ(λ1),φ(λ2),φ(λ3),φ(λ∗)
最后,我们根据函数值的大小来舍弃掉函数值最大的对应的λ点,这样可以保证我们所求的是最小的λ。
舍弃之后,我们再次剩余了三个点,再重新计算a,b,c的值,进行下一轮的迭代,最后,由于我们每次保存的都是三个函数值最小的三个点,这样可以是函数值不断的逼近最小值,最终可以获得最优点 λ ∗ λ^* λ∗。
下面,我们再来看两点两次的求解过程,同样我们也有上面的二次基本式,同时我们可以计算出:
{
a
λ
0
2
+
b
λ
0
+
c
=
φ
(
λ
0
)
a
λ
1
2
+
b
λ
1
+
c
=
φ
(
λ
1
)
2
a
λ
0
+
b
=
φ
′
(
λ
1
)
\begin{cases} aλ_0^2+bλ_0+c=φ(λ_0)\\ aλ_1^2+bλ_1+c=φ(λ_1)\\ 2aλ_0+b=φ'(λ_1) \end{cases}
⎩⎪⎨⎪⎧aλ02+bλ0+c=φ(λ0)aλ12+bλ1+c=φ(λ1)2aλ0+b=φ′(λ1)
同理,就可以推导出:
{
a
=
(
λ
0
−
λ
1
)
φ
0
′
−
(
φ
0
−
φ
1
)
(
λ
0
−
λ
1
)
2
b
=
(
λ
0
2
−
λ
1
2
)
φ
0
′
+
2
(
φ
0
−
φ
1
)
λ
0
(
λ
0
−
λ
1
)
2
\begin{cases} a=\frac{(λ_0-λ_1)φ_0'-(φ_0-φ_1)}{(λ_0-λ_1)^2}\\ \frac{}{}\\ b=\frac{(λ_0^2-λ_1^2)φ_0'+2(φ_0-φ_1)λ_0}{(λ_0-λ_1)^2}\\ \end{cases}
⎩⎪⎪⎨⎪⎪⎧a=(λ0−λ1)2(λ0−λ1)φ0′−(φ0−φ1)b=(λ0−λ1)2(λ02−λ12)φ0′+2(φ0−φ1)λ0
最后,我们也可以求出极值点为 λ ∗ = − b 2 a λ^*=-\frac{b}{2a} λ∗=−2ab
与上面一样,计算函数值,去掉函数值最大的点,保证最小值在我们目前的搜索区域内部。然后进行下一轮迭代。
总结: 对于上面的两个例子,我们来总结一下这种插值法的基本思路,首先,对于原始的数据点,我们可以求出二次插值公式中的a,b,c,然后,可以求出二次插值公式中对应的极值点,这样对于我们原始设定的点就多出来一个极值点 λ ∗ λ^* λ∗,最后,通过不同点对于原始函数值的比较,去掉最大值点,是点的数量恢复到我们初始设定的点,进行下一轮迭代。最终,在不断的接近最小的函数值的过程中,我们获得了最优点。
同理,我们可以将这种二次的扩展到三次的函数,关键在于找三次函数的极值点。如何找,这里我们就不在具体叙述了,最简单的可以利用二阶和一阶导数。
3 Shubert-Piyavskii 方法
3.1 数学基础
在介绍相关的算法之前,我们有必要了解一些非精确搜索的数学基础,以便于我们更好理解后面叙述的算法。
- 李普希兹连续:即导数的幅度存在上界。换句话来说当我们计算出来的导数在一定范围的时候,那么对应函数值的增长幅度也就一定。用公式表示就是:
∣ f ( x ) − f ( y ) ∣ ≤ l ∣ x − y ∣ , 任 意 x , y ∈ [ a , b ] |f(x)-f(y)|≤l|x-y|,任意x,y∈[a,b] ∣f(x)−f(y)∣≤l∣x−y∣,任意x,y∈[a,b]
给定点 ( x 0 , f ( x 0 ) ) (x_0,f(x_0)) (x0,f(x0)),如果 x > x 0 x>x_0 x>x0,直线 f ( x 0 ) − l ( x x 0 ) , x < x 0 , f ( x 0 ) + l ( x − x 0 ) f(x_0)-l(x_x0),x<x_0,f(x_0)+l(x-x_0) f(x0)−l(xx0),x<x0,f(x0)+l(x−x0)就形成了函数f的下界。
进一步,假设我们给定了李普希兹常数l,算法从中点 x 1 = a + b 2 x_1=\frac{a+b}{2} x1=2a+b,通过该点斜率为 + / − l +/-l +/−l的直线构造f的锯齿样的下界。通过常数有效,则这些直线总是在函数f的下面。
具体如下图所示:
3.2 Shubert-Piyavskii算法
在确定了以±l为斜率的斜线之后,我们可以取每一个锯齿的极小点
(
x
n
,
y
n
)
(x_n,y_n)
(xn,yn),与该点的函数值
f
(
x
n
)
f(x_n)
f(xn)之差小于某一个常数的时候停止。也就是
y
n
−
f
(
x
n
)
<
ε
y_n-f(x_n)<ε
yn−f(xn)<ε
每一次的迭代,计算的区域为:
[
x
i
−
1
l
(
f
(
x
m
i
n
−
y
i
)
)
,
x
i
+
1
l
(
y
i
−
y
m
i
n
)
]
[x_i-\frac{1}{l}(f(x_{min}-y_i)),x_i+\frac{1}{l}(y_i-y_{min})]
[xi−l1(f(xmin−yi)),xi+l1(yi−ymin)]
也就是说,我们每次都在不同的区域内进行计算。
具体的计算过程如下图所示:
4 不精确搜索
在前面的文章和前面的章节中,我们描述的都是精确地一维搜索,这样计算的特点是算法的复杂度高,有效性差,很多时候,我们没有对于精确搜索的需求。所以,下面的一节内容,我们阿里关注非精确搜索。
首先,对于非精确一维搜索,我们的定义其基本形式和要求:
4.2 Goldstein算法
在对于这种不精确的一维搜索有了一定的了解之后,我们首先来给出第一个算法。Goldstein算法,算法的思路很简单,首先设f函数为 R n − > R R^n->R Rn−>R,在x取一个方向d,则有 ▽ f T ( x ) d < 0 ▽f^T(x)d<0 ▽fT(x)d<0(d为下降的方向),进一步令 s k = x k + 1 − x k = λ k d k s_k=x_{k+1}-x_k=λ_kd_k sk=xk+1−xk=λkdk,我们求λ使得:
f
(
x
k
+
1
)
−
f
(
x
k
)
≤
ρ
▽
f
T
(
x
k
)
s
k
=
ρ
λ
k
d
k
f(x_{k+1})-f(x_k)≤ρ▽f^T(x_k)s_k=ρλ_kd_k
f(xk+1)−f(xk)≤ρ▽fT(xk)sk=ρλkdk
f
(
x
k
+
1
)
−
f
(
x
k
)
≥
(
1
−
ρ
)
▽
f
T
(
x
k
)
s
k
=
(
1
−
ρ
)
λ
k
d
k
f(x_{k+1})-f(x_k)≥(1-ρ)▽f^T(x_k)s_k=(1-ρ)λ_kd_k
f(xk+1)−f(xk)≥(1−ρ)▽fT(xk)sk=(1−ρ)λkdk
其中ρ∈(0,1/2),实际上经常取ρ=0.1或者更小。
对于上面的两个条件。首先,对于原来的梯度下降,我们可以发现得第一个点就是我们进一步放宽了梯度下降的范围。与此同时,当我们计算出来的值在两个不等式之外的时候,需要增大或者缩小步长,将近似值保证在范围之内。下面用一张图展示范围的放宽:
最后我们给出该算法的算法框图以及一般形式:
4.3 Wolfe-Powell算法
Wolfe—Powell算法主要是对Goldstein算法的一种改进,其对于Goldstein算法中的第二项做出改进,将其改为如下的形式:
f
(
x
k
+
1
)
≤
f
(
x
k
)
+
ρ
▽
f
T
(
x
k
)
s
k
f(x_{k+1})≤f(x_k)+ρ▽f^T(x_k)s_k
f(xk+1)≤f(xk)+ρ▽fT(xk)sk
▽
f
T
(
x
k
+
1
)
s
k
≥
σ
▽
f
T
(
x
k
)
s
k
▽f^T(x_{k+1})s_k≥σ▽f^T(x_k)s_k
▽fT(xk+1)sk≥σ▽fT(xk)sk
其中
ρ
∈
(
0
,
1
2
)
,
σ
∈
(
ρ
,
1
)
ρ∈(0,\frac{1}{2}),σ∈(ρ,1)
ρ∈(0,21),σ∈(ρ,1)
不难发现,Wolfe—Powell在第二个条件改成了对于梯度的约束,我们先给出规则图,在来考虑这种改变的意义在哪里?
首先,第一个不等式约束确定了我们在计算最优值的时候的基本范围,同时,通过第二个条件的约束,我们可以看到要求的是在 x k + 1 x_{k+1} xk+1点对应的斜率不小于 σ ▽ f T ( x k ) s k σ▽f^T(x_k)s_k σ▽fT(xk)sk,显然,其目的是通过下降的方向来控制下降的速度,通过这种斜率控制,就保证了每一次的下降都尽可能的向下,进而加快了收敛速度。
其算法实现与Goldstein类似,一些注意和改进如下图所示:
5 总结
至此,我们在一维搜索方面就结束了,起始介绍一维搜索的动因在于我们在非线性规划中的步长因子问题,进而我们从精确和非精确两个方面来叙述了一维搜索,在精确的一维搜索中,我们主要介绍了黄金分割,斐波那契,中点法和确定初始区间的进退法。从插值的思路又介绍了牛顿法,三点二次,两点二次等插值方法。最后,由于很多问题对于一维搜索的精度需求不大,我们有讲述了Goldstein算法和Wolfe-Powell算法,这两种算法主要从两个点来提升一维搜索的有效性,第一个是放宽梯度限制,第二个点是保存高速的梯度下降。
6 参考
- 哈工大—组合优化与凸优化