(最优化理论与方法)第六章无约束优化算法-第二节:梯度类算法

文章目录

  • 一:梯度下降法
    • (1)梯度下降法概述
    • (2)梯度下降法求解步骤
    • (3)Python实现
    • (4)常见梯度下降算法
      • A:全梯度下降算法(FGD)
      • B:随机梯度下降算法(SGD)
      • C:小批量梯度下降算法
  • 二:Barzilai-Borwein方法

梯度类算法:梯度类算法本质是使用函数的一阶导数信息选取下降方向 d k d^{k} dk,这其中最基本的算法是梯度下降法,也即直接选择负梯度作为下降方向 d k d^{k} dk,此外还有BB方法,是一种梯度法的变形,虽然理论性质目前仍不完整,但由于它有优秀的数值表现,也是在实际应用中使用较多的一种算法

一:梯度下降法

(1)梯度下降法概述

梯度下降法(Gradient descent,GD):使用梯度下降法寻找函数极小值时,会沿着当前点对应梯度(或近似梯度)的反方向 d d d所规定的步长 α \alpha α内进行迭代搜索。当然如果沿着梯度正方向搜索,就会接近函数的局部最大值,此时对应梯度上升法

我们经常会用下山这个例子来理解梯度下降法:现在你可以想象自己站在一座高山上的某一位置,需要下山,那么此时最快的下山策略就是环顾四周、哪里最陡峭就沿着哪个方向下山,每到一个新的地方后再次执行这个策略

  • 在机器学习中,上面的初始位置就相当于损失函数的初始值,山体的陡峭程度则是梯度,对应于损失函数的导数后偏导数
    (最优化理论与方法)第六章无约束优化算法-第二节:梯度类算法_第1张图片

可以看出梯度下降有时得到的是局部最优解,如果损失函数是凸函数,梯度下降法得到的解就是全局最优解

因此,梯度下降法公式为

θ i = θ i − α ∂ J ( θ 0 , θ 1 , . . . , θ n ) ∂ θ i \theta_{i}=\theta_{i}-\alpha \frac{\partial J(\theta_{0},\theta_{1},...,\theta_{n})}{\partial \theta_{i}} θi=θiαθiJ(θ0,θ1,...,θn)

(2)梯度下降法求解步骤

梯度下降法求解步骤:如下

  • 确定当前位置的损失函数梯度,对于 θ i \theta_{i} θi,其梯度表达式为 ∂ J ( θ 0 , θ 1 , . . . , θ n ) ∂ θ i \frac{\partial J(\theta_{0},\theta_{1},...,\theta_{n})}{\partial \theta_{i}} θiJ(θ0,θ1,...,θn)
  • 用步长乘以损失函数梯度,得到当前位置下降的距离,也即 α ∂ J ( θ 0 , θ 1 , . . . , θ n ) ∂ θ i \alpha \frac{\partial J(\theta_{0},\theta_{1},...,\theta_{n})}{\partial \theta_{i}} αθiJ(θ0,θ1,...,θn)
  • 确定是否所有的 θ i \theta_{i} θi梯度下降的距离都小于 ξ \xi ξ,如果小于则算法终止,当前所有的 θ i \theta_{i} θi即为最终结果。否则转入下一步
  • 更新所有的 θ i \theta_{i} θi,即 θ i = θ i − α ∂ J ( θ 0 , θ 1 , . . . , θ n ) ∂ θ i \theta_{i}=\theta_{i}-\alpha \frac{\partial J(\theta_{0},\theta_{1},...,\theta_{n})}{\partial \theta_{i}} θi=θiαθiJ(θ0,θ1,...,θn),更新完毕后转入第一步

(3)Python实现

  • 注意 a l p h a alpha alpha的选择可以参照前文,这里固定 a l p h a alpha alpha为0.01
import numpy as np
import torch
from sympy import *

# 计算梯度函数
def cal_grad_funciton(function):
    res = []
    x = []
    x.append(Symbol('x1'))
    x.append(Symbol('x2'))
    for i in range(len(x)):
        res.append(diff(function, x[i]))
    return res

