[机器学习] Gradient descent (Adagrad 、 SGD)

前言

  这篇文章是李宏毅的《机器学习》课程的笔记,主要目的是让我自己梳理一遍课程的内容,加深理解,找到课上没弄懂的地方,并将新的知识点与我以前的一些认知结合起来。如有写错的地方或者理解有问题的地方希望能得到纠正,欢迎一起探讨相关的问题。

正文

  回顾在前面线性回归处使用的梯度下降来寻找损失函数 J J J (或记为 L L L) 最小时的参数 θ \boldsymbol\theta θ ,我们的目标函数是:
θ ∗ = arg ⁡ min ⁡ θ J ( θ ) \boldsymbol \theta^*=\arg \min_{\boldsymbol \theta} J(\boldsymbol \theta) θ=argθminJ(θ)
  其中, θ ∗ \boldsymbol \theta^* θ 是最优条件下的参数 θ \boldsymbol \theta θ 值。

  梯度下降的方法的过程就是随机选取一个起始点 θ 0 = [ θ 1 0 θ 2 0 ] \boldsymbol \theta^{0}= \begin{bmatrix} \theta^0_1 \\ \theta^0_2\end{bmatrix} θ0=[θ10θ20] ,然后计算在这一点的梯度向量 ∇ J ( θ 0 ) = [ ∂ J ( θ 1 0 ) / ∂ θ 1 ∂ J ( θ 2 0 ) / ∂ θ 2 ] \nabla J(\boldsymbol \theta^0) = \begin{bmatrix} \partial J(\boldsymbol \theta^0_1) / \partial \theta_1 \\ \partial J(\boldsymbol \theta^0_2) / \partial \theta_2 \end{bmatrix} J(θ0)=[J(θ10)/θ1J(θ20)/θ2] ,并设定一个学习率参数 η \eta η ,然后更新参数 θ \boldsymbol \theta θ 得到一个新的 θ 1 \boldsymbol \theta^1 θ1
θ 1 = θ 0 − η ∇ J ( θ 0 ) \boldsymbol \theta^1 = \boldsymbol \theta^0 - \eta \nabla J(\boldsymbol \theta^0) θ1=θ0ηJ(θ0)
  然后不断重复这个过程,直到找到 J J J 最小的点。上面这个是 θ \boldsymbol \theta θ 只有两个参数的情况,也就是二维的情况,如果把 J J J θ \boldsymbol \theta θ 的关系图以等高线的形式画在图上,那么梯度的方向向量其实就是那一点等高线的垂线方向。梯度下降就是不断重复找当前所在位置的等高线的梯度方向,然后往其反方向走一步的过程,过程如图所示,红线是梯度方向,蓝线是移动方向,图中 L L L 就是上面的 J J J 表示损失函数。(PS: 学习率在李宏毅的课程中是记为 η \eta η 的,而在吴恩达 Coursera 上是记为 $\alpha $ ,我是先看的吴恩达的课,所以习惯用 α \alpha α ,不过貌似好像 η \eta η 作为学习率更常用,所以以后都写成 η \eta η)

Learning rate

学习率的设置

  在上面所说的梯度下降的方法中,学习率是一个不变的常数,那么如何来设置这个参数其实是一个很重要的问题,因为如果设的太大的话,可能因为每次更新参数的幅度太大了而无法收敛到最低点(下图绿线),甚至变得发散了(下图黄线)。如果设的太小的话可能收敛的速度会很慢(下图蓝线)。

  上面这个图是在参数为一维的情况下才能画出来的,如果参数大于等于三维,其实是没有办法可视化画出 θ \boldsymbol \theta θ J J J 之间的关系图的,所以也就没法从图中观察到我的学习率时候设置的太小了或者太大了。但是我们可以画出每次迭代时的当前 J J J 的图,如下图所示,可以看到当学习率过大而损失值发散的时候会像黄线那样,当太小的时候会像蓝线那样。所以画迭代次数与损失值的关系图可以帮我们了解到我们的学习率 η \eta η 是否合适。

