Momentum¶
Momentum 是一种优化算法,也可以看作是对梯度下降法的改进。它通过引入“动量”的概念,让参数更新不仅依赖当前的梯度,还参考了之前的梯度方向,从而在优化过程中能够更快地收敛并减少振荡。
核心思想¶
Momentum 模仿了物理学中动量的概念,认为参数更新的方向和步幅不仅由当前梯度决定,还受之前梯度的累积影响。
具体来说,它通过在梯度更新中加入动量项,让优化过程更有“惯性”。
当梯度在某一方向上持续变化时,动量会加速收敛。
当梯度方向频繁波动时,动量可以减少参数更新的振荡幅度。
公式¶
参数更新的过程
\[1. 动量更新: 𝑣_𝑡=𝛾𝑣_{𝑡−1}+𝜂𝑔_𝑡
2. 参数更新: 𝜃_{𝑡+1}=𝜃_𝑡−𝑣_𝑡\]
设:
\(𝑔_𝑡\) : 当前梯度。
\(𝑣_𝑡\) : 动量,表示过去梯度的累积方向。
𝜂: 学习率。
𝛾: 动量系数,控制动量的影响程度(通常取值为 0.9)。
\(𝛾𝑣_{𝑡−1}\) :保留一部分之前的动量,表示“惯性”。
\(𝜂𝑔_𝑡\) :结合当前梯度的影响。
优缺点¶
优点:
加速收敛:
在梯度方向一致的情况下,动量会累积,能够快速靠近最优点。
减少振荡:
在高维或复杂损失面中,动量可以减缓参数在梯度方向频繁变换时的震荡,尤其在狭长弯曲区域(如鞍点附近)。
提高鲁棒性:
动量能让优化器在噪声梯度下表现更稳定。
局限性:
超参数敏感性:
动量系数 𝛾 的选择对优化效果影响较大,通常需要尝试多个值。
可能过快跳过局部最优点:
如果动量过大,可能会让参数跳过最优区域。
直观理解:
在优化过程中,Momentum 就像一个滚动的小球:
如果地形(损失函数)是一个向下的坡,小球会因“惯性”加速滚动。
如果遇到凹凸不平的地形,惯性可以帮助小球平滑地滚过这些波动。
代码示例¶
import torch
import torch.optim as optim
# 假设一个简单的模型
model = torch.nn.Linear(10, 1)
criterion = torch.nn.MSELoss()
# 使用 SGD + Momentum
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 简单训练循环
for epoch in range(10):
inputs = torch.randn(32, 10)
targets = torch.randn(32, 1)
# 前向传播
outputs = model(inputs)
loss = criterion(outputs, targets)
# 反向传播与优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"Epoch [{epoch+1}/10], Loss: {loss.item():.4f}")