如果您甚至想对图形的某些部分进行两次向后的操作,则需要在第一遍中传递keep_graph = True。
但是,我发现以下代码片段实际上没有起作用。我正在使用pyTorch-0.4
x = torch.ones(2, 2, requires_grad=True)
y = x + 2
y.backward(torch.ones(2, 2)) # Note I do not set retain_graph=True
y.backward(torch.ones(2, 2)) # But it can still work!
print x.grad
Run Code Online (Sandbox Code Playgroud)
输出:
tensor([[ 2., 2.],
[ 2., 2.]])
Run Code Online (Sandbox Code Playgroud)
谁能解释?提前致谢!
retain_graph=True在您的情况下
不起作用的原因是您有一个非常简单的图形,该图形可能没有内部中间缓冲区,进而没有缓冲区会被释放,因此无需使用retain_graph=True。
但是,在图形中添加另一种额外的计算时,一切都在变化:
码:
x = torch.ones(2, 2, requires_grad=True)
v = x.pow(3)
y = v + 2
y.backward(torch.ones(2, 2))
print('Backward 1st time w/o retain')
print('x.grad:', x.grad)
print('Backward 2nd time w/o retain')
try:
y.backward(torch.ones(2, 2))
except RuntimeError as err:
print(err)
print('x.grad:', x.grad)
Run Code Online (Sandbox Code Playgroud)
输出:
Backward 1st time w/o retain
x.grad: tensor([[3., 3.],
[3., 3.]])
Backward 2nd time w/o retain
Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.
x.grad: tensor([[3., 3.],
[3., 3.]]).
Run Code Online (Sandbox Code Playgroud)
在这种情况下,v.grad将计算其他内部变量,但torch不存储中间值(中间梯度等),并且retain_graph=False v.grad将在first之后释放它们backward。
因此,如果您想第二次向后传播,则需要指定retain_graph=True“保留”图形。
码:
x = torch.ones(2, 2, requires_grad=True)
v = x.pow(3)
y = v + 2
y.backward(torch.ones(2, 2), retain_graph=True)
print('Backward 1st time w/ retain')
print('x.grad:', x.grad)
print('Backward 2nd time w/ retain')
try:
y.backward(torch.ones(2, 2))
except RuntimeError as err:
print(err)
print('x.grad:', x.grad)
Run Code Online (Sandbox Code Playgroud)
输出:
Backward 1st time w/ retain
x.grad: tensor([[3., 3.],
[3., 3.]])
Backward 2nd time w/ retain
x.grad: tensor([[6., 6.],
[6., 6.]])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
636 次 |
| 最近记录: |