自适应学习率 (Adaptive learning rates)

  上面所说的学习率是不变的,那么我们想让我们的学习率能够自适应迭代的过程要怎么办呢?一个大的原则是希望随着参数的不断更新,学习率会变的越来越小,以便更好的收敛。那么很容易可以想到可以让学习率随着迭代的次数而衰变,例如第 t t t 次迭代时的学习率 η t \eta^t ηt 为:
η t = η t + 1 \eta^t = \frac \eta {\sqrt{t+1}} ηt=t+1 η
  使用上面这种学习率自适应方法的梯度下降叫做 vanilla gradient descent,至此为止,学习率对于每一个参数 { θ 1 , θ 2 , . . . , θ n } \{\theta_1, \theta_2 ,...,\theta_n\} { θ1,θ2,...,θn}都是一样的,但是应该为不同的参数设定不同的学习率。所以有另一种学习率自适应的算法,叫做 Adagrad

Adagrad

  Adagrad 每次的学习率不是只关于迭代次数 t t t 来衰减,还与这 t t t 次迭代时每次的微分有关。记任意一个参数为 w w w ,改参数第 t t t 次的微分为 g t g^t gt 。则 使用 Adagrad 进行梯度下降的参数更新方法如下:
w t + 1 ← w t − η t σ t g t w^{t+1} \leftarrow w^t - \frac {\eta^t} {\sigma^t} g^t wt+1wtσtηtgt
  其中 η t = η t + 1 \eta^t = \frac \eta {\sqrt{t+1}} ηt=t+<

### 随机梯度下降(Stochastic Gradient Descent, SGD)概述 随机梯度下降是一种常用的优化算法,在机器学习和深度学习领域广泛应用。它通过每次迭代仅使用单一样本或一小批样本来更新模型参数,从而显著减少计算开销并提高训练效率[^4]。 #### 基本原理 SGD的核心思想是在每一次迭代过程中,利用单一数据样本的梯度方向来调整模型权重。这种方法相比传统的批量梯度下降(Batch Gradient Descent),能够更快地收敛于局部最优解,尤其是在处理大规模数据集时表现尤为突出[^3]。 #### 实现细节 在实际应用中,Torch框架提供了 `optim.sgd` 方法作为实现随机梯度下降的标准工具之一。该方法允许用户自定义超参数,例如学习率、动量项以及权重衰减系数等,这些设置对于提升模型性能至关重要[^2]。 #### 场景分析 由于其高效性和灵活性,SGD被广泛应用于多种场景下: - **大规模数据集训练**:当面对海量数据时,传统批量梯度下降可能因内存占用过高而无法运行;此时采用SGD可以有效缓解这一问题[^5]。 - **在线学习环境**:在实时流式数据分析任务中,新数据不断涌入系统,要求模型快速适应变化趋势而不需重新加载全部历史记录——这正是SGD擅长之处[^1]。 以下是基于PyTorch的一个简单SGD实现案例: ```python import torch from torch import nn, optim # 定义简单的线性回归模型 model = nn.Linear(in_features=10, out_features=1) # 创建损失函数与优化器 criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.01) # 模拟输入输出数据 inputs = torch.randn(100, 10) targets = torch.randn(100, 1) for epoch in range(10): # 进行多次epoch循环 total_loss = 0 for i in range(len(inputs)): input_data = inputs[i].unsqueeze(0) # 获取单个样本 target_data = targets[i].unsqueeze(0) optimizer.zero_grad() # 清除之前的梯度 output = model(input_data) # 计算预测值 loss = criterion(output, target_data) # 计算当前样本上的误差 loss.backward() # 反向传播求导数 optimizer.step() # 更新参数 total_loss += loss.item() print(f'Epoch {epoch}, Loss: {total_loss / len(inputs)}') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值