我试图理解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 *一个
和损失/净额结算(5-netout)w.r.t到netout ==> (0-1)
哪个是1 * a * -1 ==> -1
但问题是,如果我再次按相同的单元而不修改任何东西,那么我得到毕业-2,-3,-4 ......等
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.])
等......
我不知道为什么以及毕业价值如何增加?
答案 0 :(得分:2)
这是因为你没有将渐变归零。 loss.backward()
做的是累积渐变 - 它会为现有渐变添加渐变。如果你没有将渐变归零,那么反复运行loss.backward()
只是继续相互添加渐变。你想要做的是在每一步之后将渐变归零,你会看到渐变是正确计算的。
如果您已构建网络net
(应该是nn.Module
类对象),则只需调用net.zero_grad()
即可将渐变归零。如果您尚未构建net
(或torch.optim
对象),则必须手动将渐变归零。
在那里使用weight.grad.data.zero_()
方法。