什么是随机梯度下降?

什么是随机梯度下降?

随机梯度下降 (SGD) 是一种优化算法,通常用于提高机器学习模型的性能。它是传统梯度下降算法的变体,但有一个关键的修改:SGD 不是依赖整个数据集来计算每个步骤的梯度,而是一次使用一个数据样本。

梯度下降

梯度下降 (GD) 是一种以迭代方式最小化目标函数的优化算法。在机器学习 (ML) 的背景下,梯度下降对于提高机器学习模型在训练阶段的性能至关重要。机器学习模型,如神经网络,是复杂的、非线性的和高维的。因此,与线性回归不同,此类模型没有可以计算最佳权重的正态方程。取而代之的是梯度下降法、牛顿法和期望最大化法等近似方法。

每个模型都有一个损失函数,有时也称为成本函数。该函数用于测量模型的预测值与真实数据点之间的距离。将其视为衡量模型预测“错误”程度的标准。例如,均方误差通常用作回归问题中的损失函数。模型训练阶段旨在找到使这种损失最小化的参数值。因此,梯度下降通常是训练中使用的优化技术。该算法计算损失相对于模型参数的梯度或斜率。有了这个梯度,它就会向相反的方向迈出一步,以减少损失。学习率(也称为步长或 alpha)是步长的大小,并且对于所有 模型参数保持固定。这一过程不断重复,直到模型收敛到最小值附近。

收敛图示 收敛图示

收敛最好发生在全局最小值处。从下面的直观图中可以看出,局部最小值处的损失值低于其周边地区,但不一定是整体最低值。全局最小值是损失函数在整个域内的绝对最低值,代表问题的最佳解决方案。

三维空间中的局部最小值和全局最小值 三维空间中的局部最小值和全局最小值

如果学习率不够小,算法通常会收敛在局部最小值。要使损失函数最小化,并收敛到全局最小值,选择合理的学习率至关重要。

学习率对收敛的影响 学习率对收敛的影响

这种可视化方式描述了学习率对收敛的影响。较小的学习率会导致缓慢但稳定的收敛(左),而较大的学习率可能会导致过冲和不稳定(右)。

从 GD 到 SGD

传统梯度下降和随机梯度下降之间的主要区别在于,SGD 一次使用一个训练样本来更新模型权重。每次迭代都会随机选择一个样本。1 梯度下降法在每次参数更新之前都会使用整个训练数据集来计算梯度。这种数据使用差异使得 SGD 的计算成本要低得多,并且更容易扩展到大型数据集。另一方面,SGD 的收敛行为比 GD 的噪声更大,因为单个示例数据点可能无法很好地代表数据集。这种错误的代表行为将要点更新到了一个略微“错误”的方向。然而,这种随机性使 SGD 更快,有时更适合非凸优化问题,因为它可以逃避浅的局部最小值或鞍点。

严格来说,SGD 最初的定义是通过每次只能使用一个训练样本来更新参数。在现代用法中,术语“SGD”广泛用于表示“小批次梯度下降”,这是 GD 的一种变体,一次使用小批次训练数据。与单一样本相比,使用数据子集而不是单一样本的主要优势是噪声水平较低,因为梯度等于小批次损失的平均值。因此,小批次梯度下降是深度学习的默认设置。相反,严格的 SGD 在实践中很少使用。大多数机器学习库(如 PyTorch 和 TensorFlow)甚至将这些术语混为一谈;优化器通常被称为“SGD”,尽管它们通常使用小批次。

下图更清晰地说明了增加训练数据的样本量如何减少波动和“噪声”。

梯度下降法的变体

GD 还有其他几种变体,它们建立在基本梯度下降的基础上,增加了提高速度、稳定性和收敛性的机制。

基于动量的方法:

通过在具有一致梯度的维度中积累动量,并在具有变化梯度的维度中抑制更新,动量有助于 SGD 更快地收敛,并减少波动。2

有无动量的 SGD
  • 动量梯度下降法:包含一个“速度”项,这是以前梯度的平均值,对最近的梯度更加重要。这种方法可以减少锯齿状波动或振荡,帮助算法更快地朝着正确的方向移动。

  • NAG(涅斯捷罗夫加速梯度法):一种改进的动量方法,在计算梯度之前“预测”参数的发展方向,从而加速收敛并使收敛顺畅。换句话说,它预测未来的梯度,并利用这一信息为当前的更新步骤提供信息。3

自适应学习率方法:

