需要在培训期间调用方法zero_grad()
。但是documentation并不是很有帮助
| zero_grad(self)
| Sets gradients of all model parameters to zero.
为什么我们需要调用此方法?
答案 0 :(得分:25)
在PyTorch
中,我们需要在开始进行反向传播之前将渐变设置为零,因为PyTorch 会在后续的反向传递中累积渐变。在训练RNN时这很方便。因此,默认操作是在每次loss.backward()
调用时累积渐变。
因此,当您开始训练循环时,理想情况下您应该zero out the gradients
以便正确执行参数更新。否则,梯度将指向除预期方向之外的其他方向(即最大化目标)。
这是一个简单的例子:
import torch
from torch.autograd import Variable
import torch.optim as optim
def linear_model(x, W, b):
return torch.matmul(x, W) + b
data, targets = ...
W = Variable(torch.randn(4, 3), requires_grad=True)
b = Variable(torch.randn(3), requires_grad=True)
optimizer = optim.Adam([W, b])
for sample, target in zip(data, targets):
# clear out the gradients of all Variables
# in this optimizer (i.e. W, b)
optimizer.zero_grad()
output = linear_model(sample, W, b)
loss = (output - target) ** 2
loss.backward()
optimizer.step()
或者,如果您正在进行香草梯度下降,那么
W = Variable(torch.randn(4, 3), requires_grad=True)
b = Variable(torch.randn(3), requires_grad=True)
for sample, target in zip(data, targets):
# clear out the gradients of Variables
# (i.e. W, b)
W.grad.data.zero_()
b.grad.data.zero_()
output = linear_model(sample, W, b)
loss = (output - target) ** 2
loss.backward()
W -= learning_rate * W.grad.data
b -= learning_rate * b.grad.data
答案 1 :(得分:2)
zero_grad()正在重新启动循环,如果您使用梯度方法来减少错误(或损失),则不会从上一步中丢失
如果您不使用zero_grad(),那么损失将减少而不会根据需要增加
例如 如果使用zero_grad(),则会找到以下输出:
model training loss is 1.5
model training loss is 1.4
model training loss is 1.3
model training loss is 1.2
如果不使用zero_grad(),则会发现以下输出:
model training loss is 1.4
model training loss is 1.9
model training loss is 2
model training loss is 2.8
model training loss is 3.5
答案 2 :(得分:0)
虽然这个想法可以从选择的答案中得出,但我觉得我想明确地写出来。
能够决定何时调用 optimizer.zero_grad()
和 optimizer.step()
为优化器在训练循环中如何累积和应用梯度提供了更多的自由。当模型或输入数据很大并且一个实际训练批次不适合 GPU 卡时,这一点至关重要。
在这个来自 google-research 的示例中,有两个参数,分别命名为 train_batch_size
和 gradient_accumulation_steps
。
train_batch_size
是前向传递的批量大小,跟在 loss.backward()
之后。这是受gpu内存限制的。
gradient_accumulation_steps
是实际的训练批量大小,其中累积了多次前向传递的损失。这不受 gpu 内存的限制。
从此示例中,您可以看到 optimizer.zero_grad()
后面是如何optimizer.step()
但NOT loss.backward()
后面。 loss.backward()
会在每次迭代中调用(第 216 行),但 optimizer.zero_grad()
和 optimizer.step()
仅在累积训练批次数等于 gradient_accumulation_steps
时才会调用(if
中的第 227 行)第 219 行中的 {1}} 块)
https://github.com/google-research/xtreme/blob/master/third_party/run_classify.py
也有人在询问 TensorFlow 中的等效方法。我猜 tf.GradientTape 的用途相同。
(我对 AI 库还是个新手,如果我说的有误请指正)