梯度下降法

梯度下降

梯度下降(Gradient Descent)又称最速下降(steepest descent),是求解无约束最优化问题的一种常用方法,梯度下降法是一种迭代算法,每一步都需要求解目标函数的梯度向量
假设 f ( x ) f(x) f(x) R n R^n Rn上具有一阶连续偏倒数的函数,要求解以下无约束最优化问题:
min ⁡ x ∈ R n f ( x ) \min_{x \in R^n} f(x) xRnminf(x)
x ∗ x^* x表示要求解的目标函数 f ( x ) f(x) f(x)的极小点,即,目标函数 f ( x ) f(x) f(x) x ∗ x^* x处能够取得极小值。

梯度下降法是一种迭代算法。首先选取适当的初始值 x ( 0 ) x^{(0)} x(0),通过不断迭代来更新 x x x的值,进行目标函数的极小化,直到收敛。由于负梯度方向是使函数值下降最快的方向,在迭代的每一步,以负梯度方向更新 x x x的值,从而达到减少函数值的目的。

由于 f ( x ) f(x) f(x)具有一阶连续偏导数,若第 k k k次迭代值为 x ( k ) x^{(k)} x(k),则可将 f ( x ) f(x) f(x) x ( k ) x^{(k)} x(k)附近进行一阶泰勒展开:
f ( x ) = f ( x ( k ) ) + g k T ( x − x ( k ) ) f(x)=f(x^{(k)})+g_k^T(x-x^{(k)}) f(x)=f(x(k))+gkT(xx(k))
上式中的 g k = g ( x ( k ) ) = ∇ f ( x ( k ) ) g_k=g(x^{(k)})=\nabla f(x^{(k)}) gk=g(x(k))=f(x(k)) f ( x ) f(x) f(x)在点 x ( k ) x^{(k)} x(k)处的梯度。
k + 1 k+1 k+1次的迭代值 x ( k + 1 ) x^{(k+1)} x(k+1)可有以下方式获得:
x ( k + 1 ) ← x ( k ) + λ k p k x^{(k+1)} \leftarrow x^{(k)} + \lambda_k p_k x(k+1)x(k)+λkpk
上式中, p k p_k pk 是搜索方向,取负梯度方向 p k = − ∇ f ( x ( k ) ) p_k = -\nabla f(x^{(k)}) pk=f(x(k)) λ k \lambda_k λk是步长,由一维搜索确定,即 λ k \lambda_k λk使得
f ( x ( k ) + λ k p k ) = min ⁡ λ ≥ 0 f ( x ( k ) + λ p k ) f(x^{(k)} + \lambda_k p_k) = \min_{\lambda \geq 0} f(x^{(k)} + \lambda p_k) f(x(k)+λkpk)=λ0minf(x(k)+λpk)

梯度下降法具体步骤

梯度下降法具体步骤如下:
输入:目标函数 f ( x ) f(x) f(x),梯度函数 g ( x ) = ∇ f ( x ) g(x) = \nabla f(x) g(x)=f(x),计算精度 ϵ \epsilon ϵ
输出 f ( x ) f(x) f(x)的极小值点 x ∗ x^* x
(1) 取初始值 x ( 0 ) ∈ R n x^{(0)} \in R^n x(0)Rn,令 k = 0 k=0 k=0
(2) 计算 f ( x ( k ) ) f(x^{(k)}) f(x(k))
(3) 计算梯度 g k = g ( x ( k ) ) g_k=g(x^{(k)}) gk=g(x(k)),当 ∣ ∣ g k < ϵ ∣ ∣ ||g_k < \epsilon|| gk<ϵ时,停止迭代,并令 x ∗ = x ( k ) x^* = x^{(k)} x=x(k);否则,令 p k = − g ( x ( k ) ) p_k = -g(x^{(k)}) pk=g(x(k)),求 λ k \lambda_k λk,使
f ( x ( k ) + λ k p k ) = min ⁡ λ ≥ 0 f ( x ( k ) + λ p k ) f(x^{(k)} + \lambda_k p_k) = \min_{\lambda \geq 0} f(x^{(k)} + \lambda p_k) f(x(k)+λkpk)=λ0minf(x(k)+λpk)
(4) 令 x ( k + 1 ) = x ( k ) + λ k p k x^{(k+1)} = x^{(k)} + \lambda_k p_k x(k+1)=x(k)+λkpk,计算 f ( x ( k ) ) f(x^{(k)}) f(x(k)),当 ∣ ∣ f ( x ( k + 1 ) ) − f ( x ( k ) ) ∣ ∣ < ϵ ||f(x^{(k+1)})- f(x^{(k)})|| < \epsilon f(x(k+1))f(x(k))<ϵ ∣ ∣ x ( k + 1 ) − x ( k ) ∣ ∣ < ϵ ||x^{(k+1)}-x^{(k)}||<\epsilon x(k+1)x(k)<ϵ时,停止迭代,并令 x ∗ = x ( k + 1 ) x^* = x^{(k+1)} x=x(k+1)
(5) 否则,令 k = k + 1 k = k+1 k=k+1,转至步骤(3)。

