如何从零开始实现梯度下降优化?

2024年8月28日 | 阅读 8 分钟

梯度下降是一种广泛应用于机器学习和深度学习中的基本优化规则。理解梯度下降的工作原理,能够从基础知识和技术知识出发使用它,对于任何数据科学家或技术爱好者来说都很重要。在本教程中,我们将详细介绍梯度下降,并逐步手动实现 Python 的完整版本。

什么是梯度下降?

梯度下降是一种迭代优化算法,通过在由梯度负方向定义的陡峭下降方向上进行迭代移动来减小一个特征。它是一种一阶优化算法,通常用于机器学习中,用于减小损失函数,并继续探索模型最优参数,获得深入的知识。

它的工作原理如下

目标函数:梯度下降从一个需要最小化的定义好的目标函数开始。在机器学习的上下文中,这个函数将是一个成本函数,代表模型预测值与训练数据中的实际值之间的差异。

梯度计算:算法计算目标函数相对于模型参数的梯度。梯度是一个指向函数最陡峭上升方向的向量。换句话说,它表明了函数在参数空间每个维度上如何增加或减小。

参数更新:通过在梯度相反方向上采取步长来迭代更新模型参数。通过在与梯度相反的方向上移动,算法旨在最小化目标函数。每一步的步长由一个称为学习率的参数决定。

学习率:学习率控制梯度下降每次迭代过程中在参数空间中采取的步长大小。较小的学习率会导致收敛速度较慢,但有助于避免“过冲”最小值;而较大的学习率会加速收敛,但可能导致振荡或发散。

收敛:梯度下降会继续更新参数,直到满足停止条件。这可能是最大迭代次数、梯度幅度的阈值,或者达到所需的精度水平。

梯度下降有多种变体,包括批量梯度下降、随机梯度下降和小型批量梯度下降,每种变体都有其自身的特点和权衡。尽管梯度下降很简单,但它是一种强大的优化算法,广泛用于各种机器学习算法中,例如线性回归、逻辑回归、神经网络等。

梯度下降的基本步骤

1. 设定目标

在优化过程开始时,您有一个需要最小化的目标函数。这个函数可能代表您的模型预测与实际数据之间的误差或损失。例如,在线性回归中,目标函数可能是均方误差,它衡量预测值与实际值之间的平均平方差。

2. 计算梯度

目标函数的梯度表示函数相对于模型每个参数的变化率。它告诉你当您对参数进行微小更改时,目标函数会发生多大的变化以及变化的方向。从数学上讲,梯度是一个由目标函数相对于每个参数的偏导数组成的向量。

3. 更新参数

一旦您有了梯度,您就在梯度的相反方向上调整模型的参数。通过在梯度相反的方向上移动,您旨在减小目标函数的成本。调整的大小由学习率决定,学习率控制着参数空间中的步长。更大的学习率会导致更大的步长,可能导致更快的收敛,但有“过冲”最小值的风险。较小的学习率可能会收敛得更慢,但更稳定。

4. 选择步长

学习率是一个在优化过程开始前需要选择的超参数。它决定了在梯度下降的每次新迭代中,您在参数空间中采取的步长大小。选择合适的学习率对于优化过程的收敛性和稳定性至关重要。

5. 迭代直至收敛

梯度下降是一种迭代算法,这意味着您重复步骤 2 和 3,直到满足停止条件。这个停止条件可以是达到最大迭代次数,达到所需的精度水平,或者当目标函数的改进变得微乎其微时。算法会持续调整参数,直到收敛到一个点,在该点上进一步的更改不会显著改进目标函数。

在 Python 中实现梯度下降

