多元线性回归梯度下降法

本文涉及的产品
实时计算 Flink 版,1000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 梯度下降法是一种通用的优化算法,尤其适用于机器学习中找到最优解。与解析解法不同,它不局限于特定情况,能在数据规模较大时依然有效。该方法通过迭代逐步接近最优解,每次迭代利用损失函数的梯度信息调整参数。学习率是控制参数更新幅度的关键因素,太大会导致发散,太小则收敛慢。全量梯度下降每次使用所有样本更新,收敛稳定但速度慢;随机梯度下降每次仅用一个样本,速度快但可能产生较大波动;小批量梯度下降取两者之间,以一定的样本批量进行更新,兼顾速度和稳定性。

梯度下降法(Gradient Descent)是一个算法,但不同于解析解法一般局限,相反,他是一个非常通用的优化算法来帮助一些机器学习求出最优解。

 解析解可以成功的原因是MSE损失函数是凸函数,即Hessian矩阵半正定,但假使损失函数非凸,解析解就比较局限。而且解析解的运算较为复杂,时间复杂度达到 。所以解析解法在涉及数据较大时并不好用。

梯度下降法是一点点逼近最优解的方法

image.gif 编辑

梯度下降公式

这里梯度下降公式仅仅只是一个指导计算机迭代过程中如何去调整θ变化的式子,不需要推导和证明。其中 为学习率(learning rate)。学习率一般为正数。在最优解左侧,梯度小于0,学习率大于0,Wj递增,靠近最优解。同理,在最优解右侧,梯度大于0,学习率大于0,Wj递减,同样会靠近最优解。

学习率设置

image.gif 编辑

如上图所示,小学习率比较稳定,但是迭代次数会比较大,如果遇到鞍面会停留很长时间。

适中的学习率迭代次数更少而且可以跳出局部最优解去寻找更好的解,但是可能会出现达不到最优解的情况。大学习率会发散,损失函数会越来越大。这种是不可取的学习率。最后是最优学习率(一般不考虑),即一步直接到最优解。

image.gif 编辑

我们可以设置学习率随着迭代次数减小,这样既可以跳出局部最优解,同时也保证可以收敛到最优解。这个过程我们称为学习速率调整(又称学习速率调度):一般使用某种事先设定好的策略或者在每次迭代中衰减一个减小的阈值。

梯度下降的流程(附代码)

Step 1. 随机θ参数

我们先创建一组随机的θ参数作为起始点

import numpy as np
theta = np.random.randn(2,1)#创建一组服从正态分布的参数

image.gif

这里,我们创建一个两行一列的参数矩阵。

Step 2. 求解梯度

简而言之,假设X(mxn),W(nx1)某个维度j的梯度gradient(j) = ε(mx1)乘上X的第j列,这显然不符合矩阵相乘,所以真实情况是需要将Xj转置。

import numpy as np
gradients = X_b.T.dot((X_b.dot(theta) - y))

image.gif

Step 3. 调整θ参数

判断收敛时使用g= 0并不合理,因为当损失函数时非凸函数的话,g = 0只是一个驻点,还可能是最大值,这不能说明什么。其实判断loss下降收益更加合理,当收益不再变化就可以认为达到局部最优解。即

theta = theta - learning_rate * gradients

image.gif

梯度下降的分类

区别:三种梯度下降的区别仅在于第二步求解梯度所用到的X数据集的样本数量不同,每次学习(更新模型参数)使用的样本数目,每次使用不同的样本会导致每次学习的准确性和学习时间不同。

全量梯度下降(Batch Gradient Descent)

在全量梯度下降中,对于θ的更新,所有样本都有贡献,也就是参与调整θ。其计算得到的是一个标准梯度。因而理论上来说一次更新的幅度是比较大的。如果样本不多的情况下,这样的收敛速度会更快,优点在于每次更新都会朝着正确的方向进行,最终收敛于极值点,缺点就是时间比较长。

import numpy as np
#全量梯度下降
X = np.random.rand(100,1)
y = 4+3*X + np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
#创建超参数
n_iterations = 10000
t0,t1 = 5, 500
#定义一个函数来动态调整学习率
def learning_rate_schedule(t):
    return t0/(t+t1)
#初始化theta
theta = np.random.randn(2,1)
truth =np.array([[4],[3]])
#判断是否收敛,一般不设置阈值,而是采用相对大的迭代次数保证收敛
for i in range(n_iterations):
    # 求梯度,计算gradient
    gradients = X_b.T.dot((X_b.dot(theta) - y))  # 一个含有g0和g1的列向量
    # 应用梯度下降法的公式去调整theta值
    learning_rate = learning_rate_schedule(i)
    theta = theta - learning_rate * gradients
print(theta)
print("Error(%):")
print("W0=",((abs(theta-truth)[0,:]/abs(truth)[0,:])*100)[0],"%")
print("W1=",((abs(theta-truth)[1,:]/abs(truth)[1,:])*100)[0],"%")

image.gif

image.gif

随机梯度下降(Stochastic Gradient Descent)

梯度下降算法每次从训练集中随机选择一个样本来进行学习

优点:学习非常迅速,可能会选择更好的局部最优解。

缺点:每次更新可能并不会按照正确方向进行,因此带来优化波动,迭代次数增加。

import numpy as np
X = np.random.rand(100,1)
y = 4 + 3*X + np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
n_epochs = 10000
m = 100
truth =np.array([[4],[3]])
t0,t1 = 5, 500
def learning_rate_schedule(t):
    return t0/(t+t1)
