梯度下降优化-AadGrad自适应梯度
1. 问题引入
在优化复杂的损失函数时,普通的梯度下降法和动量法会遇到以下问题:
- 固定学习率问题:所有参数使用相同的学习率,但不同参数可能需要不同的更新速度
- 稀疏梯度问题:某些参数很少更新(梯度稀疏),需要更大的学习率
- 频繁更新问题:某些参数频繁更新(梯度大),需要更小的学习率以避免震荡
- 学习率衰减问题:随着训练进行,需要逐渐减小学习率,但手动调整困难
AdaGrad(Adaptive Gradient) 通过为每个参数自适应地调整学习率,能够有效解决这些问题。
正如 AdaGrad 优化方法的名称 "自适应梯度",该优化方法的思路是根据梯度动态的调整学习率。
梯度较大时学习率变小,参数更新的步长减小。可以理解为下山时在坡度较陡的路段,我们脚步移动的距离会减小速度会放缓。
梯度较大时学习率增大,参数更新的步长增大。可以理解为在坡度没那大的平缓地段坡,我们可以放心的迈大步子往前走速度会提高。
2. 理解 AdaGrad
2.1 生活中的类比
想象你在一个多山的地形中寻找最低点:
普通梯度下降(固定学习率):
- 无论你在陡坡还是缓坡,都使用相同的步长
- 在陡坡上可能走得太快,容易越过最低点
- 在缓坡上可能走得太慢,收敛速度慢
AdaGrad(自适应学习率):
- 记录你在每个方向上走过的总距离
- 在陡坡方向(梯度大),你已经走了很多步,自动减小步长,避免震荡
- 在缓坡方向(梯度小),你走得少,保持较大的步长,加速收敛
- 就像"经验"告诉你:某个方向已经探索很多了,应该小心;某个方向探索少,可以大胆前进
2.2 具体例子:神经网络训练
假设我们在训练一个神经网络,有两个参数 $w_1$ 和 $w_2$:
场景1:稀疏梯度问题
- 参数 $w_1$(对应输入特征1):梯度很少出现,但一旦出现就很大
- 参数 $w_2$(对应输入特征2):梯度频繁出现,但每次都很小
普通梯度下降的问题:
- 如果学习率设置得适合 $w_2$,那么 $w_1$ 更新太慢
- 如果学习率设置得适合 $w_1$,那么 $w_2$ 更新太快,容易震荡
AdaGrad 的解决方案:
- $w_1$:梯度稀疏但大,累积梯度平方和增长慢,学习率衰减慢,保持较大学习率
- $w_2$:梯度频繁但小,累积梯度平方和增长快,学习率衰减快,自动减小学习率
2.3 数学直觉
核心思想:
- 为每个参数维护一个累积梯度平方和
- 梯度大的参数,累积平方和大,学习率自动减小
- 梯度小的参数,累积平方和小,学习率保持较大
- 随着训练进行,所有参数的学习率都会逐渐减小(自动学习率衰减)
2.4 直观理解
下面通过一个直观的可视化图来理解 AdaGrad 的核心思想:梯度大时步长减小,梯度小时步长增大。
我们使用一个简单函数 $f(x) = x^2 + 0.1\sin(10x)$ 这个函数有陡坡和缓坡区域,适合展示自适应学习率的效果。
这个示意图展示了:
- 在梯度大的区域(陡坡),AdaGrad 自动减小学习率,步长变小,避免震荡
- 在梯度小的区域(缓坡),AdaGrad 保持较大学习率,步长变大,加速收敛
- 每个参数都有自己的学习率,实现自适应优化

