梯度下降算法原理及其实战

定义:

梯度下降算法是一种用于寻找函数最小值的优化算法。它通过沿着函数梯度的反方向以步长为学习率的方式迭代更新参数,最终达到函数最小值的目的。梯度下降算法广泛应用于机器学习中的模型训练,如线性回归、逻辑回归、神经网络等。它可以用于最小化损失函数、最大化似然函数等目标函数。由于梯度下降算法的简单性和效率,在机器学习领域得到了广泛的应用和研究。

原理:

梯度下降算法用到的数学知有:最小二乘法,代价函数,偏导数

梯度下降算法是一种常用的优化算法,用于求解目标函数的最小值。其基本思想是通过计算目标函数在当前点的梯度方向,沿着梯度的反方向进行迭代,使目标函数逐渐趋于最小值。

具体地,对于一个连续可导的目标函数f(x),在当前点 xi处,通过计算其梯度可以得到函数在该点的最陡下降方向。接下来,通过将当前点朝着最陡下降方向移动一定的步长,得到下一个点。通过不断重复这个过程,即可逐步逼近目标函数的最小值点。

需要注意的是,梯度下降算法有可能陷入局部最优解,因此需要根据实际情况进行调整。同时,步长的选择也对算法的性能有重要影响,如果步长太大可能会导致算法不收敛,而步长太小则会增加算法的迭代次数,降低算法效率。因此,需要通过实验和经验不断调整步长的取值。

举例

比如随机生成一些数据在坐标上如图所示:

 

先选择预测函数是一个线性函数Y(x)=wx+b

因此实验的目标转化为求当w和b在何值时能拟合数据,而在数学上对拟合程序的大小用代价函数来表示

 

函数的值越小则越拟合于数据其中h(x)表示预测函数,m表示样本的数量,当我们把预测函数带入到代价函数再整理后会发现是一个关于w 或b二次函数

这里以b来举例,通过函数可知在中间有个最小值即为拟合最好的时候,

 

因为参数少函数简单可以直接用高中知识求解,但我们换一个思路先给定一个起始值,通过迭代优化的方式找到这个最小值。我们先求出当前的斜率即代价函数关于b的偏导数,在乘以一个常量(学习率)向斜率的反方向前行寻找,此时对于b我们得到一个新的值

 

这个值会比初始的代价函数值更小直到找到最小值b

 

而w的迭代求法同上类似,因此我们通过这样不断的迭代就能找到能拟合数据的w和b至此就是梯度算法的内容

但本次举例的是二元函数,相对来说好迭代,但现实中的预测函数往往很复杂,有可能3元4元不等,因此这些预测函数的代价函数图像不再是个二维图像,可能是个三维图像

 

另外像我们再以上列子中的学习率假定是一个常量,但实际中对于学习率应该是个变量在越接近最小值的时候值越小例如 这就是2011年提出的AdaGrad算法,但式子中的r的变化与梯度有关,可能让学习率过早的变小不好控制,因此在2014年提出了Adam算法帮助快速收敛

 

 

代码实现

本次实验不考虑动态学习率,预测函数为简单的线性函数,同时用matplptlib库实现数据的可视化

代码如下

import numpy as np

import matplotlib.pyplot as plt

#初始化参数

x = np.random.randn(10, 1)

y = 2 * x + np.random.rand()

w = 0.0

b = 0.0

learning_rate = 0.01





def descend(x, y, w, b, learning_rate):

    dldw = 0.0

    dldb = 0.0

    N = x.shape[0]

    for xi, yi in zip(x, y):

        dldw += -2 * xi * (yi - (w * xi + b))#预测函数在均值代价函数中对w的偏导数

        dldb += -2 * (yi - (w * xi + b))#预测函数在均值代价函数中对b的偏导数

    # 计算梯度下降步长

    w = w - learning_rate * (1 / N) * dldw

    b = b - learning_rate * (1 / N) * dldb

    return w, b





fig, ax = plt.subplots()#创建Figure对象和Axes对象。

ax.scatter(x, y)#在图上标出所以点

for epoch in range(400):

    w, b = descend(x, y, w, b, learning_rate)

    yhat = w * x + b

    loss = np.divide(np.sum((y - yhat) ** 2, axis=0), x.shape[0])

    ax.plot(x, yhat, color='r', alpha=0.3)#画函数先

    ax.set_title('Epoch %d - Loss: %.4f' % (epoch, loss))

    plt.pause(0.01)#每画一次函数停止一下

plt.show()

实现界面

 

最终实现如图:

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值