# 定义目标函数
def function_define():
    x = []
    x.append(Symbol('x1'))
    x.append(Symbol('x2'))
    # y = 2 * (x[0] - x[1] ** 2) ** 2 + (1 + x[1]) ** 2
    # Rosenbrock函数
    y = 100 * (x[1] - x[0] ** 2) ** 2 + (1 - x[0]) ** 2
    
    return y

# 计算函数返回值
def cal_function_ret(function, x):
    res = function.subs([('x1', x[0]), ('x2', x[1])])
    return res

# 计算梯度
def cal_grad_ret(grad_function, x):
    res = []
    
    for i in range(len(x)):
        res.append(grad_function[i].subs([('x1', x[0]), ('x2', x[1])]))
    return res

def norm(x):
    return sqrt(np.dot(x, x))

def gradient_descent(function, grad_function, x):
    k = 1
    
    d = cal_grad_ret(grad_function, x)
    d = np.dot(-1, d).tolist()
    alpha = 0.01
    while norm(d) > 0.00001 and k < 1000:
        d = cal_grad_ret(grad_function, x)
        d = np.dot(-1, d).tolist()
        # armijo_goladstein准则选择步长
        # alpha = armijo_goldstein(function, grad_function, x, d)
        # armijo_wlofe准则选择步长
        # alpha = armijo_wlofe(function, grad_function, x, d)
        x = np.add(x, np.dot(alpha, d))
        k = k + 1
    
    # 返回最小值点,函数最小值和迭代次数
    return x, cal_function_ret(function, x), k


if __name__ == '__main__':
    function = function_define()
    grad_function = cal_grad_funciton(function)
    print("函数为:", function)
    print("梯度函数为:", grad_function)

    x0 = [-10, 10]
    Min, MinValue, Iterator = gradient_descent(function, grad_function, x0)
    print("最小值点为:", Min)
    print("最小值为:", MinValue)
    print("迭代次数为:", Iterator)

(最优化理论与方法)第六章无约束优化算法-第二节:梯度类算法_第2张图片

(4)常见梯度下降算法

A:全梯度下降算法(FGD)

全梯度下降算法(FGD):计算训练集所有样本误差,对其求和再取平均值作为目标函数。权重向量沿其梯度相反的方向移动,从而使当前目标函数减少得最多。因为在执行每次更新时,需要在整个数据集上计算所有的梯度,所以速度会很慢,同时,其在整个训练数据集上计算损失函数关于参数θ的梯度

θ = θ − η ⋅ ∇ θ J ( θ ) \theta = \theta -\eta \cdot \nabla_{\theta}J(\theta) θ=θηθJ(θ)

B:随机梯度下降算法(SGD)

随机梯度下降算法(SGD):由于FGD每迭代更新一次权重都需要计算所有样本误差,而实际问题中经常有上亿的训练样本,故效率偏低,且容易陷入局部最优解,因此提出了随机梯度下降算法。其每轮计算的目标函数不再是全体样本误差,而仅是单个样本误差,即每次只代入计算一个样本目标函数的梯度来更新权重,再取下一个样本重复此过程,直到损失函数值停止下降或损失函数值小于某个设定的阈值。此过程简单,高效,通常可以较好地避免更新迭代收敛到局部最优解。其迭代形式为

θ = θ − η ⋅ ∇ θ J ( θ ; x ( i ) ; y ( i ) ) \theta = \theta -\eta \cdot \nabla_{\theta}J(\theta;x^{(i)};y^{(i)}) θ=θηθJ(θ;x(i);y(i))

  • x ( i ) x^{(i)} x(i):表示一条训练样本的特征值
  • x ( i ) x^{(i)} x(i):表示一条训练样本的标签值

C:小批量梯度下降算法

小批量梯度下降算法:小批量梯度下降算法是FG和SG的折中方案,在一定程度上兼顾了以上两种方法的优点。每次从训练样本集上随机抽取一个小样本集,在抽出来的小样本集上采用FGD迭代更新权重。被抽出的小样本集所含样本点的个数称为batch_size,通常设置为2的幂次方,更有利于GPU加速处理

  • batch_size=1,则变成了SGD
  • batch_size=n,则变成了FGD

