pytorch autograd.grad的内部工作,用于内部导数



考虑以下代码:

x = torch.tensor(2.0, requires_grad=True)
y = torch.square(x)
grad = autograd.grad(y, x)
x = x + grad[0]
y = torch.square(x)
grad2 = autograd.grad(y, x)

首先,我们有∇(x^2)=2x。据我所知,grad2=∇((x + ∇(x^2))^2)=∇((x+2x)^2)=∇((3x)^2)=9∇x^2=18x。不出所料,grad=4.0=2x,但grad2=12.0=6x,我不明白它是从哪里来的。感觉3来自我的表达式,但它不是平方的,2来自传统的导数。有人能帮我理解为什么会发生这种事吗?此外,存储梯度的计算图可以追溯到多远?

具体来说,我是从元学习的角度出发的,其中人们对计算以下形式的量∇ L(theta - alpha * ∇ L(theta))=(1 + ∇^2 L(theta)) ∇L(theta - alpha * ∇ L(theta)感兴趣(这里的导数是关于theta的(。因此,我们称之为A的计算包括一个二阶导数。计算与下面的∇_{theta - alpha ∇ L(theta)}L(theta - alpha * ∇ L(theta))=∇_beta L(beta)非常不同,我将其称为B

希望我能清楚地看到我的片段与我在第二段中描述的内容之间的关系。我的总体问题是:pytorch在什么情况下使用autograd.grad实现计算A与计算B?如果能对autograd如何处理此特定案例的技术详细信息做出任何解释,我将不胜感激。

PD。我遵循的原始代码让我怀疑这是在这里;特别是第69到106行,以及随后的第193行,当它们使用autograd.grad时。因为代码更不清楚,因为他们做了很多model.clone()等等

如果这个问题有任何不清楚的地方,请告诉我。

我做了一些更改:

  1. 我不确定torch.rand(2.0)应该做什么。根据文本,我只是将其设置为2
  2. 添加了一个中间变量z,这样我们就可以计算原始变量的梯度w.r.t。您的被覆盖
  3. 设置create_graph=True以计算更高阶梯度。看见https://pytorch.org/docs/stable/generated/torch.autograd.grad.html
import torch
from torch import autograd
x = torch.ones(1, requires_grad=True)*2
y = torch.square(x)
grad = autograd.grad(y, x, create_graph=True)
z = x + grad[0]
y = torch.square(z)
grad2 = autograd.grad(y, x)
# yours is more like autograd.grad(y, z)
print(x)
print(grad)
print(grad2)

最新更新