数值优化方法:梯度下降,最速梯度下降与共轭梯度下降
本文对常见的数值优化方法进行总结,重点关注优化方法的原理、迭代过程和计算复杂度。常见的数值优化方法包括梯度下降法(最速梯度下降法)、牛顿法、共轭梯度下降法等。本笔记的算法思路只是便于对各种优化方法进行理解,并不是完整的逻辑推导,如果想了解其中的数学推导,建议还是查看相关教材。(文章里公式渲染有点慢,需要等一会)
本文相关代码在https://github.com/flztiii/numerical_optimization_test.git
梯度下降算法
算法思路
考虑到以下问题,找到一个 x ∗ x^* x∗使 f ( x ∗ ) < f ( x ) , ∀ x ∈ R n f(x^*) < f(x), \forall x \in R^n f(x∗)<f(x),∀x∈Rn。梯度下降算法的思路很简单:每一次迭代的点要比上一次次迭代点的值更小。用公式表达就是
f ( x k + 1 ) f(x_{k+1}) f(xk+1) < f ( x k ) ( 1 ) f(x_{k}) \quad (1) f(xk)(1)
接下来就是如何根据这个思路得到从 x k x_k xk到 x k + 1 x_{k+1} xk+1的增量 Δ x \Delta x Δx。可以对 f ( x ) f(x) f(x)进行一阶泰勒展开,表达式如下所示
f ( x + Δ x ) = f ( x ) + f ′ ( x ) ⋅ Δ x ( 2 ) f(x+\Delta x) = f(x) + f^{'}(x) \cdot \Delta x \quad (2) f(x+Δx)=f(x)+f′(x)⋅Δx(2)
再根据公式(2),可以得到
f ( x + Δ x ) − f ( x ) = f ′ ( x ) ⋅ Δ x f(x+\Delta x) - f(x) = f^{'}(x) \cdot \Delta x f(x+Δx)−f(x)=f′(x)⋅Δx < 0 ( 3 ) 0 \quad (3) 0(3)
那么,只要满足公式(4)的条件,就可以得到 f ( x + Δ x ) f(x+\Delta x) f(x+Δx) < f ( x ) f(x) f(x)。为了使公式(4)成立,可以令(总所周知,平方大于0)
Δ x = − α ⋅ f ′ ( x ) , α \Delta x = -\alpha \cdot f^{'}(x),\alpha Δx=−α⋅f′(x),α > 0 ( 4 ) 0 \quad (4) 0(4)
所以,可以得到从 x k x_k xk到 x k + 1 x_{k+1} xk+1的迭代过程满足
x k + 1 = x k + Δ x = x k − α ⋅ f ′ ( x k ) ( 5 ) x_{k+1} = x_k + \Delta x = x_k - \alpha \cdot f^{'}(x_k) \quad (5) xk+1=xk+Δx=xk−α⋅f′(xk)(5)
时,始终存在 f ( x k + 1 ) < f ( x k ) f(x_{k+1}) < f(x_k) f(xk+1)<f(xk)。也就是一开始谈到的思路,只要不断寻找值更小的点,就可以最终找到最小值。
算法过程
- 给出初始点 x 0 x_0 x0,学习率 α \alpha α
- 计算 x 0 x_0 x0处的梯度 f ′ ( x 0 ) f^{'}(x_0) f′(x0)
- 判断 ∣ f ′ ( x 0 ) ∣ |f^{'}(x_0)| ∣f′(x0)∣是否小于阈值 δ \delta δ,如果小于,停止迭代,算法结束
- 得到下一个迭代点 x 1 = x 0 − α ⋅ f ′ ( x 0 ) x_1 = x_0 - \alpha \cdot f^{'}(x_0) x1=x0−α⋅f′(x0)
- 重复2-4过程
算法总结
梯度下降算法是最为基础的优化方法之一,它只需要知道梯度方法,不需要计算海森矩阵。计算复杂度较低。但是此方法容易陷入局部极小值,收敛结果对初始点和学习率的要求较高。
最速梯度下降
算法思路
最速梯度下降算法与梯度下降算法思路相似,都是希望每一次迭代的点要比上一次次迭代点的值更小。但是最速梯度下降算法与梯度下降算法的不同之处在于,它对学习率进行了调整,使学习率并不是一个固定值,而是不断变化的。
最速梯度下降算法希望在 x k x_k xk处沿梯度方法 f ( x k ) f(x_k) f(xk)下降时,找到一个学习率 α k \alpha_k αk,使得沿 f ( x k ) f(x_k) f(xk)下降量比选择其他 α \alpha α都要大。用公式表达就是
α k = a r g m i n α f ( x k − α ⋅ f ′ ( x k ) ) ( 6 ) \alpha_k = argmin_{\alpha} f(x_k - \alpha \cdot f^{'}(x_k)) \quad (6) αk=argminαf(xk−α⋅f′(xk))(6)
以上就是最速梯度下降算法的核心。接下来,使用二次型为例子,继续进行说明。(因为二次型具有比较好的性质)我们假设
f ( x ) = 1 2 x T A x − b T x ( 7 ) f(x) = \frac{1}{2} x^T A x - b^T x \quad (7) f(x)=21xTAx−bTx(7)
则可以计算得到f(x)的梯度和海森矩阵分别为
f
′
(
x
)
=
A
x
−
b
(
8
)
f^{'}(x) = Ax - b \quad (8)
f′(x)=Ax−b(8)
f
′
′
(
x
)
=
A
(
9
)
f^{''}(x) = A \quad (9)
f′′(x)=A(9)
同时我们可以令
g ( α ) = f ( x k + 1 ) = f ( x k − α f ′ ( x k ) ) ( 10 ) g(\alpha) = f(x_{k+1})= f(x_k - \alpha f^{'}(x_k)) \quad (10) g(α)=f(xk+1)=f(xk−αf′(xk))(10)
则公式(6)的必要条件为 d g ( α ) d α = 0 \frac{d g(\alpha)}{d \alpha} = 0 dαdg(α)=0。因此,我们通过公式(10)中可以得到
g ′ ( α ) = − f ′ ( x k + 1 ) T f ′ ( x k ) = 0 ( 11 ) g^ {'} (\alpha)= -f^ {'} (x_{k+1})^ T f ^ {'}(x_k)=0 \quad (11) g′(α)=−f′(xk+1)Tf′(xk)=0(11)
将公式(8)代入公式(11)可以得到
f ′ ( x k + 1 ) T f ′ ( x k ) = ( A x k + 1 − b ) T f ′ ( x k ) f^ {'} (x_{k+1})^ T f^ {'} (x_k) = (Ax_{k+1} - b)^ T f^{'}(x_k) f′(xk+1)Tf′(xk)=(Axk+1−b)Tf′(xk)
f ′ ( x k + 1 ) T f ′ ( x k ) = ( A ( x k − α f ′ ( x k ) ) − b ) T f ′ ( x k ) f^{'}(x_{k+1})^T f^{'}(x_k) = (A(x_k - \alpha f^{'}(x_k)) - b)^T f^{'}(x_k) f′(xk+1)Tf′(xk)=(A(xk−αf′(xk))−b)Tf′(xk)
f ′ ( x k + 1 ) T f ′ ( x k ) = ( A x k − b ) T f ′ ( x k ) − α f ′ ( x k ) T A f ′ ( x k ) f^{'}(x_{k+1})^T f^{'}(x_k) = (A x_k - b)^T f^{'}(x_k) - \alpha f^{'}(x_k)^T A f^{'}(x_k) f′(xk+1)Tf′(xk)=(Axk−b)Tf′(xk)−αf′(xk)TAf′(xk)
f ′ ( x k + 1 ) T f ′ ( x k ) = f ′ ( x k ) T f ′ ( x k ) − α f ′ ( x k ) T A f ′ ( x k ) = 0 f^{'}(x_{k+1})^T f^{'}(x_k) = f^{'}(x_k)^T f^{'}(x_k) - \alpha f^{'}(x_k)^T A f^{'}(x_k) = 0 f′(xk+1)Tf′(xk)=f′(xk)Tf′(xk)−αf′(xk)TAf′(xk)=0
α = f ′ ( x k ) T f ′ ( x k ) f ′ ( x k ) T A f ′ ( x k ) ( 12 ) \alpha = \frac{f^{'}(x_k)^T f^{'}(x_k)}{ f^{'}(x_k)^T A f^{'}(x_k)} \quad (12) α=f′(xk)TAf′(xk)f′(xk)Tf′(xk)(12)
所以当待优化函数为二次型时,每一次的学习率的计算公式为公式(12)。梯度下降方法就变成最速梯度下降算法。
算法过程
- 给出初始点 x 0 x_0 x0
- 计算 x 0 x_0 x0处的梯度 f ′ ( x 0 ) f^{'}(x_0) f′(x0)
- 判断 ∣ f ′ ( x 0 ) ∣ |f^{'}(x_0)| ∣f′(x0)∣是否小于阈值 δ \delta δ,如果小于,停止迭代,算法结束
- 计算当前梯度f^{’}(x_0)下的学习率,计算公式为 α 0 = a r g m i n α f ( x 0 − α ⋅ f ′ ( x 0 ) ) \alpha_0 = argmin_{\alpha} f(x_0 - \alpha \cdot f^{'}(x_0)) α0=argminαf(x0−α⋅f′(x0))(如果 f ( x ) f(x) f(x)为二次型,则计算公式为 α 0 = f ′ ( x 0 ) T f ′ ( x 0 ) f ′ ( x 0 ) T A f ′ ( x 0 ) \alpha_0 = \frac{f^{'}(x_0)^T f^{'}(x_0)}{ f^{'}(x_0)^T A f^{'}(x_0)} α0=f′(x0)TAf′(x0)f′(x0)Tf′(x0))(也可以使用Armijo-Goldstein准则或Wolfe-Powell准则)
- 得到下一个迭代点 x 1 = x 0 − α 0 ⋅ f ′ ( x 0 ) x_1 = x_0 - \alpha_0 \cdot f^{'}(x_0) x1=x0−α0⋅f′(x0)
- 重复2-5过程
算法总结
最速梯度下降算法是在梯度下降算法基础上的改进,通过修改学习率,可以提高算法的收敛速度。但是仍然无法避免梯度下降容易被困于局部极小值的问题。
牛顿法
算法思路
牛顿法的思想与梯度下降不同,它并不是寻找比当前点具有更小值的点,而是从极小值的必要条件出发。我们知道,极小值的必要条件为梯度为0,也就是
f ′ ( x ) = 0 ( 13 ) f^{'}(x) = 0 \quad (13) f′(x)=0(13)
从这一点出发,我们可以对 f ( x ) f(x) f(x)进行二阶泰勒展开,如下所示
f ( x + Δ x ) = f ( x ) + f ′ ( x ) Δ x + Δ x T f ′ ′ ( x ) Δ x ( 14 ) f(x + \Delta x) = f(x) + f^{'}(x) \Delta x + \Delta x^T f^{''}(x) \Delta x \quad (14) f(x+Δx)=f(x)+f′(x)Δx+ΔxTf′′(x)Δx(14)
如果满足公式(13),则可以得到 f ( x + Δ x ) = f ( x ) f(x + \Delta x) = f(x) f(x+Δx)=f(x)。将其代入公式(14)可以得到
f ′ ( x ) Δ x + Δ x T f ′ ′ ( x ) Δ x = 0 f^{'}(x) \Delta x + \Delta x^T f^{''}(x) \Delta x = 0 f′(x)Δx+ΔxTf′′(x)Δx=0
Δ x = − f ′ ( x ) f ′ ′ ( x ) ( 15 ) \Delta x = -\frac{f^{'}(x)}{f^{''}(x)} \quad (15) Δx=−f′′(x)f′(x)(15)
这样可以得到每一次迭代的更新量。随着迭代的不断进行,最终可以找到待优化函数的极小值。
算法过程
- 给出初始点 x 0 x_0 x0
- 计算 x 0 x_0 x0处的梯度 f ′ ( x 0 ) f^{'}(x_0) f′(x0)和海森矩阵 f ′ ′ ( x 0 ) f^{''}(x_0) f′′(x0)
- 判断 ∣ f ′ ( x 0 ) ∣ |f^{'}(x_0)| ∣f′(x0)∣是否小于阈值 δ \delta δ,如果小于,停止迭代,算法结束
- 得到下一个迭代点 x 1 = x 0 − f ′ ( x 0 ) f ′ ′ ( x 0 ) x_1 = x_0 - \frac{f^{'}(x_0)}{f^{''}(x_0)} x1=x0−f′′(x0)f′(x0)
- 重复2-4过程
算法总结
相比于梯度下降方法,牛顿法收敛速度更快。但是,它需要计算海森矩阵,计算复杂度较高。如果待优化函数为最小二乘,则可以利用高斯-牛顿法,避免计算海森矩阵。
共轭梯度下降算法
算法思路
共轭梯度下降算法也是一种梯度下降。但与普通梯度下降、最速梯度下降不同之处在于,它下降的方向并不是梯度方向。其思路涉及到线性代数相关知识,比普通梯度下降要更加复杂。为了简化后续的说明,我们还是以二次型作为例子进行讲解,即
f ( x ) = 1 2 x T A x − b T x ( 16 ) f(x) = \frac{1}{2} x^T A x - b^T x \quad (16) f(x)=21xTAx−bTx(16)
在讲解之前,需要先说明一下什么是共轭。设 A A A为 n n n阶实对称正定矩阵,如果有两个 n n n维向量 d 1 d_1 d1和 d 2 d_2 d2满足
d 1 T A d 2 = 0 d_1^T A d_2 = 0 d1TAd2=0
则称向量 d 1 d_1 d1和 d 2 d_2 d2对于矩阵 A A A共轭。若一组非零向量 d 0 , d 1 , . . . , d n − 1 d_0, d_1, ..., d_{n-1} d0,d1,...,dn−1满足
d i T A d j = 0 , i ≠ j d_i^T A d_j = 0, i \neq j diTAdj=0,i=j
则称向量系 d i , ( i = 0 , 1 , . . . , n − 1 ) d_i, (i=0, 1, ..., n-1) di,(i=0,1,...,n−1)为关于矩阵 A A A共轭。了解了共轭向量的概念后,可以很容易知道一组共轭向量 d i , ( i = 0 , 1 , . . . , n − 1 ) d_i, (i=0, 1, ..., n-1) di,(i=0,1,...,n−1)是线性无关的,证明如下。我们构造一组参数 a i , ( i = 0 , 1 , . . . , n − 1 ) a_i, (i=0, 1, ..., n-1) ai,(i=0,1,...,n−1),计算以下表达式成立时的 a i a_i ai。只要 a i a_i ai全部为0,则 d i , ( i = 0 , 1 , . . . , n − 1 ) d_i, (i=0, 1, ..., n-1) di,(i=0,1,...,n−1)是线性无关的。
a 0 d 0 + a 1 d 1 + . . . + a n − 1 d n − 1 = 0 a_0 d_0 + a_1 d_1 + ... + a_{n-1} d_{n - 1} = 0 a0d0+a1d1+...+an−1dn−1=0
我们让等式两边左侧同时乘上 d i T A , ∀ i d_i^T A, \forall i diTA,∀i,根据共轭的条件可以得到
a i d i T A d i = 0 , ∀ i a_i d_i^T A d_i = 0, \forall i aidiTAdi=0,∀i
由于 A A A为正定矩阵, d i T A d i > 0 d_i^T A d_i > 0 diTAdi>0必然成立,因此,要让等式成立,必须 a i = 0 , ∀ i a_i = 0, \forall i ai=0,∀i。则可以证明 d i , ( i = 0 , 1 , . . . , n − 1 ) d_i, (i=0, 1, ..., n-1) di,(i=0,1,...,n−1)是线性无关的。
再回到待优化函数 f ( x ) f(x) f(x)上。其中, x x x是 n n n维向量,且公式(16)中的矩阵 A A A为正定矩阵。我们可以假设,待优化函数 f ( x ) f(x) f(x)取得最小值时的 x x x为 x ∗ x^* x∗,并且存在一组 d i , ( i = 0 , 1 , . . . , n − 1 ) d_i, (i=0, 1, ..., n-1) di,(i=0,1,...,n−1)关于矩阵 A A A共轭。由之前的描述可以得到 d i d_i di是线性无关的。则可以使用 d i d_i di对 x ∗ x^* x∗进行表达,表达式为
x ∗ − x 0 = α 0 d 0 + α 1 d 1 + . . . + α n − 1 d n − 1 ( 17 ) x^* - x_0= \alpha_0 d_0 + \alpha_1 d_1 + ... + \alpha_{n-1} d_{n-1} \quad (17) x∗−x0=α0d0+α1d1+...+αn−1dn−1(17)
那么,可以这样来看,从初始点 x 0 x_0 x0开始,不断在上一个点基础上增加 α i d i \alpha_i d_i αidi,经过 n n n次迭代,就可以得到最终解 x ∗ x^* x∗,用公式表达就是
x k + 1 = x k + α k d k ( 18 ) x_{k+1} = x_k + \alpha_k d_k \quad (18) xk+1=xk+αkdk(18)
可以看到,与梯度下降的迭代公式一致。其中 α k \alpha_k αk就是第 k k k次迭代的学习率,而 d k d_k dk是下降方向。那么,下一步就是找到一组关于矩阵 A A A共轭的方向向量 d k d_k dk。经过推导可以认为
d k + 1 = − g k + 1 + β k d k ( 19 ) d_{k+1} = -g_{k+1} + \beta_k d_k \quad (19) dk+1=−gk+1+βkdk(19)
g k + 1 = f ′ ( x k + 1 ) g_{k+1} = f^{'}(x_{k+1}) gk+1=f′(xk+1)
接下来只要计算出 β k \beta_k βk即可。在公式(19)左侧同时乘上 d k T A d_k^T A dkTA可以得到
d k T A d k + 1 = − d k T A g k + 1 + β k d k T A d k = 0 d_k^T A d_{k+1} = -d_k^T A g_{k+1} +\beta_k d_k^T A d_k=0 dkTAdk+1=−dkTAgk+1+βkdkTAdk=0
β k = − d k T A g k + 1 d k T A d k ( 20 ) \beta_k = \frac{-d_k^T A g_{k+1}}{d_k^T A d_k} \quad (20) βk=dkTAdk−dkTAgk+1(20)
下降方向已经得到了,迭代过程中唯一未知的量还有学习率 α k \alpha_k αk。学习率的计算方法与公式(12)相同,最后计算得到的学习率为
α k = − g k T d k d k T A d k \alpha_k = -\frac{g_k^T d_k}{d_k^T A d_k} αk=−dkTAdkgkTdk
当然,以上公式只有在 f ( x ) f(x) f(x)是二次型的时候才成立,路过不是二次型,需要借助其他方法进行求解。
算法过程
如果 f ( x ) f(x) f(x)是二次型
- 设定 k : = 0 k:=0 k:=0,选择优化初始点 x 0 x_0 x0
- 计算 x 0 x_0 x0处的梯度 g 0 = f ′ ( x 0 ) g_0=f^{'}(x_0) g0=f′(x0),判断 g 0 g_0 g0是否为0,如果是,结束迭代;反之,令 d 0 = − g 0 d_0 = -g_0 d0=−g0
- 计算学习率 α k = − g k T d k d k T A d k \alpha_k = -\frac{g_k^T d_k}{d_k^T A d_k} αk=−dkTAdkgkTdk
- 得到新的点 x k + 1 = x k + α k d k x_{k+1} = x_k + \alpha_k d_k xk+1=xk+αkdk
- 计算梯度 g k + 1 = f ′ ( x k + 1 ) g_{k+1} = f^{'}(x_{k+1}) gk+1=f′(xk+1),判断 g k + 1 g_{k+1} gk+1是否为0,如果是,结束迭代
- 计算新的下降方向参数 β k = g k + 1 T A d k d k T A d k \beta_{k} = \frac{g_{k+1}^T A d_k}{d_k^T A d_k} βk=dkTAdkgk+1TAdk
- 计算新的梯度下降方向 d k + 1 = − g k + 1 + β k d k d_{k+1} = -g_{k+1} + \beta_{k} d_k dk+1=−gk+1+βkdk
- 重复3-7过程
如果 f ( x ) f(x) f(x)不是二次型
- 设定 k : = 0 k:=0 k:=0,选择优化初始点 x 0 x_0 x0
- 计算 x 0 x_0 x0处的梯度 g 0 = f ′ ( x 0 ) g_0=f^{'}(x_0) g0=f′(x0),判断 g 0 g_0 g0是否为0,如果是,结束迭代;反之,令 d 0 = − g 0 d_0 = -g_0 d0=−g0
- 计算学习率 α k = a r g m i n α f ( x k + α ⋅ d k ) \alpha_k = argmin_{\alpha} f(x_k + \alpha \cdot d_k) αk=argminαf(xk+α⋅dk)(可以使用Armijo-Goldstein准则或Wolfe-Powell准则)
- 得到新的点 x k + 1 = x k + α k d k x_{k+1} = x_k + \alpha_k d_k xk+1=xk+αkdk
- 计算梯度 g k + 1 = f ′ ( x k + 1 ) g_{k+1} = f^{'}(x_{k+1}) gk+1=f′(xk+1),判断 g k + 1 g_{k+1} gk+1是否为0,如果是,结束迭代
- (a) 计算新的下降方向参数 β k = g k + 1 T g k + 1 g k T g k \beta_{k} = \frac{g_{k+1}^T g_{k+1}}{g_k^T g_k} βk=gkTgkgk+1Tgk+1(Fletcher-Reeves Formula) (b) 计算新的下降方向参数 β k = g k + 1 T ( g k + 1 − g k ) g k T g k \beta_{k} = \frac{g_{k+1}^T (g_{k+1} - g_k)}{g_k^T g_k} βk=gkTgkgk+1T(gk+1−gk)(Polak-Ribiere Formula) © 计算新的下降方向参数 β k = g k + 1 T ( g k + 1 − g k ) d k T ( g k + 1 − g k ) \beta_{k} = \frac{g_{k+1}^T (g_{k+1} - g_k)}{d_k^T (g_{k+1} - g_k)} βk=dkT(gk+1−gk)gk+1T(gk+1−gk)(Hestenes-Stiefel Formula)
- 计算新的梯度下降方向 d k + 1 = − g k + 1 + β k d k d_{k+1} = -g_{k+1} + \beta_{k} d_k dk+1=−gk+1+βkdk
- 重复3-7过程
算法总结
共轭梯度下降算法对传统梯度下降算法的下降方向进行了优化,其收敛速度介于梯度下降算法和牛顿法之间。并且只需要计算梯度方向,计算复杂度较低。