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

Aly*_*Aly 4 python gradient pytorch

我是pytorch的初学者,面临以下问题:

当我得到下面的张量的梯度时(请注意,我以某种方式使用一些变量x,如下所示),我得到了梯度:

import torch
myTensor = torch.randn(2, 2,requires_grad=True)
with torch.enable_grad():
    x=myTensor.sum() *10
x.backward()
print(myTensor.grad)
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试修改的元素,则会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)
Run Code Online (Sandbox Code Playgroud)

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

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

blu*_*nox 5

这里的问题是该行表示就地操作:

myTensor[0,0]*=5
Run Code Online (Sandbox Code Playgroud)

而且PyTorch或更准确地说autograd在处理就地操作方面不是很好,特别是对于那些将requires_grad标志设置为的张量True

您也可以在这里查看:https :
//pytorch.org/docs/stable/notes/autograd.html#in-place-operations-with-autograd

通常,应避免可能的就地操作,在某些情况下它可以工作,但应始终避免对设置为的张量进行就地操作。requires_gradTrue

不幸的是,没有多少pytorch函数可以解决此问题。因此,in-place在这种情况下,您将不得不使用辅助张量来避免操作:

码:

myTensor[0,0]*=5
Run Code Online (Sandbox Code Playgroud)

输出:

tensor([[50., 10.],
        [10., 10.]])
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不是很好,如果有更好或更完善的解决方案,我将不胜感激。
但是就我目前所知(0.4.1)而言,您将不得不针对具有梯度响应的张量使用此解决方法。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)
Run Code Online (Sandbox Code Playgroud)

但这当然会产生不同的结果:

tensor([[10., 10.],
        [10., 10.]])
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!