Neural network 为什么我们需要显式调用zero_grad()?
为什么我们需要显式地将PyTorch中的梯度归零?为什么调用Neural network 为什么我们需要显式调用zero_grad()?,neural-network,deep-learning,pytorch,gradient-descent,Neural Network,Deep Learning,Pytorch,Gradient Descent,为什么我们需要显式地将PyTorch中的梯度归零?为什么调用loss.backward()时不能将渐变归零?将梯度保留在图形上,并要求用户显式地将梯度归零,这适用于什么情况?我们显式地需要调用zero\u grad(),因为在loss.backward()(计算梯度时)之后,我们需要使用optimizer.step()来进行梯度下降。更具体地说,渐变不会自动归零,因为这两个操作,loss.backward()和optimizer.step()是分开的,并且optimizer.step()需要刚刚
loss.backward()
时不能将渐变归零?将梯度保留在图形上,并要求用户显式地将梯度归零,这适用于什么情况?我们显式地需要调用zero\u grad()
,因为在loss.backward()
(计算梯度时)之后,我们需要使用optimizer.step()
来进行梯度下降。更具体地说,渐变不会自动归零,因为这两个操作,loss.backward()
和optimizer.step()
是分开的,并且optimizer.step()
需要刚刚计算的渐变
此外,有时我们需要在一些批次之间累积梯度;要做到这一点,我们只需多次向后调用
,
并进行一次优化。我有一个PyTorch中当前设置的用例
如果一个人使用的是在每一步都进行预测的递归神经网络(RNN),那么他可能希望有一个超参数,允许他在时间上累积梯度。不必在每个时间步将梯度归零,就可以以有趣而新颖的方式使用时间反向传播(BPTT)
如果您想了解有关BPTT或RNN的更多信息,请参阅文章或。在调用
之前保留梯度。如果您想在多个批次之间累积梯度(如其他人所述),步骤()
非常有用
如果您想为SGD实现动量,那么在调用
.step()
之后,它也很有用,其他各种方法可能取决于上一次更新的梯度值。PyTorch中有一个循环:
- 当我们从输入中获得输出或
时向前y\u hat
- 计算损失,其中
loss=loss\u fn(y\u hat,y)
当我们计算梯度时loss.backward
优化程序。更新参数时的步骤
for mb in range(10): # 10 mini batches
y_pred = model(x)
loss = loss_fn(y_pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
如果我们不在优化器.step
之后清除梯度,这是适当的步骤,或者在下一个backward()之前,梯度将累积。
下面是一个显示累积的示例:
import torch
w = torch.rand(5)
w.requires_grad_()
print(w)
s = w.sum()
s.backward()
print(w.grad) # tensor([1., 1., 1., 1., 1.])
s.backward()
print(w.grad) # tensor([2., 2., 2., 2., 2.])
s.backward()
print(w.grad) # tensor([3., 3., 3., 3., 3.])
s.backward()
print(w.grad) # tensor([4., 4., 4., 4., 4.])
没有任何方法指定此项
torch.autograd.backward(张量,梯度张量=None,保留图=None,创建图=False,梯度变量=None)
从所有可以指定的选项中,无法手动将渐变归零。如前一个迷你示例中所示:
w.grad.zero_()
关于每次使用backward()
(显然是以前的梯度)进行zero_grad()
,并保持梯度,有一些讨论,但这从未出现过。这个答案需要更清楚一些。也许一个例子会有所帮助。下面是它将更新的变量的示例+梯度(即模型的可学习+权重)的解释。这是因为在默认情况下,每当调用.backward()+#时,渐变都会被+#累积在缓冲区中(即,不会被覆盖)。有关详细信息,请查看torch.autograd.backward的文档。实际上,您提到了“minibatch”(或“batch subpartition”)与“batch”——在这种情况下,累加在前馈网络(不仅仅是RNN)中很有用。当我们需要一个更大的批量进行优化,但有物理限制(例如GPU内存)来增加样本数时。您能举一个例子说明我们需要累积梯度吗?@RedFloyd,以防您想要有效地训练一个大批量(想象64),但您的GPU同时只能容纳32个示例。您需要通过两个步骤累积渐变,并且每两个步骤只调用一次optimizer.step()
。