AdaGrad如何根据梯度平方和自动调整学习率?
区分基础学习率与每个参数的有效学习率,并解释AdaGrad为什么越训练越慢。
DETAILED ANSWER
直接结论
AdaGrad确实会调整步长,但不是随意修改你设置的基础学习率。它为每个参数分别累计历史梯度平方,再用这个累计值缩小该参数本轮的有效学习率。
历史梯度平方和越大
→ 分母越大
→ 当前参数的有效学习率越小
它为每个参数维护一份累计值
对某一个参数,设本轮梯度为g_t,累计值为s_t:
s_t = s_(t-1) + g_t²
参数更新可以简化为:
新w = 旧w − η / (sqrt(s_t) + ε) × g_t
这里:
η:人工设置的基础学习率;s_t:这个参数从训练开始到现在的梯度平方和;ε:防止分母为0的小数;η / (sqrt(s_t) + ε):这个参数当前真正使用的有效学习率。
不同教材可能把ε写在平方根内或平方根外,但“用历史梯度平方累计值缩小步长”的核心不变。
用数字看步长怎样变化
假设基础学习率η=0.1,某个参数连续两次梯度都是2,暂时忽略ε。
第一次:
s_1 = 0 + 2² = 4
有效学习率 = 0.1 / sqrt(4) = 0.05
参数移动量 = 0.05 × 2 = 0.10
第二次:
s_2 = 4 + 2² = 8
有效学习率 = 0.1 / sqrt(8) ≈ 0.035
参数移动量 ≈ 0.035 × 2 = 0.071
梯度相同,但由于累计平方和变大,第二次移动距离更小。
为什么要平方
平方有两个作用:
- 正负梯度不会互相抵消,能稳定记录历史梯度的大小;
- 梯度长期较大的参数会得到更强的步长缩小。
方向并不是由平方和决定的。更新公式中仍然乘着未平方的g_t,因此参数往左还是往右仍由当前梯度的正负决定。
为什么后期可能走不动
AdaGrad的s_t只会累加,不会遗忘早期梯度。因此训练越久,分母通常越大,有效学习率就越小,后期可能几乎不再更新。这正是RMSProp改用“近期梯度平方平均”的原因。
