我试图理解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/