『梯度清零』和 momentum 冲突吗?

在PyTorch中,即使使用了optimizer.zero_grad()来清零梯度,优化器仍然能够利用 momentum 来更新参数。这是因为optimizer.zero_grad()只是将模型的参数梯度设置为0,而优化器内部会维护一个额外的状态,用于存储每个参数的前一个梯度(即动量)。这个状态在每次optimizer.step()调用时会被更新,并且用于计算新的参数值。

当你使用带有动量的SGD优化器时,每个参数的更新不仅取决于当前的梯度,还取决于之前的梯度。优化器内部会为每个参数维护一个动量变量,这个变量在每次optimizer.step()调用时会被更新,并用于计算参数的更新量。

具体来说,动量算法会这样做:

  1. 在每次迭代开始时,optimizer.zero_grad()会清零参数的梯度,但不会影响优化器内部维护的动量变量。

  2. 在前向传播和反向传播之后,loss.backward()会计算当前迭代的梯度。

  3. optimizer.step()会执行实际的参数更新。在这个步骤中,优化器会根据当前的梯度和之前的动量变量来更新每个参数。更新后的动量变量会被存储起来,用于下一次迭代。

  4. 动量变量会根据以下公式更新:

\[v = \mu \times v + \nabla \theta \]

其中, \(v\) 是动量变量, \(\mu\) 是动量系数(momentum), \(\nabla \theta\) 是当前参数的梯度。

  1. 参数更新公式会考虑动量变量:

\[\theta = \theta - \eta \times v \]

其中, \(\theta\) 是参数, \(\eta\) 是学习率。

因此,即使梯度在每个迭代开始时被清零,优化器仍然能够利用之前迭代的梯度信息来更新参数,这就是动量能够提高训练稳定性和速度的原因。

posted @ 2024-02-03 09:30  茴香豆的茴  阅读(9)  评论(0编辑  收藏  举报