关键观察:
-
在梯度大的区域(陡坡):
- 梯度大 → 累积平方和增长快 → 学习率小
- 步长 = 小学习率 × 大梯度 = 中等步长(避免震荡)
-
在梯度小的区域(缓坡):
- 梯度小 → 累积平方和增长慢 → 学习率大
- 步长 = 大学习率 × 小梯度 = 较大步长(加速收敛)
-
这就是 AdaGrad 的自适应机制:
- 自动平衡不同梯度区域的更新速度
- 梯度大的地方小心走(步长小)
- 梯度小的地方大胆走(步长大)
3. 普通梯度下降法和动量法回顾
3.1 标准梯度下降更新公式
对于损失函数 $L(\theta)$,标准梯度下降的更新公式为:
$$\theta_{t+1} = \theta_t - \alpha \cdot \nabla_\theta L(\theta_t)$$
问题:所有参数使用相同的学习率 $\alpha$
3.2 Momentum(动量法)更新公式
$$v_t = \beta \cdot v_{t-1} + \nabla_\theta L(\theta_t)$$
$$\theta_{t+1} = \theta_t - \alpha \cdot v_t$$
问题:虽然引入了动量,但所有参数仍使用相同的学习率 $\alpha$
3.3 为什么需要自适应学习率?
考虑一个简单的例子:
$$L(x, y) = 100x^2 + y^2$$
梯度:
$$\frac{\partial L}{\partial x} = 200x$$
$$\frac{\partial L}{\partial y} = 2y$$
问题分析:
- $x$ 方向的梯度是 $y$ 方向的 100 倍
- 如果使用相同的学习率,$x$ 方向更新太快,$y$ 方向更新太慢
- 理想情况:$x$ 方向使用较小的学习率,$y$ 方向使用较大的学习率
AdaGrad 的解决方案:
- 自动为 $x$ 方向分配较小的学习率(因为梯度大)
- 自动为 $y$ 方向分配较大的学习率(因为梯度小)
4. AdaGrad 的数学推导
4.1 AdaGrad 的核心思想
AdaGrad 通过为每个参数维护一个累积梯度平方和,来自适应地调整学习率。
核心思路:
- 记录每个参数的历史梯度平方和
- 梯度大的参数,累积平方和大,学习率自动减小
- 梯度小的参数,累积平方和小,学习率保持较大
- 随着训练进行,学习率自动衰减
4.2 AdaGrad 的更新公式
AdaGrad 的更新公式:
$$G_t = G_{t-1} + \nabla_\theta L(\theta_t) \odot \nabla_\theta L(\theta_t)$$
$$\theta_{t+1} = \theta_t - \frac{\alpha}{\sqrt{G_t + \epsilon}} \odot \nabla_\theta L(\theta_t)$$
公式详细说明:
第一步:累积梯度平方和 $G_t$
- $G_t$:第 $t$ 步的累积梯度平方和(向量,与参数 $\theta$ 同维度)
- $G_{t-1}$:第 $t-1$ 步的累积梯度平方和(历史累积)
- $\nabla_\theta L(\theta_t)$:当前梯度(向量)
- $\odot$:逐元素相乘(Hadamard 积)
- $\nabla_\theta L(\theta_t) \odot \nabla_\theta L(\theta_t)$:梯度的逐元素平方
- 物理意义:$G_t$ 记录了每个参数方向上历史梯度的平方和
第二步:参数更新
- $\theta_{t+1}$:更新后的参数
- $\theta_t$:当前参数
- $\alpha$:初始学习率(全局学习率)
- $\sqrt{G_t + \epsilon}$:自适应学习率分母(向量)
- $\sqrt{\cdot}$:逐元素开平方
- $\epsilon$:小常数(通常取 $10^{-8}$),防止分母为0
- $\frac{\alpha}{\sqrt{G_t + \epsilon}}$:自适应学习率(向量,每个参数有自己的学习率)
- $\odot$:逐元素相乘,每个参数使用自己的学习率
关键洞察:
- 每个参数 $\theta_i$ 有自己的学习率 $\frac{\alpha}{\sqrt{G_{t,i} + \epsilon}}$
- 梯度大的参数,$G_{t,i}$ 大,学习率小
- 梯度小的参数,$G_{t,i}$ 小,学习率大
- 随着训练进行,$G_t$ 单调递增,学习率单调递减(自动学习率衰减)
4.3 AdaGrad 公式的完整推导
让我们从初始状态开始,逐步推导 AdaGrad 的更新过程。
初始条件:
$$G_0 = 0$$
第1步:
$$G_1 = G_0 + \nabla_\theta L(\theta_1) \odot \nabla_\theta L(\theta_1) = \nabla_\theta L(\theta_1) \odot \nabla_\theta L(\theta_1)$$
$$\theta_2 = \theta_1 - \frac{\alpha}{\sqrt{G_1 + \epsilon}} \odot \nabla_\theta L(\theta_1)$$
$$= \theta_1 - \frac{\alpha}{\sqrt{\nabla_\theta L(\theta_1) \odot \nabla_\theta L(\theta_1) + \epsilon}} \odot \nabla_\theta L(\theta_1)$$
第2步:
$$G_2 = G_1 + \nabla_\theta L(\theta_2) \odot \nabla_\theta L(\theta_2)$$
$$= \nabla_\theta L(\theta_1) \odot \nabla_\theta L(\theta_1) + \nabla_\theta L(\theta_2) \odot \nabla_\theta L(\theta_2)$$
$$\theta_3 = \theta_2 - \frac{\alpha}{\sqrt{G_2 + \epsilon}} \odot \nabla_\theta L(\theta_2)$$
第t步(一般形式):
$$G_t = \sum_{i=1}^{t} \nabla_\theta L(\theta_i) \odot \nabla_\theta L(\theta_i)$$
$$\theta_{t+1} = \theta_t - \frac{\alpha}{\sqrt{G_t + \epsilon}} \odot \nabla_\theta L(\theta_t)$$
$$= \theta_t - \frac{\alpha}{\sqrt{\sum_{i=1}^{t} [\nabla_\theta L(\theta_i)]^2 + \epsilon}} \odot \nabla_\theta L(\theta_t)$$
关键洞察:
- $G_t$ 是历史梯度平方的累积和(单调递增)
- 每个参数的学习率 = $\frac{\alpha}{\sqrt{该参数的历史梯度平方和 + \epsilon}}$
- 梯度大的参数,累积平方和增长快,学习率衰减快
- 梯度小的参数,累积平方和增长慢,学习率衰减慢
4.4 逐元素展开(标量形式)
为了更好地理解,我们将公式展开为每个参数的标量形式:
假设参数向量 $\theta = [\theta_1, \theta_2, ..., \theta_n]^T$,梯度向量 $\nabla_\theta L = [g_1, g_2, ..., g_n]^T$。
对于第 $i$ 个参数 $\theta_i$:
$$G_{t,i} = \sum_{k=1}^{t} g_{k,i}^2$$
$$\theta_{t+1,i} = \theta_{t,i} - \frac{\alpha}{\sqrt{G_{t,i} + \epsilon}} \cdot g_{t,i}$$
$$= \theta_{t,i} - \frac{\alpha}{\sqrt{\sum_{k=1}^{t} g_{k,i}^2 + \epsilon}} \cdot g_{t,i}$$
公式中每一项的详细说明:
- $\theta_{t,i}$:第 $t$ 步时第 $i$ 个参数的值
- $g_{t,i} = \frac{\partial L}{\partial \theta_i}\bigg|_{\theta_t}$:第 $t$ 步时第 $i$ 个参数的梯度
- $g_{k,i}^2$:第 $k$ 步时第 $i$ 个参数的梯度平方
- $G_{t,i} = \sum_{k=1}^{t} g_{k,i}^2$:第 $i$ 个参数到第 $t$ 步的累积梯度平方和
- $\sqrt{G_{t,i} + \epsilon}$:第 $i$ 个参数的自适应学习率分母
- $\frac{\alpha}{\sqrt{G_{t,i} + \epsilon}}$:第 $i$ 个参数的有效学习率(自适应学习率)
- $\epsilon$:小常数,防止 $G_{t,i} = 0$ 时分母为0(通常取 $10^{-8}$)
- $\alpha$:全局初始学习率(所有参数共享)
更新步长分析:
第 $i$ 个参数在第 $t$ 步的更新步长为:
$$\text{步长}i = \frac{\alpha}{\sqrt{G{t,i} + \epsilon}} \cdot |g_{t,i}|$$
情况1:梯度大且频繁
- $g_{t,i}$ 大,$G_{t,i}$ 增长快
- $\sqrt{G_{t,i}}$ 大,学习率 $\frac{\alpha}{\sqrt{G_{t,i}}}$ 小
- 步长 = 小学习率 × 大梯度 = 中等步长(避免震荡)
情况2:梯度小且频繁
- $g_{t,i}$ 小,$G_{t,i}$ 增长慢
- $\sqrt{G_{t,i}}$ 小,学习率 $\frac{\alpha}{\sqrt{G_{t,i}}}$ 大
- 步长 = 大学习率 × 小梯度 = 中等步长(加速收敛)
情况3:梯度稀疏但大
- $g_{t,i}$ 大但出现频率低,$G_{t,i}$ 增长慢
- $\sqrt{G_{t,i}}$ 小,学习率 $\frac{\alpha}{\sqrt{G_{t,i}}}$ 大
- 步长 = 大学习率 × 大梯度 = 大步长(快速更新稀疏参数)
4.5 学习率衰减分析
让我们分析 AdaGrad 的学习率如何随时间衰减。
假设梯度大小恒定:
假设第 $i$ 个参数在每一步的梯度大小都相同:$|g_{k,i}| = g$(常数)
则:
$$G_{t,i} = \sum_{k=1}^{t} g^2 = t \cdot g^2$$
有效学习率:
$$\eta_{t,i} = \frac{\alpha}{\sqrt{G_{t,i} + \epsilon}} = \frac{\alpha}{\sqrt{t \cdot g^2 + \epsilon}} \approx \frac{\alpha}{g \sqrt{t}}$$
关键观察:
- 有效学习率与 $\frac{1}{\sqrt{t}}$ 成正比(自动学习率衰减)
- 梯度 $g$ 越大,学习率衰减越快
- 梯度 $g$ 越小,学习率衰减越慢
更新步长:
$$\text{步长}i = \eta{t,i} \cdot g = \frac{\alpha}{g \sqrt{t}} \cdot g = \frac{\alpha}{\sqrt{t}}$$
重要结论:
- 即使梯度大小恒定,更新步长也会随时间衰减($\propto \frac{1}{\sqrt{t}}$)
- 这提供了自动的学习率衰减机制
- 但这也可能导致学习率过早衰减到0(这是 AdaGrad 的一个缺点)
5. AdaGrad 的优势和劣势
5.1 优势
- 自适应学习率:每个参数有自己的学习率,适应不同参数的更新需求
- 适合稀疏梯度:稀疏但大的梯度能保持较大的学习率,快速更新
- 自动学习率衰减:随着训练进行,学习率自动减小,无需手动调整
- 减少超参数调优:主要只需要调整初始学习率 $\alpha$
5.2 劣势
- 学习率过早衰减:$G_t$ 单调递增,学习率单调递减,可能过早衰减到接近0
- 不适合非凸优化:在非凸优化中,可能需要学习率重新增大,但 AdaGrad 无法做到
- 累积平方和持续增长:$G_t$ 只增不减,导致后期学习率过小
5.3 改进方法
为了解决 AdaGrad 的学习率过早衰减问题,后续出现了改进算法:
- RMSProp:使用指数移动平均代替累积和,允许学习率重新增大
- Adam:结合了 Momentum 和 RMSProp 的思想
(这些内容将在后续教程中详细讲解)
6. 标准梯度下降、Momentum、AdaGrad 对比
为了对比标准梯度下降、动量法和 AdaGrad 的效果,我们使用一个经典的鞍点函数:
$$f(x, y) = x^2 - y^2$$
函数特点:
- 在 $x$ 方向上:$f(x, y) = x^2$,是凸函数,最小值在 $x=0$
- 在 $y$ 方向上:$f(x, y) = -y^2$,是凹函数,最大值在 $y=0$
- 鞍点:$(0, 0)$,梯度为0,但不是全局最优
- 全局最优:不存在(函数无下界)
梯度:
$$\frac{\partial f}{\partial x} = 2x$$
$$\frac{\partial f}{\partial y} = -2y$$
在鞍点 $(0, 0)$ 处:
- $\frac{\partial f}{\partial x} = 0$
- $\frac{\partial f}{\partial y} = 0$
- 梯度为0,普通梯度下降会停滞
AdaGrad 的优势:
- 在接近鞍点时,$x$ 方向的梯度逐渐减小,$y$ 方向的梯度也逐渐减小
- AdaGrad 会根据历史梯度自动调整学习率
- 如果从某个方向接近鞍点,历史梯度信息可以帮助算法继续前进
6.1 三种优化算法在鞍点函数上的表现

