PyTorch中的“ detach()”和“ with torch.nograd()”之间的区别?

时间:2019-06-29 08:47:44

标签: python pytorch

我知道从梯度计算backward中排除计算元素的两种方法

方法1:使用with torch.no_grad()

with torch.no_grad():
    y = reward + gamma * torch.max(net.forward(x))
loss = criterion(net.forward(torch.from_numpy(o)), y)
loss.backward();

方法2:使用.detach()

y = reward + gamma * torch.max(net.forward(x))
loss = criterion(net.forward(torch.from_numpy(o)), y.detach())
loss.backward();

这两者之间有区别吗?两者都有好处/缺点吗?

3 个答案:

答案 0 :(得分:6)

detach()

一个没有detach()的示例:

from torchviz import make_dot
x=torch.ones(2, requires_grad=True)
y=2*x
z=3+x
r=(y+z).sum()    
make_dot(r)

enter image description here

绿色r的最终结果是AD计算图的根,蓝色是叶子张量。

另一个带有detach()的示例:

from torchviz import make_dot
x=torch.ones(2, requires_grad=True)
y=2*x
z=3+x.detach()
r=(y+z).sum()    
make_dot(r)

enter image description here

这与:

from torchviz import make_dot
x=torch.ones(2, requires_grad=True)
y=2*x
z=3+x.data
r=(y+z).sum()    
make_dot(r)

但是,x.data是旧方法(符号),而x.detach()是新方法。

x.detach()

有什么区别
print(x)
print(x.detach())

出局:

tensor([1., 1.], requires_grad=True)
tensor([1., 1.])

因此, x.detach()是删除requires_grad的一种方法,您得到的是一个新的分离的张量(与AD计算图分离)。

torch.no_grad

torch.no_grad实际上是一个类。

x=torch.ones(2, requires_grad=True)
with torch.no_grad():
    y = x * 2
print(y.requires_grad)

出局:

False

来自help(torch.no_grad)

在您确定时,禁用梯度计算对于推断很有用 |您将不会调用:meth:Tensor.backward()。它将减少内存 |否则将具有requires_grad=True的计算的消耗。 |
|在这种模式下,每次计算的结果将具有 | requires_grad=False,即使输入中有requires_grad=True

答案 1 :(得分:2)

tensor.detach()创建一个张量,该张量与不需要grad的张量共享存储。它将输出与计算图分离。因此,不会沿该变量向后传播梯度。

包装器with torch.no_grad()暂时将所有requires_grad标志设置为false。 torch.no_grad说,任何操作都不能建立图形。

区别在于,仅引用一个给定变量对其进行调用。另一个影响with语句中发生的所有操作。另外,torch.no_grad将使用较少的内存,因为它从一开始就知道不需要渐变,因此不需要保留中间结果。

进一步了解它们之间的区别以及here中的示例。

答案 2 :(得分:1)

一个简单而深刻的解释是,with torch.no_grad()的使用就像一个循环,其中写入的所有内容都将requires_grad自变量设置为False,尽管是暂时的。因此,如果您需要停止某些变量或函数的梯度的反向传播,则无需指定任何其他内容。

但是,顾名思义,torch.detach()只是从梯度计算图中分离变量。但这在必须为有限数量的变量或函数(例如)提供本规范时使用。通常,在神经网络训练中,在某个时期结束后显示损失和准确性输出时,因为那一刻,它仅消耗资源,因为在显示结果期间其梯度无关紧要。