Skip to content

Adam

Adaptive Moment Estimation

Adam 是目前最广泛使用的深度学习优化器之一。它巧妙地结合了两种优化思想:动量自适应学习率,让模型训练既快又稳。

核心思想

  • 动量(Momentum):来自 SGD with Momentum。它像物理中的惯性,保留之前梯度的方向,在平坦区域加速,在震荡区域平滑。
  • 自适应学习率(Adaptive Learning Rate):来自 AdaGrad 和 RMSProp。它为每个参数单独调整学习率,让那些频繁出现大梯度的参数学习率变小,反之变大。

Adam 维护两个指数移动平均:

  • 一阶矩 mt :梯度的平均(带衰减),反映梯度方向。
  • 二阶矩 vt :梯度平方的平均,反映梯度的大小(或方差)。

最终用这两个量来动态计算每个参数的实际更新步长。

更新公式

设第 t 步的梯度为 gt,Adam 的更新过程为:

(更新一阶矩)mt=β1mt1+(1β1)gt(更新二阶矩)vt=β2vt1+(1β2)gt2(偏差修正)m^t=mt1β1t(偏差修正)v^t=vt1β2tθt+1=θtηv^t+ϵm^t

参数说明:

  • β1=0.9β2=0.999 (常用默认值)
  • η:学习率(默认0.001)
  • ϵ=108:防止除0

直观理解

  • 一阶矩 mt:相当于梯度的“带遗忘的累加”。如果一个方向梯度一直为正,mt 会正向累积,从而加速更新;如果梯度来回震荡,mt 会相互抵消,起到平滑作用。
  • 二阶矩 vt:记录过去梯度平方的均值,反映该参数梯度的“典型大小”。梯度大的参数,vt 大,学习率变小,避免震荡;梯度小的参数,学习率变大,加快收敛。
  • 偏差修正:因为 m0v0 初始为 0,早期估计会偏向 0,修正后能让估计更快进入正确范围。

优点

  • 实现简单,计算高效:只需额外存储一阶矩和二阶矩,内存占用小。
  • 对超参数不敏感:默认参数通常就能工作得很好,无需大量调参。
  • 适合稀疏梯度:对于词嵌入等稀疏特征,二阶矩归一化能让每个特征都有合适的更新步长。
  • 自动调整学习率:省去了手动调节学习率的麻烦。

对比 SGD

你可以把训练一个模型想象成这样一个场景:

你站在一座大山(数学函数)的某个点上。你的目标是要走到这座山最低的谷底(最小的误差)。但你什么都看不见,只能用脚去探。

  • 你踩一下,感觉哪边比较陡(计算梯度)。
  • 你往陡的方向跨一小步(更新参数)。

这个“用脚探路,往陡的地方走”的过程,就是最基础的梯度下降

这个“盲人下山”的方法虽然能走到谷底,但有几个很烦人的问题:

  • 问题一:原地踏步,走不动
    如果你走到一个“平原”上,四周都是平缓的,你感觉哪里都不陡,脚步就会变得很小很小,甚至可能停住不动。这在数学里叫梯度消失或者陷入鞍点。模型学不动了。
  • 问题二:疯狂震荡,走不稳
    假设你要下的山不是个圆润的碗,而是一个又窄又深的峡谷。你可能在峡谷两侧的峭壁上跳来跳去,每一步都很大,但一直下不去,浪费了很多力气。这在数学里叫震荡。模型跑偏了。
  • 问题三:步伐一成不变,不聪明。
    你在很陡的地方应该用小碎步,防止摔跤;在平缓的地方应该迈大步,快点过去。但是基础版下山法步子的大小是固定的,没法根据地形改变。

Adam就是为了解决上面那几个傻瓜问题而设计的。

  • 装备一:“记忆球”
    这个球记录着他之前走过的方向。当走到平原感觉不到坡度时,记忆球会告诉他:“别停,我们之前是朝着这个方向来的,继续走!”这就解决了走不动的问题。这在数学里叫动量
  • 装备二:“地形感知器”
    这个装备能记录脚下的路是经常很陡,还是经常很平。对于那些经常很陡的方向,他意识到危险,会自觉地迈小碎步;对于那些一直很平的方向,他意识到这里安全,可以迈大步快速通过。这就解决了步伐不聪明震荡的问题。这在数学里叫自适应学习率

总结:

  • SGD:一个盲人,靠脚探路,傻傻地走。
  • SGD with Momentum:盲人有了惯性,能冲过小土坡。
  • RMSProp / AdaGrad:给不同方向的路配了不同的灵敏度。
  • Adam:一个既有惯性(动量),又对不同地形有不同灵敏度(自适应学习率)的登山者。