为什么我们需要在PyTorch中明确归零渐变?调用loss.backward()
时为什么不能将渐变归零?通过在图表上保持渐变并要求用户明确地将梯度归零来实现什么样的场景?
答案 0 :(得分:35)
我们明确需要调用zero_grad()
,因为在loss.backward()
之后(计算渐变时),我们需要使用optimizer.step()
来进行渐变下降。更具体地说,渐变不会自动归零,因为这两个操作loss.backward()
和optimizer.step()
是分开的,optimizer.step()
需要刚刚计算出的渐变。
此外,有时候,我们需要在一些批次之间积累梯度;要做到这一点,我们可以简单地多次调用backward
并优化一次。
答案 1 :(得分:5)
我有一个PyTorch当前设置的用例。
如果正在使用在每个步骤进行预测的递归神经网络(RNN),人们可能希望有一个超参数,允许人们及时积累渐变。不是每次都将梯度归零,步骤允许人们以有趣和新颖的方式使用反向传播时间(BPTT)。
如果您想了解有关BPTT或RNN的更多信息,请参阅文章Recurrent Neural Networks Tutorial, Part 3 – Backpropagation Through Time and Vanishing Gradients或The Unreasonable Effectiveness of Recurrent Neural Networks。
答案 2 :(得分:2)
在调用.step()
之前将梯度保留在适当的位置很有用,以防您要在多个批次中累积梯度(如其他人所提到的)。
如果要为SGD实现动量,在之后调用.step()
时它也很有用,其他各种方法可能取决于上次更新的梯度值。
答案 3 :(得分:0)
因为loss.backward()
没有任何指定方法。
torch.autograd.backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False, grad_variables=None)
您可以从所有选项中指定没有办法手动将梯度归零。
关于每次与zero_grad()
进行backward()
以及与preserve_grads=True
保持毕业的讨论,但这从未成为现实。