梯度下降算法(一)

简介: 梯度下降是一种迭代优化算法,用于找到多变量函数的最小值。它不直接求解方程,而是从随机初始点开始,沿着梯度(函数增大幅度最大方向)的反方向逐步调整参数,逐步逼近函数的最小值。在单变量函数中,梯度是导数,而在多变量函数中,梯度是一个包含所有变量偏导数的向量。通过计算梯度并乘以学习率,算法更新参数以接近最小值。代码示例展示了如何用Python实现梯度下降,通过不断迭代直到梯度足够小或达到预设的最大迭代次数。该过程可以类比为在雾中下山,通过感知坡度变化来调整前进方向。

梯度下降算法


1.1 什么是梯度下降


在线性回归中,我们使用最小二乘法,能够直接计算损失函数最小值时的参数值,但是,最小二乘法有使用的限制条件,在大多数机器学习的使用场景之下,我们会选择梯度下降的方法来计算损失函数的极小值,首先梯度下降算法的目标仍然是求最小值,但和最小二乘法这种一步到位、通过解方程组直接求得最小值的方式不同,梯度下降是通过一种“迭代求解”的方式来进行最小值的求解,其整体求解过程可以粗略描述为,先随机选取一组参数初始值,然后沿着某个方向,一步一步移动到极小值点


梯度下降法的基本思想可以类比为一个下山的过程:


