我可以截取在“ backward()”期间计算出的中间梯度值吗?

时间:2019-07-17 15:04:46

标签: pytorch derivative differentiation automatic-differentiation autograd

a ← b ← c的计算图中,我希望独立计算导数?c/?a,?c/?b和?b/?a。

这是我第一次尝试:

import torch as tch

# Leaf tensor.
a = tch.tensor(5., requires_grad=True)
# A few random computations.
b = (6 * a + 42) ** 2 # Intermediate result.
c = -tch.sqrt(b/2.) # Final result.

# Now trying to get derivatives:
c.backward() # Autograd! Glory! :')
a.grad # Expect ?c/?a, is that it? (-4.2426)
b.grad # Expect ?c/?b.. but got nothing :(

那么b.grad为什么为空?我认为?c/?b必须作为?c/?a的中间结果来计算。此中间结果是否存储在任何地方?

我不喜欢的天真的第二种方法:

# Alternative solution.. but it feels wrong.
a = tch.tensor(5., requires_grad=True)
b = (6 * a + 42) ** 2
b.backward() # First half-pass.
b = b.clone().detach().requires_grad_(True) # Useless copy?
c = -tch.sqrt(b/2.)
c.backward() # Second half-pass.
a.grad # Expect ?b/?a, okay? (864.)
b.grad # Expect ?c/?b, okay? (-0.0049)
# How do I get ?c/?a?

一个人可能会说?c/?a=?c/?b*?b/?a,所以我只需要将最后两个结果相乘(事实就是这样)。但是我不确定如果有几个叶节点a0, a1, ..或几个中间节点b0, b1, ..会如何转换。怎么样?

此外,我觉得第二种方法中的克隆/分离/重新连接过程毫无用处,因为autograd已经拥有第一种方法中所需的所有信息。正确吗?

在这种情况下,我能区分?c/?a,?c/?b和?b/?a的最佳方法是什么?

0 个答案:

没有答案