我无法采用以下函数的二阶导数。当我想要关于u_s的二阶导数时,它可以工作,但是对于x_s,则不起作用。
有人知道我在这里做错了吗?
def cost(xt, x_goal, u, Q, R):
return (xt - x_goal).matmul(Q).matmul((xt - x_goal).transpose(0,1)) + u.matmul(R).matmul(u)
x_s = tr.tensor([ 0.0000, -1.0000, 0.0000], dtype=torch.float64, requires_grad=True)
u_s = tr.tensor([-0.2749], dtype=torch.float64, requires_grad=True)
c = cost(x_s, x_Goal, u_s, tr.tensor(Q), tr.tensor(R))
c
output:
tensor([[4.0076]], dtype=torch.float64, grad_fn=<ThAddBackward>)
Cu = grad(c, u_s, create_graph=True)[0]
Cu
output:
tensor([-0.0550], dtype=torch.float64, grad_fn=<ThAddBackward>)
Cuu = grad(Cu, u_s, allow_unused=True)[0]
Cuu
output:
tensor([0.2000], dtype=torch.float64)
Cux = grad(Cu, x_s, allow_unused=True)
Cux
output:
(None,)
我猜测Cu本身完全独立于x_s,但是导数至少应为零,而不是无!
答案 0 :(得分:2)
您没有做错任何事情。
假设我有变量x
,y
和z=f(y)
。如果我计算z.backward(),然后尝试询问相对于x的梯度,则会得到None
。例如,
import torch
x = torch.randn(1,requires_grad=True)
y = torch.randn(1,requires_grad=True)
z = y**2
z.backward()
print(y.grad) # Outputs some non-zero tensor
print(x.grad) # None
那么,这与您尝试计算二阶导数Cux
有什么关系?当您编写create_graph=True
时,PyTorch会跟踪计算Cu
的导数计算中的所有运算,并且由于导数本身是由基本运算组成的,因此您可以计算渐变的梯度,如下所示:你在做。这里的问题是,梯度Cu
从未遇到变量x_s
,所以有效地Cu = f(u_s)
。这意味着当执行Cu.backward()
时,Cu
的计算图将永远不会看到变量x_s
,因此它的渐变类型仍为None
,就像上面的示例一样。 / p>