我试图理解python中的grad()函数,我了解反向传播,但是对.grad()函数结果有些怀疑。

因此,如果我有一个非常简单的网络,说一个输入和一个权重:

import torch
from torch.autograd import Variable
from torch import FloatTensor


a_tensor=Variable(FloatTensor([1]))
weight=Variable(FloatTensor([1]),requires_grad=True)


现在我在ipython单元格中运行它:

net_out=a_tensor*weight
loss=5-net_out
loss.backward()
print("atensor",a_tensor)
print('weight',weight)
print('net_out',net_out)
print('loss',loss)
print(weight.grad)


在第一次运行期间,它返回:

atensor tensor([ 1.])
weight tensor([ 1.])
net_out tensor([ 1.])
loss tensor([ 4.])
tensor([-1.])


这是正确的,因为如果我是对的,那么计算梯度方程将在这里:



现在netout / w将是(w * a)w.r.t到w ==> 1 * a
和损失/净额(5净额)净额==>(0-1)

那将是1 * a * -1 ==> -1

但是问题是,如果我再次按相同的单元格而不修改任何内容,那么我会得到grad -2,-3,-4 ... etc

atensor tensor([ 1.])
weight tensor([ 1.])
net_out tensor([ 1.])
loss tensor([ 4.])
tensor([-2.])


下一次运行:

atensor tensor([ 1.])
weight tensor([ 1.])
net_out tensor([ 1.])
loss tensor([ 4.])
tensor([-3.])


等等。

我不明白那里发生了什么,为什么以及如何增加grad的价值?

最佳答案

这是因为您没有将梯度归零。 loss.backward()的作用是累积渐变-将渐变添加到现有渐变中。如果您不将渐变归零,则一遍又一遍地运行loss.backward(),只需将渐变彼此添加即可。您要做的是在每个步骤之后将梯度设为零,您将看到梯度计算正确。

如果已建立网络net(应该是nn.Module类对象),则只需调用net.zero_grad()即可将梯度归零。如果尚未构建net(或torch.optim对象),则必须自己手动将渐变归零。

在此使用weight.grad.data.zero_()方法。

关于python - Pytorch:.grad()函数如何返回结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50751689/

10-11 22:48