θ = θ − η ⋅ ∇ θ J ( θ ; x ( i : i + n ) ; y ( i : i + n ) ) \theta = \theta -\eta \cdot \nabla_{\theta}J(\theta;x^{(i:i+n)};y^{(i:i+n)}) θ=θηθJ(θ;x(i:i+n);y(i:i+n))

二:Barzilai-Borwein方法

随机梯度下降算法(SGD):当问题的条件数很大,也即问题比较病态时,梯度下降法的收敛性质会受到很大影响。Barzilai-Borwein方法是一种特殊的梯度法,经常比一般的梯度法有着更好的效果,从形式上来看,BB方法的下降方向仍然是点 x k x^{k} xk处的负梯度方向,但是步长 a k a_{k} ak并不是直接由线搜索算法给出的

考虑下降法格式

x k + 1 = x k − α k ∇ f ( x k ) x^{k+1}=x^{k}-\alpha_{k}\nabla f(x^{k}) xk+1=xkαkf(xk)

这种格式也可以写成

x k + 1 = x k − D k ∇ f ( x k ) x^{k+1}=x^{k}-D^{k}\nabla f(x^{k}) xk+1=xkDkf(xk)

其中 D k = α k I D^{k}=\alpha_{k}I Dk=αkI。BB方法选取的 α k \alpha_{k} αk是如下两个最优问题之一的解

  • ①: m i n α ∣ ∣ α y k − 1 − s k − 1 ∣ ∣ 2 \mathop{min}\limits_{\alpha}\quad ||\alpha y^{k-1}-s^{k-1}||^{2} αminαyk1sk12
  • ②: m i n α ∣ ∣ y k − 1 − α − 1 s k − 1 ∣ ∣ 2 \mathop{min}\limits_{\alpha}\quad || y^{k-1}-\alpha^{-1}s^{k-1}||^{2} αminyk1α1sk12

其中引入记号

  • s k − 1 = d e f x k − x k − 1 s^{k-1}\mathop{=}\limits^{def}x^{k}-x^{k-1} sk1=defxkxk1
  • y k − 1 = d e f ∇ f ( x k ) − ∇ f ( x k − 1 ) y^{k-1}\mathop{=}\limits^{def}\nabla f(x^{k})-\nabla f(x^{k^{-1}}) yk1=deff(xk)f(xk1)

容易验证问题①和②的解分别为

  • α B B 1 k = d e f ( s k − 1 ) T y k − 1 ( y k − 1 ) T y k − 1 \alpha^{k}_{BB1}\mathop{=}\limits^{def}\frac{(s^{k-1})^{T}y^{k-1}}{(y^{k-1})^{T}y^{k-1}} αBB1k=def(yk1)Tyk1(sk1)Tyk1

  • α B B 2 k = d e f ( s k − 1 ) T s k − 1 ( s k − 1 ) T y k − 1 \alpha^{k}_{BB2}\mathop{=}\limits^{def}\frac{(s^{k-1})^{T}s^{k-1}}{(s^{k-1})^{T}y^{k-1}} αBB2k=def(sk1)Tyk1(sk1)Tsk1

    • 这两个式子表明,计算两种BB步长的任何一种仅仅需要函数相邻两步的梯度信息和迭代点信息,不需要任何线搜索算法即可选取算法步长
    • 对于一般的问题,通过上面式子计算出的步长可能过大或者过小,因此我们还需要将步长截断。也即选取 0 < α m < α M 0 < \alpha_{m} <\alpha_{M} 0<αm<αM,使得 α m ≤ α k ≤ α M \alpha_{m} \leq \alpha_{k} \leq \alpha_{M} αmαkαM

由此可得到BB方法的两种迭代格式

  • x k + 1 = x k − α B B 1 k ∇ f ( x k ) x^{k+1}=x^{k}-\alpha^{k}_{BB1}\nabla f(x^{k}) xk+1=xkαBB1kf(xk)
  • x k + 1 = x k − α B B 2 k ∇ f ( x k ) x^{k+1}=x^{k}-\alpha^{k}_{BB2}\nabla f(x^{k}) xk+1=xkαBB2kf(xk)

下图给出了BB方法的一种框架

(最优化理论与方法)第六章无约束优化算法-第二节:梯度类算法_第3张图片

你可能感兴趣的:(最优化理论与方法,算法,人工智能)