theta = np.random.randn(2,1)
for epoch in range(n_epochs):
    #每个轮次开始前打乱顺序
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    for i in range(m):
        xi = X_b[i:i+1]#左闭右开
        yi = y[i:i+1]
        gradients = xi.T.dot((xi.dot(theta) - yi))
        learning_rate = learning_rate_schedule(epoch*m + i)
        theta = theta - learning_rate*gradients
print(theta)
print("Error(%):")
print("W0=",((abs(theta-truth)[0,:]/abs(truth)[0,:])*100)[0],"%")
print("W1=",((abs(theta-truth)[1,:]/abs(truth)[1,:])*100)[0],"%")

image.gif

image.gif 编辑

小批量梯度下降(Mini-Batch Gradient Descent)

Mini-Batch梯度下降综合了batch梯度下降与stochastic梯度下降,在每次更新速度与更新次数中间取得一个平衡,其每次更新从训练集中随机选择batch-size个样本进行学习,使得学习更加稳定。

import numpy as np
X = 2*np.random.rand(100,1)
y = 4+3*X + np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
learning_rate = 0.0001
n_epochs = 10000
m = 100
batch_size = 10
num_batches = int(m/batch_size)
theta = np.random.randn(2,1)
truth =np.array([[4],[3]])
for epoch in range(n_epochs):
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    for i in range(num_batches):
        selected_index = np.random.randint(m)
        x_batch = X_b[i:i+batch_size]
        y_batch = y[i:i+batch_size]
        gradients = x_batch.T.dot((x_batch.dot(theta) - y_batch))
        theta = theta - learning_rate * gradients
print(theta)
print("Error(%):")
print("W0=",((abs(theta-truth)[0,:]/abs(truth)[0,:])*100)[0],"%")
print("W1=",((abs(theta-truth)[1,:]/abs(truth)[1,:])*100)[0],"%")

image.gif

image.gif 编辑

目录
相关文章
|
数据采集 机器学习/深度学习 算法
|
12月前
|
机器学习/深度学习 算法
机器学习入门:梯度下降算法(上)
机器学习入门:梯度下降算法(上)
|
机器学习/深度学习 存储 算法
梯度下降算法(一)
梯度下降是一种迭代优化算法,用于找到多变量函数的最小值。它不直接求解方程,而是从随机初始点开始,沿着梯度(函数增大幅度最大方向)的反方向逐步调整参数,逐步逼近函数的最小值。在单变量函数中,梯度是导数,而在多变量函数中,梯度是一个包含所有变量偏导数的向量。通过计算梯度并乘以学习率,算法更新参数以接近最小值。代码示例展示了如何用Python实现梯度下降,通过不断迭代直到梯度足够小或达到预设的最大迭代次数。该过程可以类比为在雾中下山,通过感知坡度变化来调整前进方向。
|
4月前
|
存储 Java
银行余额生成器,银行汇款回执单生成器, 银行转账p图【仅供娱乐学习用途】
这是一套基于Java的银行交易记录模拟教学系统,包含BankSimulator和Main两个核心类。BankSimulator类通过Transaction静态嵌套类实现交易记录。
|
10月前
|
自然语言处理 搜索推荐 小程序
博物馆导览系统:提升观众参观效率与满意度
在这个快节奏时代,博物馆面临挑战与机遇。传统导览方式难以满足个性化、互动性和沉浸式学习需求。本文深入解析博物馆智能导览系统,包括精准定位导航、展品解说和AR技术应用,提升观众参观效率与满意度。
402 5
|
10月前
|
人工智能 数据可视化 数据处理
告别编码难题,低代码平台让应用开发更简单!#高效开发
低代码平台通过创新技术和智能化工具,提供高效、低成本的应用开发模式,大幅降低开发门槛。平台支持可视化开发、高效数据处理、模型驱动开发、AI智能辅助及丰富的插件生态,帮助企业快速实现复杂业务逻辑,加速数字化转型。
|
12月前
|
SQL 关系型数据库 MySQL
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
MySQL中用于数据检索的`fetchone()`, `fetchmany()`, `fetchall()`函数的功能、SQL语句示例和应用场景。
303 3
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
|
机器学习/深度学习 存储 PyTorch
【深度学习】Pytorch面试题:什么是 PyTorch?PyTorch 的基本要素是什么?Conv1d、Conv2d 和 Conv3d 有什么区别?
关于PyTorch面试题的总结,包括PyTorch的定义、基本要素、张量概念、抽象级别、张量与矩阵的区别、不同损失函数的作用以及Conv1d、Conv2d和Conv3d的区别和反向传播的解释。
930 2
梯度下降算法(二)
梯度下降法中,学习率选择至关重要。0.3的学习率导致无法找到最小值且产生震荡,而0.01则使结果接近最优解(2.99998768)。当学习率进一步减小至0.001,点远离最低点。通过迭代次数增加至1000次,可更接近最低点(2.999999999256501)。梯度下降用于最小化损失,学习率控制参数更新步长,需平衡收敛速度和稳定性。迭代次数和初始点也影响模型性能,合适的初始化能加速收敛并避开局部极小值。
|
存储 SQL 关系型数据库
MySQL存储过程和存储函数的使用
MySQL的存储过程和存储函数在功能和用法上有明显的区别。存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,通过指定名称和参数(如果有)来调用执行,可以返回多个值或结果集,但不直接返回值。而存储函数则是一个有返回值的特殊存储过程,它返回一个值或表对象,可以直接嵌入SQL语句中使用,如SELECT语句中。两者都是为了提高SQL代码的重用性和性能,但使用场景和方式有所不同。
4442 4