自适应学习率方法(例如 AdaGrad 和 RMSProp)的独特之处在于,它们会单独调整每个参数的学习率。这种方法与 SGD 方法形成鲜明对比,SGD 方法对所有参数都使用固定的学习率。

  • AdaGrad(自适应梯度算法):根据每个参数之前的梯度调整其学习率。出现频率较低的功能的学习率较高,而频繁出现的功能的学习率较低。这种方法意味着,与使用 SGD 相比,学习不常用功能的速度更快。这种自适应学习率意味着它非常适合处理功能频率差异较大的稀疏数据,例如自然语言处理 (NLP) 和推荐系统。2
     

  • RMSProp(均方根传播):另一种自适应学习率优化技术,通过使用最近梯度平方的移动平均值来调整每个参数的学习率。过去的梯度信息被丢弃,只保留当前的梯度信息。4对于梯度较小的参数,学习率会变大,而对于梯度较大的参数,学习率会变小。这种方法消除了 AdaGrad 的学习率递减问题。RMSProp 有助于保持深度学习训练的稳定性,尤其适用于神经网络 (RNN) 等模型,并且在目标不断变化的问题上效果很好,例如强化学习

混合方法:

  • Adam(自适应力矩估算):通过跟踪过去的梯度和平方梯度的平均值,将基于动量的 GD 与 RMSProp 相结合。这种组合即使对于噪声较大且数据稀疏的数据集也能实现快速收敛。 3此外,许多框架的默认超参数(例如学习率为 0.001)都能立即发挥良好作用。然而,对于超大规模数据集,带动量的 SGD 可以实现更好的泛化效果。Adam 算法对每个参数的激进调整可能会导致训练数据过拟合,或者陷入泛化能力较差的尖锐最小值。

当训练时间成为瓶颈时,SGD 和其他 GD 变体就会派上用场。5

变体每个步骤使用的数据主要功能常用
GD所有数据稳定但缓慢小型数据集
新加坡元1 个经典 SGD 样本嘈杂但快速在线学习
小批次 GD少量样本平衡且可扩展深度学习
Momentum批次/小批次朝正确的方向加速神经网络
NAG批次/小批次Look-ahead 动量更快的收敛速度
AdaGrad小批次自适应学习率稀疏数据
RMSProp小批次修复 AdaGrad 衰减RNN、深度网络
Adam小批次动量 + RMSProp今天的默认选择

理解数学原理

SGD 的目标是找到参数θ使我们的模型预测尽可能接近真实值y。换句话说,我们想要最小化损失函数。L(θ) .

对于线性回归,这些参数是w(权重)和b(偏见)。因此,在这种情况下,尽量减少L(θ)就等同于最小化L(w,b) .

 yi^=w·xi+b

L(w,b)=1ni=1n(yi-yi^)2

在教授梯度下降时常用的一个类比是,GD 就像在山上走下坡,直到到达山谷(最小损失)。想象一下损失函数的梯度, L,指向上坡;要下坡,我们必须朝相反的方向迈进。

参数的一般更新规则θ  是:

θ:=θ-η·θL(θ)

其中 η 是学习率和 θL(θ) 是损失函数关于 的梯度θ .

SGD 仅使用一个随机选择的样本 (xi,yi) 来近似梯度:

θL(θ)θ(xi,yi;θ)

注意,小写 (xi,yi;θ) 表示丢失一个训练样本。而大写字母 L(θ) 是总体损失函数(数据集中的所有单个损失的平均值)。这种全局性误差正是我们在训练中要尽量减少的。

示例:使用 SGD 进行线性回归

让我们完成使用 SGD 进行线性回归的示例。

对于样本 (xi,yi) ,预测为:

 yi^=w·xi+b

局部损失是单个样本的平方误差:

 (xi,yi;w,b)=(yi-(wxi+b))2

现在,在反向传播算法过程中,利用链式规则更新模型参数,计算损失函数与每个参数相关的梯度。5 梯度(导数)为:

 w=-2xi(yi-(wxi+b))

 b=-2(yi-(wxi+b))

通过 SGD,我们可以更新这些参数,w以及b ,使用以下规则:

 w:=w-η·(-2xi(yi-(wxi+b)))

 b:=b-η·(-2(yi-(wxi+b)))

SGD 不是计算整个数据集的重平均梯度,而是使用轻量级随机估计。

SGD 的简单 Python 实施

在使用机器学习框架时,可以使用内置的 SGD 优化器类。例如:torch.optim.SGD  for PyTorchtf.keras.optimizers.SGD  for Keras(TensorFlow 内置)以及 SGDRegressor  for Scikit-learn

为了学习的目的,让我们从头开始,逐步实施一个简单的 Python 随机梯度下降算法。

重申一下,我们的目标是找到最佳参数(模型权重),使损失函数(衡量我们预测错误程度的指标)最小。我们将一次更新一个样本,或更新非常小的批次。

首先,我们可以随机初始化参数值(权重)。接下来,我们可以随机选择一个数据点 (x,y) 。然后,我们计算预测值和误差。对于这个简单的演示,让我们尝试拟合一条简单的线: y=mx+b 。该过程的下一步是反向传播,即计算损失函数与参数相关的梯度。这些梯度(导数)随后用于在 SGD 优化过程中更新参数。由于梯度指向损失函数增加的方向,因此 SGD 会从每个梯度的当前参数值中减去该梯度。我们可以将其视为沿梯度的相反方向移动,以减小损失函数。因此,“随机梯度下降”中的“下降”就是这个意思。我们重复这些步骤,直到一个固定的历时次数或损失小于容差为止。后者意味着损失几乎没有变化,我们便不再改进目标函数。换句话说,一旦算法收敛,我们就会停止。

