梯度法及其应用(python示例)

上一篇《导数,数值微分,偏导数,以及梯度下降的Python示例》展示了梯度下降的相关概念和代码示例,本篇展示梯度下降法的具体应用

梯度法

通过上一篇我们已经知道,函数中某个点的梯度,就是该点处函数值函数值减小最多的方向。例如函数:
y=x02+x12
如果将x0和x1在[-2,2]区间内每个点的‘负梯度’计算并用python画出来,可以发现每个点的梯度都指向函数的最小值对应的坐标点(0,0):
在这里插入图片描述
利用这一特性,我们可以用来求解函数的极值,就是梯度下降法。其算法描述如下:
第一步:随机一个点
第二步:计算该点的梯度
第三步:沿着该点的梯度,前进一定距离
第四步:再次进入第二步,知道达到最大循环次数

其中第三步:沿梯度下降一定距离,数学表达如下:
x i = x i − η ∂ f ∂ x i ( 公 式 1 , η 为 学 习 率 ) x_i=x_i-\eta\frac{\partial^{}f}{\partial x^{}_i}(公式1 ,\eta为学习率) xi=xiηxif(1η)

上面的步骤,就像你在一座山上,想最快下山,因此你每次都找到当前位置“最陡”的方向(梯度),下降一段距离,再找最陡的方向…
我们可以看到,梯度下降法是一种贪心算法,对于非凸函数,容易陷入局部最优(最终你到了一个离你最近的山谷里,但不一定是山脚下)。如何跳出局部最优此处暂不讨论。
在这里插入图片描述

梯度法求解函数极值的手工计算过程

按照上面的算法,我们手工计算y=x02+x12的最小值
(1) 随机一个点(-3,4),设定学习率η为0.1, 最大循环次数100次
   解析函数式对x0的偏导计算公式:=2x0
   解析函数式对x1的偏导计算公式:=2x1
(2) 计算点(-3,4)处的梯度,得到向量(-6,8)
(3) 根据公式1,计算新的点:
   x0=-3-0.1*(-6)=-24
   x2=4-0.1*(8)=3.2
   可以看到两个维度都向(0,0)点靠近了一些
(4)回到第(2)步,计算新的点(-2.4,3.2)处的梯度,得到(-4.8,6.4)
(5)进入到第(3)步,计算新的点,得到(-1.92 2.56)…
…直到循环次数达到100次

梯度法求函数极值的python实现

python代码如下:
使用微分法求解偏导数,参见前一篇《导数,数值微分,偏导数,以及梯度下降的Python示例

import numpy as np

# 要计算的函数
def f(x):
    return x[0]**2+x[1]**2

# 通过数值微分计算梯度,注意x为数组
def numerical_gradient(f,x):
    h=1e-4 #0.0001,∆x,注意不能太小,会导致舍入误差而变成0
    grad=np.zeros_like(x)

    for index in range(x.size):
        #计算第index个x的偏导数
        temp_val=x[index]
        x[index]=temp_val+h
        fxh1=f(x)
        x[index]=temp_val-h
        fxh2=f(x)

        # 将偏导数存为梯度向量
        grad[index]=(fxh1-fxh2)/(2*h)
        x[index]=temp_val

    return  grad

#梯度下降法
# lr为学习率,step_num为最大循环次数
def gradient_descent(f,x,lr=0.1,step_num=100):
    ini_x=x
    for step in range(step_num):
        grad=numerical_gradient(f,ini_x)
        ini_x-=lr*grad #更新向量

    print("解向量{},函数最小值:{}".format(ini_x,f(ini_x)))

gradient_descent(f,np.array([-3.0,4.0]))

运行结果:
解向量[-6.11110793e-10 8.14814391e-10],函数最小值:1.0373788922158197e-18

这是一个非常接近(0,0)的结果
如果将每次得到的向量标记在坐标上,可以直观看出梯度下降效果:
在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值