当目标函数是凸函数时,梯度下降法的解是全局最优解。一般情况下,其解不保证是全局最优解。梯度下降法的收敛速度也未必是最快的。

示例1-求解一元函数极小值

一元函数 f ( x ) f(x) f(x) 为:

f ( x ) = ( x + 1 ) ( x − 1 ) ( x + 2 ) ( x − 2 ) f(x)=(x+1)(x-1)(x+2)(x-2) f(x)=(x+1)(x1)(x+2)(x2)

f ( x ) f(x) f(x) 求导可得:

f ′ ( x ) = 4 x 3 − 10 x f'(x)=4x^3-10x f(x)=4x310x

def f(x):
    """
    原函数
    """
    return (x+1)*(x-1)*(x+2)*(x-2)

def df(x):
    """
    导函数
    """
    return 4*x**3-10*x
lr = 0.001
x = -3

for i in range(1000):
    x -= lr*df(x)    # 迭代
    if i%100==0:
        print("epoch:{},x:{}".format(i,x))
print("epoch:{},x:{}".format(i,x))

输出如下:

epoch:0,x:-2.922
epoch:100,x:-1.6594568957100684
epoch:200,x:-1.5908783935416804
epoch:300,x:-1.5824199959582812
epoch:400,x:-1.5813085551214408
epoch:500,x:-1.5811613357358625
epoch:600,x:-1.5811418147173184
epoch:700,x:-1.5811392259039174
epoch:800,x:-1.5811388825776078
epoch:900,x:-1.5811388370458432
epoch:999,x:-1.581138831026283

示例2-求解二元函数极小值

求解二元函数 f ( x , y ) f ( x , y ) f(x,y)的极小值:

f ( x , y ) = x 3 − y 3 + 3 x 2 + 3 y 2 − 9 x f ( x , y ) = x ^ { 3 } - y ^ { 3 } + 3 x ^ { 2 } + 3 y ^ { 2 } - 9 x f(x,y)=x3y3+3x2+3y29x

x x x求偏导数:

∂ f ∂ x = 3 x 2 + 6 x − 9 \frac{\partial f}{\partial x}=3x^2+6x-9 xf=3x2+6x9

y y y求偏导数:

∂ f ∂ y = − 3 y 2 + 6 y \frac{\partial f}{\partial y}=-3y^2+6y yf=3y2+6y

def f(x,y):
    """
    参数:
    x -- x 的值
    y -- y 的值

    返回:
    v -- 当取 x, y 时,该多元函数的值
    """
    v = x**3-y**3+3*x**2+3*y**2-9*x
    return v

def dx(x, y):
    """
    x的偏导数
    
    参数:
    x -- x 的值
    y -- y 的值

    返回:
    v -- 当取 x, y 时,该多元函数关于 x 的偏导的值
    """
    v = 3*x**2+6*x-9
    return v

def dy(x, y):
    """
    y的偏导数
    
    参数:
    x -- x 的值
    y -- y 的值

    返回:
    v -- 当取 x, y 时,该多元函数关于 y 的偏导的值
    """
    v = -3*y**2+6*y
    return v

def df(x,y):
    """
    f(x,y)的导数
    """
    return dx(x, y),dy(x, y)
def gradient_descent(x, y, f, dx, dy, lr, max_iter):
    """
    梯度下降法求解二元函数极小值点的计算函数
    
    参数:
    x -- 初始变量 x 的值
    y -- 初始变量 y 的值
    f -- 该数学函数所定义的 Python 函数
    dx -- 函数 f 关于 x 的偏导数,Python 函数
    dy -- 函数 f 关于 y 的偏导数,Python 函数
    lr -- 学习率,即参数更新速度
    max_iter -- 最大迭代次数

    返回:
    x -- 极小值点对应的 x 的值
    y -- 极小值点对应的 y 的值
    v -- 极小值点的值
    """
    
    for i in range(max_iter):
        x -= lr*dx(x,y)
        y -= lr*dy(x,y)
    
    v = f(x,y)

    return x, y, v
import numpy as np

np.random.seed(10) # 设置随机数种子
# 初始点和学习率
x = np.random.randn(1)
y = np.random.randn(1)
lr = 0.1
max_iter = 1000

gradient_descent(x, y, f, dx, dy, lr, max_iter)

输出如下:

(array([1.]), array([0.]), array([-5.]))

参考:

[1] 李航. 统计学习方法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

great-wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值