import numpy as np 
 
def stochastic_gradient_descent(X, y, lr=0.01, epochs=100, tol=1e-6): 
    “”” 
    Perform Stochastic Gradient Descent (SGD) to fit a line y = w*x + b 
     
    Parameters: 
        X (ndarray): Input features 
        y (ndarray): Target values 
        lr (float): Learning rate (step size for updates) 
        epochs (int): Number of iterations through the dataset 
     
    Returns: 
        w (float): Learned weight 
        b (float): Learned bias 
    “”” 
    # Initialize parameters randomly 
    w = np.random.randn() 
    b = np.random.randn() 
     
    n = len(X) 
 
    prev_loss = float(‘inf’) 
     
    for epoch in range(epochs): 
        # Shuffle the data for each epoch 
        indices = np.arange(n) 
        np.random.shuffle(indices) 
         
        for i in indices: 
            xi = X[i] 
            yi = y[i] 
             
            # Prediction 
            y_pred = w * xi + b 
             
            # Compute gradients (derivatives) 
            dw = -2 * xi * (yi - y_pred)   # derivative wrt w 
            db = -2 * (yi - y_pred)        # derivative wrt b 
             
            # Update parameters 
            w -= lr * dw 
            b -= lr * db 
         
        
        # Compute loss at the end of the epoch 
        loss = np.mean((y - (w*X + b))**2) 
         
        # Check stopping condition 
        if abs(prev_loss - loss) < tol: 
            print(f”Stopped early at epoch {epoch+1}”) 
            break 
                 
        prev_loss = loss 
             
    return w, b

SGD 的应用

SGD 是训练深度神经网络的最常见优化方法。在深度学习中,作为数据科学领域内机器学习的一个子集,其目标是让计算机模拟人类大脑的复杂决策能力。传统 ML 模型使用由一层或两层组成的简单神经网络。而深度学习模型则使用三层或更多层。通常需要数百或数千个层来训练模型。鉴于 SGD 易于扩展到大型训练集,它通常是训练神经网络的首选方法。SGD 训练的其他应用程序包括岭回归、正则化逻辑回归,以及优化线性核支持向量机 (SVM) 中使用的铰链损失函数。

总结

SGD 是 GD 的一种变体,通过一次使用一个数据样本来最大限度地减少机器学习模型的损失函数。这种方法与 GD 不同,GD 依赖于每个步骤的整个数据集来计算梯度。还有其他几种 GD 变体,可以归类为基于动量的学习方法或自适应学习方法。动量梯度下降和涅斯捷罗夫加速梯度就是前者示例。这些方法充分利用梯度一致的维度中积累的动量,并抑制梯度变化的维度中的更新。因此,有助于 SGD 更快地收敛,减少振荡。自适应学习率方法(例如 AdaGrad 和 RMSProp)会单独调整每个参数的学习率,而传统的 SGD 会使用固定的学习率。此外,Adam 等混合方法通过结合基于动量的 GD 和 RMSProp 的优势,提供了强大的替代方案。

相关解决方案
IBM watsonx.ai

使用面向 AI 构建器的新一代企业级开发平台 IBM watsonx.ai,可以训练、验证、调整和部署生成式 AI、基础模型和机器学习功能。使用一小部分数据,即可在很短的时间内构建 AI 应用程序。

了解 watsonx.ai
人工智能 (AI) 解决方案

借助 IBM 业界领先的人工智能专业知识和解决方案组合,让人工智能在您的业务中发挥作用。

深入了解 AI 解决方案
AI 咨询与服务

通过增加 AI 重塑关键工作流程和运营,最大限度提升体验、实时决策和商业价值。

深入了解人工智能服务
采取后续步骤

一站式访问跨越 AI 开发生命周期的功能。利用用户友好型界面、工作流并访问行业标准 API 和 SDK,生成功能强大的 AI 解决方案。

深入了解 watsonx.ai 预约实时演示
脚注

Bottou, L. (2010). Large-Scale Machine Learning with Stochastic Gradient DescentLechevallier, Y., Saporta, G. (eds) Proceedings of COMPSTAT’2010. Physica-Verlag HD. 

Ruder, S. (2016). An overview of gradient descent optimization algorithms

Tian, Y., Zhang, Y., & Zhang, H. (2023). Recent Advances in Stochastic Gradient Descent in Deep LearningMathematics, 11(3), 682. 

Haji, S. H., & Abdulazeez, A. M. (2021). Comparison of optimization techniques based on gradient descent algorithm: A review. PalArch’s Journal of Archaeology of Egypt/Egyptology, 18(4), 2715-2743.

Bottou, L. (2012). Stochastic Gradient Descent TricksMontavon, G., Orr, G.B., Müller, KR. (eds) Neural Networks: Tricks of the Trade. Lecture Notes in Computer Science, vol 7700. Springer, Berlin, Heidelberg.