6.2 损失函数值对比

6.3 AdaGrad 的自适应学习率变化

6.4 三种算法的详细对比

从实验结果可以看到:
-
x方向和y方向的学习率不同:
- x方向的梯度:$\frac{\partial f}{\partial x} = 2x$,在初始点(2.5, 1.5)处,梯度为5
- y方向的梯度:$\frac{\partial f}{\partial y} = -2y$,在初始点(2.5, 1.5)处,梯度为-3
- x方向的梯度更大,累积平方和增长更快,学习率衰减更快
- y方向的梯度较小,累积平方和增长较慢,学习率衰减较慢
-
自动学习率衰减:
- 随着训练进行,两个方向的学习率都逐渐减小
- 这提供了自动的学习率衰减机制
- 但可能导致后期学习率过小,更新步长过小
-
更新步长的平衡:
- 虽然x方向的梯度大,但由于学习率小,更新步长不会过大
- 虽然y方向的梯度小,但由于学习率大,更新步长不会过小
- 这实现了不同方向上的平衡更新
6.4.1 三种算法的对比
普通梯度下降:
- 使用固定学习率,所有参数相同
- 在鞍点附近容易停滞
- 收敛速度较慢
Momentum(动量法):
- 引入动量项,加速收敛
- 可以帮助逃离鞍点
- 但仍使用固定学习率
AdaGrad(自适应梯度):
- 每个参数有自己的学习率
- 自动适应不同参数的更新需求
- 自动学习率衰减
- 但可能过早衰减到接近0
6.4.2 AdaGrad 的适用场景
适合的场景:
- 稀疏梯度问题(如自然语言处理中的词嵌入)
- 需要自动学习率衰减的场景
- 不同参数需要不同学习率的场景
不适合的场景:
- 需要学习率重新增大的非凸优化
- 长期训练(学习率会过早衰减)
- 需要精细控制学习率的场景
6.4.3 AdaGrad 的改进方向
为了解决 AdaGrad 的学习率过早衰减问题,后续出现了改进算法:
-
RMSProp:使用指数移动平均代替累积和
$$G_t = \beta \cdot G_{t-1} + (1-\beta) \cdot \nabla_\theta L(\theta_t) \odot \nabla_\theta L(\theta_t)$$- 允许学习率重新增大
- 更关注最近的梯度信息
-
Adam:结合 Momentum 和 RMSProp
- 既利用历史梯度信息(Momentum)
- 又自适应调整学习率(RMSProp)
(这些内容将在后续教程中详细讲解)
7. 总结
7.1 核心公式回顾
AdaGrad 的更新公式:
$$G_t = G_{t-1} + \nabla_\theta L(\theta_t) \odot \nabla_\theta L(\theta_t)$$
$$\theta_{t+1} = \theta_t - \frac{\alpha}{\sqrt{G_t + \epsilon}} \odot \nabla_\theta L(\theta_t)$$
公式中每一项的含义:
- $G_t$:累积梯度平方和(向量)
- $\alpha$:全局初始学习率
- $\sqrt{G_t + \epsilon}$:自适应学习率分母
- $\frac{\alpha}{\sqrt{G_t + \epsilon}}$:自适应学习率(向量,每个参数不同)
- $\epsilon$:小常数,防止分母为0
7.2 关键特性
- 自适应学习率:每个参数有自己的学习率
- 自动衰减:学习率随训练自动减小
- 适合稀疏梯度:稀疏但大的梯度能保持较大学习率
- 减少超参数:主要只需调整初始学习率
7.3 优缺点
优点:
- 自适应学习率,适应不同参数
- 适合稀疏梯度
- 自动学习率衰减
缺点:
- 学习率可能过早衰减到0
- 不适合需要学习率重新增大的场景