net.zero_grad() 与 optim.zero_grad() pytorch

Posted

技术标签:

【中文标题】net.zero_grad() 与 optim.zero_grad() pytorch【英文标题】:net.zero_grad() vs optim.zero_grad() pytorch 【发布时间】:2020-09-05 23:13:35 【问题描述】:

Here 他们提到在将参数梯度训练为零时需要包含optim.zero_grad()。我的问题是:我也可以这样做net.zero_grad() 会产生同样的效果吗?还是有必要做optim.zero_grad()。此外,如果我两者都做会发生什么?如果我什么都不做,那么梯度会累积,但这到底是什么意思?他们被添加了吗?换句话说,做optim.zero_grad()net.zero_grad()有什么区别。我问是因为here, line 115 他们使用net.zero_grad(),这是我第一次看到,这是强化学习算法的一种实现,因为有多个网络和梯度,所以必须特别小心梯度,所以我想他们有理由这样做net.zero_grad(),而不是optim.zero_grad()

【问题讨论】:

【参考方案1】:

net.zero_grad() 将其所有参数(包括子模块的参数)的梯度设置为零。如果您调用optim.zero_grad(),它将执行相同的操作,但对于已指定要优化的所有参数。如果您在优化器中仅使用 net.parameters(),例如optim = Adam(net.parameters(), lr=1e-3),那么两者是等价的,因为它们包含完全相同的参数。

您可能拥有由同一优化器优化的其他参数,它们不属于net,在这种情况下,您要么必须手动将它们的梯度设置为零,从而跟踪所有参数,要么您可以简单地调用optim.zero_grad() 以确保所有正在优化的参数都将其梯度设置为零。

另外,如果我两者都做会怎样?

没什么,梯度只是再次设置为零,但由于它们已经为零,所以完全没有区别。

如果我什么都不做,那么梯度会累积,但这到底是什么意思?他们被添加了吗?

是的,它们正在添加到现有渐变中。在反向传递中,计算每个参数的梯度,然后将梯度添加到参数的梯度 (param.grad)。这允许您有多个反向传递,这会影响相同的参数,如果梯度被覆盖而不是被添加,这是不可能的。

例如,如果您需要更大的批次以提高训练稳定性,但没有足够的内存来增加批次大小,您可以累积多个批次的梯度。这在 PyTorch 中实现起来很简单,这实际上是放弃 optim.zero_grad() 并延迟 optim.step() 直到您收集到足够的步骤,如 HuggingFace - Training Neural Nets on Larger Batches: Practical Tips for 1-GPU, Multi-GPU & Distributed setups 所示。

这种灵活性的代价是必须手动将渐变设置为零。坦率地说,一条线路的支付成本非常低,尽管许多用户不会使用它,尤其是初学者可能会感到困惑。

【讨论】:

以上是关于net.zero_grad() 与 optim.zero_grad() pytorch的主要内容,如果未能解决你的问题,请参考以下文章

python网络编程基础(线程与进程并行与并发同步与异步)

=与==&与&&| 与 || 的区别

与 0 进行比较与与某个值进行比较是不是更快?

三.工具与市场-债券与债务股票与公司

RESTfulREST 与 RESTful 理解与实践

RESTfulREST 与 RESTful 理解与实践