一个人 被困在山上,需要从山上下来 (i.e. 找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低。因此,下山的路径就无法确定,他必须利用自己周围的信息去找到下山的路径。这个时候,他就可以利用梯度下降算法来帮助自己下山。以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走


首先,我们有一个 可微分的函数 。这个函数就代表着一座山。我们的目标就是找到 这个函数的最小值 ,也就是山底。根据之前的场景假设,最快的下山的方式就是找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是 找到给定点的梯度 ,然后朝着梯度相反的方向,就能让函数值下降的最快。


1.2 梯度的概念


  • 在单变量的函数中,梯度就是函数的微分,代表着函数在某个给定点的切线的斜率;


  • 在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向;


  • 在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。


向量求导的梯度向量形式 :


image.png


在给定具体的参数一组取值之后,我们就能计算梯度表达式的取值,该值也被称为损失函数在某组参数取值下的梯度


image.png 当前的函数是一元函数,我们只需要计算导数即可算出梯度值

image.png

当前的函数是一元函数,我们只需要计算导数即可算出梯度值


image.png

我们可以设置学习率为lr=0.01,则从x0进行移动的距离是0.0111.25=0.1125,而又是朝向梯度的负方向进行移动,因此x0最终移动到了X1=0.5+0.1125=0.6125


1.3代码实现


def gradient_descent(df, x, alpha=0.01, iterations=100, epsilon=1e-8):
    history = [x]
    for i in range(iterations):
        if abs(df(x)) < epsilon:
            print("梯度足够小")
            break
        x = x - alpha * df(x)
        history.append(x)
    return history


  1. df: 目标函数的导数(gradient)。在优化过程中,梯度下降法沿着函数下降最快的方向更新变量x
  2. x: 初始化的起点或当前点,表示我们开始搜索最小值的位置
  3. alpha: 学习率(learning rate),它决定了每次迭代时x的更新步长。较大的alpha可能导致更快的收敛,但也可能使算法错过最小值;较小的alpha可能导致更慢的收敛速度,但结果可能更精确
  4. iterations: 最大迭代次数
  5. epsilon: 极小值,用于判断梯度是否足够小
  6. history: 用于存储每次迭代后的x值,用来绘制优化过程或者检查收敛性


import numpy as np
x = np.linspace(0,6,1000)
y = np.power(x,3) - 3*np.power(x,2)-9*x +2
yf = lambda x: np.power(x,3) - 3*np.power(x,2)-9*x +2
# 求好了导函数,作为一个函数,作用于下面的更新方法
y_d = lambda x: 3*np.power(x,2) - 6*x -9
# 参数表示x的初始值选择1,并且学习率是0.01, 迭代100次
path = gradient_descent(y_d, 1,0.01, 100)
path[-1]


  1. 结果为2.9999876804184145,path中的最后一个值已经很接近于这个函数在【0,6】中最小值坐标点的X值。


path = gradient_descent(y_d, 0.5,0.01, 200)
path[-1]


可以发现迭代200次后,就触发了停止迭代的条件,说明迭代次数以及足够多而且梯度值以及不足以继续下降了。


我们还可以将迭代过程进行可视化展示:


path_x = np.array(path)
path_y = yf(path_x)

plt.plot(x, y)
plt.scatter(x[y.argmin()],y[y.argmin()])
plt.text(0.5,yf(0.5),"start")

plt.quiver(path_x[:-1], path_y[:-1], path_x[1:]-path_x[:-1],path_y[1:]-path_y[:-1], scale_units='xy',angles="xy",scale=1)
plt.show()


  • argmin()与argmax()方法是一种,argmin()是找到当前序列的最小值的索引,方法的参数axis是指沿着某个轴运算。
  • plt.scatter(x[y.argmin()],y[y.argmin()])就是找到函数的全局最小值。


image.png


有了梯度计算公式之后,我们可以使用gradient_descent方法进行迭代计算,计算出x_0的值


loss_prime = lambda x:(np.power(x,2)-2)*x
path = gradient_descent(loss_prime, 1, 0.01,500)
path[-1]


输出1.414213559949299,最小值为1.4142135623730951


先读取并展示数据点:


import matplotlib.pyplot as plt
plt.scatter(data[:,0],data[:,1])
plt.show()
def linear_regression_gd_iteration(X, y, w, alpha=0.01, iterations=100, epsilon=1e-9):
    history = [w]
    for i in range(iterations):
        gd = linearRegression_gd(X, y, w)
        if np.max(np.abs(gd)< epsilon):
            print("梯度过小")
            break
        w = w - alpha * gd
        history.append(w)
    return history
    
lr = 0.001
iterations = 10000
w0 = np.array([-7.5,-7.5]).reshape(-1,1)
path = linear_regression_gd_iteration(X, y , w0,lr,iterations)
path[-1]

def draw_line(X,y,w,lineWidth=2):
    plt.scatter(X[:,0],y)
    yhat = X @ w
    plt.plot(X[:,0],yhat,'r-',linewidth=lineWidth)
    plt.show()
draw_line(X, y, path[-1]) 


梯度下降算法(二)+https://developer.aliyun.com/article/1544681?spm=a2c6h.13148508.setting.27.2a1e4f0euIPhgb

相关文章
|
14天前
|
机器学习/深度学习 算法 PyTorch
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
【从零开始学习深度学习】38. Pytorch实战案例:梯度下降、随机梯度下降、小批量随机梯度下降3种优化算法对比【含数据集与源码】
|
6天前
|
算法
梯度下降算法(二)
梯度下降法中,学习率选择至关重要。0.3的学习率导致无法找到最小值且产生震荡,而0.01则使结果接近最优解(2.99998768)。当学习率进一步减小至0.001,点远离最低点。通过迭代次数增加至1000次,可更接近最低点(2.999999999256501)。梯度下降用于最小化损失,学习率控制参数更新步长,需平衡收敛速度和稳定性。迭代次数和初始点也影响模型性能,合适的初始化能加速收敛并避开局部极小值。
|
8天前
|
机器学习/深度学习 算法 C语言
【深度学习】优化算法:从梯度下降到Adam
【深度学习】优化算法:从梯度下降到Adam
35 1
|
13天前
|
机器学习/深度学习 算法 PyTorch
《PyTorch深度学习实践》--3梯度下降算法
《PyTorch深度学习实践》--3梯度下降算法
|
1月前
|
算法 vr&ar Python
R语言用极大似然和梯度下降算法估计GARCH(p)过程
R语言用极大似然和梯度下降算法估计GARCH(p)过程
|
1月前
|
机器学习/深度学习 算法
反向传播原理的梯度下降算法
反向传播原理的梯度下降算法
|
9月前
|
机器学习/深度学习 算法 大数据
机器学习梯度下降算法
机器学习梯度下降算法
46 0
|
9月前
|
算法
梯度下降算法详解(从下山比喻、数学推导到代码实现)
梯度下降算法详解(从下山比喻、数学推导到代码实现)
173 0
|
10月前
|
机器学习/深度学习 算法 Python
数学和微分角度理解梯度下降算法
数学和微分角度理解梯度下降算法
|
10月前
|
机器学习/深度学习 算法 PyTorch
Gradient Descent Algorithm 梯度下降算法
Gradient Descent Algorithm 梯度下降算法
63 0