此函数使用梯度下降来优化简单线性回归模型的参数。以下是函数使用情况的细分:

  1. gradient_descent 函数:此函数接收特征矩阵 X、目标向量 y、初始参数 theta、学习率和迭代次数作为输入。它迭代更新参数,直到收敛为止,使用梯度下降。
  2. 生成随机数据:在演示任务中,我们生成一些随机数据 X 和 y。
  3. 添加截距项:我们在特征矩阵 X 中添加一列来估计线性回归模型中的截距项。
  4. 初始化参数:我们随机初始化参数 theta。
  5. 设置超参数:我们为梯度下降算法设置学习率和迭代次数。
  6. 运行梯度下降:我们使用给定的数据和超参数调用 gradient_descent 函数来优化参数 theta。
  7. 打印最优参数:最后,我们打印运行梯度下降后找到的最优参数。
  8. 此实现基本上是一个模型,可以扩展和改编以用于不同的优化任务和机器学习模型。

    此函数使用梯度下降来优化简单线性回归模型的参数。以下是函数使用情况的细分:

    gradient_descent 函数:此函数接收特征矩阵 X、目标向量 y、初始参数 theta、学习率和迭代次数作为输入。它迭代更新参数,直到收敛为止,使用梯度下降。

    生成随机数据:在演示任务中,我们生成一些随机数据 X 和 y。

    添加截距项:我们在特征矩阵 X 中添加一列来估计截距项。

    导入必要的库

    我们引入 NumPy 库,该库提供了算术运算的支持,尤其是在处理数组和矩阵时。

    定义梯度下降函数

    这个 gradient_descent 函数接收特征矩阵 X、目标向量 y、初始参数 theta、学习率和迭代次数作为输入。它迭代更新参数,直到收敛为止,使用梯度下降。

    生成随机数据进行演示

    我们出于演示目的生成随机数据。X 代表特征,y 代表目标值。

    添加截距项

    为了估计线性回归模型中的截距项,我们在特征矩阵 X 中添加一列。

    初始化参数

    我们随机初始化参数 theta。在此情况下,我们使用随机值初始化一个 2x1 的数组。

    设置超参数

    我们为梯度下降算法设置超参数。步长决定了每次迭代的步长大小,迭代次数决定了我们更新参数的频率。

    运行梯度下降

    我们使用给定的数据和超参数调用 gradient_descent 函数来微调参数 theta。

    打印最优参数

    最后,我们打印运行梯度下降后获得的最优参数。

    这是完整的代码

    特征缩放

    将特征缩放到相似的范围可以帮助梯度下降更快地收敛。常用的策略包括标准化(减去均值并除以标准差)或归一化(将特征缩放到 0 到 1 之间的范围)。

    正则化

    可以使用 L1(Lasso)和 L2(Ridge)正则化等正则化策略来防止过拟合,方法是惩罚较大的参数值,将其集成到梯度下降中。

    小型批量梯度下降

    小型批量梯度下降使用训练数据的一个子集(一个小型批量)而不是整个数据集来计算梯度。这可以导致更快的收敛和更好的泛化能力,特别是对于大型数据集。

    随机梯度下降 (SGD)

    SGD 一次只使用一个训练样本来更新参数。它在参数更新中引入了随机性,这可以帮助跳出局部最小值,但也可能导致收敛不稳定。

    动量

    动量是一种通过将前一个更新向量的一部分添加到当前更新中来加速梯度下降的技术。它有助于克服局部最小值,并在具有一致梯度的方向上加速收敛。

    学习率调度

    学习率调度不使用固定的学习率,而是会调整训练过程中的学习率。常用的策略包括随时间减小学习率,或根据特定条件进行调整。

    收敛准则

    确定何时停止梯度下降的迭代至关重要。收敛准则可以包括达到最大迭代次数、达到所需的精度水平,或者当目标函数的改进变得微乎其微时。

    优化算法

    除了简单的梯度下降之外,还有许多优化算法旨在改进其局限性。这些算法包括 AdaGrad、RMSprop、Adam 等,它们会根据过去的梯度自适应地调整学习率或更新方向。


    下一主题解释相关系数