我是pytorch的初学者,我遇到以下问题:
当我得到下面的张量的梯度时(请注意,我以某种方式使用变量x,如下所示),我得到了梯度:
myTensor
现在,如果我尝试修改leaf variable has been moved into the graph interior
的元素,则会收到错误import torch
myTensor = torch.randn(2, 2,requires_grad=True)
myTensor[0,0]*=5
with torch.enable_grad():
x=myTensor.sum() *10
x.backward()
print(myTensor.grad)
。看到以下代码:
big.Float
后面的代码有什么问题?以及我该如何纠正?
任何帮助将不胜感激。非常感谢!
答案 0 :(得分:5)
这里的问题是该行代表就地操作:
myTensor[0,0]*=5
并且 PyTorch 或更准确地说 autograd 在处理就地操作方面不是很好,特别是对于带有{{1 }}标志设置为requires_grad
。
您也可以在这里看看:
https://pytorch.org/docs/stable/notes/autograd.html#in-place-operations-with-autograd
通常,在可能的情况下,应避免进行就地操作,但在某些情况下它可以工作,但应始终避免对张量进行就地操作将True
设置为requires_grad
。
不幸的是,没有多少pytorch函数可以解决此问题。因此,在这种情况下,您将不得不使用辅助张量来避免True
操作:
代码:
in-place
输出:
import torch
myTensor = torch.randn(2, 2,requires_grad=True)
helper_tensor = torch.ones(2, 2)
helper_tensor[0, 0] = 5
new_myTensor = myTensor * helper_tensor # new tensor, out-of-place operation
with torch.enable_grad():
x=new_myTensor.sum() *10 # of course you need to use the new tensor
x.backward() # for further calculation and backward
print(myTensor.grad)
不幸的是,这不是很好,如果有更好或更完善的解决方案,我将不胜感激。
但是就我所知,在当前版本(0.4.1)中,您将不得不针对具有梯度响应的张量使用此解决方法。 tensor([[50., 10.],
[10., 10.]])
。
希望对于将来的版本,会有更好的解决方案。
顺便说一句。如果您稍后激活渐变,您会发现它工作正常:
requires_grad=True
但是,这当然会产生不同的结果:
import torch
myTensor = torch.randn(2, 2,requires_grad=False) # no gradient so far
myTensor[0,0]*=5 # in-place op not included in gradient
myTensor.requires_grad = True # activate gradient here
with torch.enable_grad():
x=myTensor.sum() *10
x.backward() # no problem here
print(myTensor.grad)
希望这会有所帮助!