修改pytorch张量然后获取渐变使渐变不起作用

时间:2018-10-29 18:44:01

标签: python gradient pytorch gradients

我是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

后面的代码有什么问题?以及我该如何纠正?

任何帮助将不胜感激。非常感谢!

1 个答案:

答案 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)

希望这会有所帮助!