Appearance
Adagrad算法
音译为"阿达格拉德", 全称为 Adaptive Gradient Algorithm
Adagrad 是一种自适应步长的优化算法,专门解决 “稀疏特征”(比如 NLP 里的低频词、推荐系统里的小众物品)的学习率问题 —— 就像登山时给不同的路况定制不同的步长:崎岖的陡坡走小步,平坦的缓坡走大步,让每个参数都能以合适的速度收敛,是稀疏数据优化的 “利器”。
一、核心逻辑:为啥需要 “定制步长”?
1. 普通梯度下降的痛点
在稀疏数据场景(比如训练语言模型),不同参数的更新频率差异极大:
高频特征(比如 “学习” 这个词)的参数经常更新,普通梯度下降的学习率对它们来说可能降得太慢,容易震荡;
低频特征(比如 “预先条件” 这个词)的参数很少更新,普通梯度下降的学习率对它们来说可能降得太快,还没学到足够的信息就停止更新了。
这就像登山时不管是陡坡还是平路都用同样的步长:陡坡走大步容易摔,平路走小步太慢,效率极低。
2. Adagrad 的解决方案
Adagrad 给每个参数单独定制学习率:
对于梯度大的参数(相当于崎岖陡坡):过去的梯度平方和大,学习率自动变小,走小步,避免震荡;
对于梯度小的参数(相当于平坦缓坡):过去的梯度平方和小,学习率自动保持较大,走大步,保证足够的更新。
简单说:Adagrad 让 “难走的路慢走,好走的路快走”,每个参数都能找到自己的最优步长。
二、Adagrad 的核心原理
1. 核心公式
Adagrad 通过累加每个参数过去的梯度平方和来调整学习率,公式如下:
其中:
:每个参数的梯度平方累加和,相当于这个参数的 “路况复杂度记录”;
:全局学习率,控制整体的步长大小;
:一个极小的常数(比如 ),防止除以 0;
:每个参数的自适应学习率,梯度大的参数 大,学习率小,反之亦然。
2. 公式解读
把自适应学习率展开看,每个参数的步长是全局学习率除以 “过去梯度的均方根”:
对于高频特征(梯度频繁更新, 大):学习率 小,步长小,避免震荡;
对于低频特征(梯度很少更新, 小):学习率 大,步长大,保证足够的更新。
3. 直观效果
以二维函数 为例:
的梯度大(相当于陡坡), 增长快,学习率快速变小,步长越来越小,震荡很快被抑制;
的梯度小(相当于缓坡), 增长慢,学习率保持较大,步长足够大,能快速收敛到最小值。
最终 Adagrad 的收敛轨迹比普通梯度下降更平滑,两个参数都能稳定收敛到最小值。
三、关键参数:怎么调才合适?
1. 全局学习率
常用值: ,Adagrad 的自适应学习率是 ,所以 可以比普通梯度下降大一些;
比如在二维函数的例子里,普通梯度下降用 ,Adagrad 可以用 甚至 ,收敛效果更好。
2. 数值稳定性常数
- 常用值: ,防止当 时除以 0,一般不用调整。
四、PyTorch 实战:定制步长的登山流程
1. 从零开始实现
手动实现 Adagrad 的参数更新逻辑,适合理解原理:
python
import torch
from torch import nn
from d2l import torch as d2l
# 1. 初始化Adagrad状态(每个参数对应一个梯度平方累加和,初始为0)
def init_adagrad_states(feature_dim):
s_w = torch.zeros((feature_dim, 1)) # 权重的梯度平方累加和
s_b = torch.zeros(1) # 偏置的梯度平方累加和
return (s_w, s_b)
# 2. Adagrad更新函数
def adagrad(params, states, hyperparams):
eps = 1e-6 # 防止除以0
for p, s in zip(params, states):
with torch.no_grad():
# 累加当前梯度的平方
s[:] += torch.square(p.grad)
# 自适应步长更新参数
p[:] -= hyperparams['lr'] * p.grad / torch.sqrt(s + eps)
p.grad.data.zero_() # 清空梯度
# 3. 训练函数
def train_adagrad(lr, num_epochs=2):
# 加载数据
data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
# 定义模型
net = nn.Sequential(nn.Linear(feature_dim, 1))
nn.init.normal_(net[0].weight, std=0.01)
# 训练
d2l.train_ch11(
adagrad,
init_adagrad_states(feature_dim),
{'lr': lr},
data_iter, feature_dim, num_epochs
)
# 启动训练(lr=0.1,比普通梯度下降大)
train_adagrad(lr=0.1)2. 框架简洁实现
用 PyTorch 内置的optim.Adagrad直接调用,更简洁:
python
# 直接使用框架内置的Adagrad
trainer = torch.optim.Adagrad
d2l.train_concise_ch11(
trainer,
{'lr': 0.1}, # 配置全局学习率
data_iter
)五、优缺点:什么时候用 Adagrad?
1. 优点
自适应步长:自动给每个参数定制学习率,不用手动调整;
对稀疏数据友好:特别适合 NLP、推荐系统、计算广告学等有大量稀疏特征的场景,低频特征能得到足够的更新;
收敛更平滑:梯度大的参数步长自动变小,减少震荡,收敛更稳定。
2. 缺点
学习率衰减太快:因为 是累加的,学习率会不断降低,后期可能学习率太小,导致收敛停滞;
不适合非凸问题:深度学习的非凸问题中,Adagrad 的学习率衰减太快,可能无法跳出局部最小值,所以深度学习里一般用它的改进版(比如 RMSProp、Adam)。
3. 适用场景
稀疏数据的优化:比如 NLP 的词嵌入训练、推荐系统的协同过滤、计算广告学的点击率预测;
凸优化问题:Adagrad 在凸问题里有很好的收敛保证。
六、常见误区:避开这 2 个坑
全局学习率设置太大:虽然 Adagrad 是自适应步长,但全局学习率太大的话,前期的步长会太大,导致震荡;
在深度学习里滥用 Adagrad:深度学习的非凸问题中,Adagrad 的学习率衰减太快,后期容易停滞,一般用 RMSProp 或 Adam 替代。
七、核心总结
Adagrad 本质:给每个参数定制自适应步长,根据过去的梯度平方和调整学习率,梯度大的步长小,梯度小的步长大;
关键优势:对稀疏数据特别友好,解决了普通梯度下降对稀疏特征学习率不合适的问题;
适用场景:稀疏数据的凸优化问题,比如 NLP、推荐系统、计算广告学;
一句话记忆:登山时看路况调步长,陡坡小步走,平路大步走,每个参数都能高效下山~
(注:文档部分内容可能由 AI 生成)