PyTorch 二阶导数处处为零
PyTorch second derivative is zero everywhere
我正在研究一个自定义损失函数,它需要我计算神经网络的 Hessian 矩阵相对于其输入的轨迹。
在一维中,这减少到网络相对于其输入的二阶导数。假设我的网络是u
,我的输入是x
。这个问题完全是一维的,所以我要建模的关系是 u(x)
,其中 u
有一个输入和一个输出,而 x
是一维的。但是,我是 运行 个批次,所以 x
作为列向量“进来”,我期望列向量作为输出。
如果我们将批次中的样本标记为 x_1, x_2, ..., x_n
,那么我对以下向量感兴趣:
在 PyTorch 中,我尝试了以下方法:
u = model(x)
d = grad(u, x, grad_outputs=torch.ones_like(u), create_graph=True)[0]
dd = grad(d, x, grad_outputs=torch.ones_like(d), retain_graph=True, create_graph=False)[0]
这对 u' 很有效,但 u'' 到处都是零:
我对这里首先需要矢量雅可比积的整个概念感到有点困惑。我是否应该将计算视为从 R^n
到 R^n
的 u
映射,其中 n
是我的批处理的大小?
感谢任何帮助!
玩具示例
我已尝试为您设计一个玩具示例:
x = torch.rand(3, requires_grad=True).reshape(-1, 1)
u = x ** 2.
# du/dx = 2 * x
dx = torch.autograd.grad(u, x, torch.ones_like(u), retain_graph=True, create_graph=True)[0]
# d^2 u/dx^2 = 2
ddx = torch.autograd.grad(dx, x, torch.ones_like(u))[0]
这些是 x
、dx
、ddx
的输出:
tensor([[0.5217],
[0.0400],
[0.5509]], grad_fn=<ReshapeAliasBackward0>)
tensor([[1.0434],
[0.0800],
[1.1018]], grad_fn=<MulBackward0>)
tensor([[2.],
[2.],
[2.]])
所以grad
正在计算x
element-wise.
的梯度
我是否应该将计算视为从 R^n 到 R^n 的 u 映射,其中 n 是我的批处理的大小?
我的回答是否定的,否则dx
应该是雅可比矩阵而不是向量。
这对 u' 很有效,但 u'' 到处都是零
鉴于上下文有限,我唯一能想到的是model(x)
关于x
的二阶导数为零。
我正在研究一个自定义损失函数,它需要我计算神经网络的 Hessian 矩阵相对于其输入的轨迹。
在一维中,这减少到网络相对于其输入的二阶导数。假设我的网络是u
,我的输入是x
。这个问题完全是一维的,所以我要建模的关系是 u(x)
,其中 u
有一个输入和一个输出,而 x
是一维的。但是,我是 运行 个批次,所以 x
作为列向量“进来”,我期望列向量作为输出。
如果我们将批次中的样本标记为 x_1, x_2, ..., x_n
,那么我对以下向量感兴趣:
在 PyTorch 中,我尝试了以下方法:
u = model(x)
d = grad(u, x, grad_outputs=torch.ones_like(u), create_graph=True)[0]
dd = grad(d, x, grad_outputs=torch.ones_like(d), retain_graph=True, create_graph=False)[0]
这对 u' 很有效,但 u'' 到处都是零:
我对这里首先需要矢量雅可比积的整个概念感到有点困惑。我是否应该将计算视为从 R^n
到 R^n
的 u
映射,其中 n
是我的批处理的大小?
感谢任何帮助!
玩具示例
我已尝试为您设计一个玩具示例:
x = torch.rand(3, requires_grad=True).reshape(-1, 1)
u = x ** 2.
# du/dx = 2 * x
dx = torch.autograd.grad(u, x, torch.ones_like(u), retain_graph=True, create_graph=True)[0]
# d^2 u/dx^2 = 2
ddx = torch.autograd.grad(dx, x, torch.ones_like(u))[0]
这些是 x
、dx
、ddx
的输出:
tensor([[0.5217],
[0.0400],
[0.5509]], grad_fn=<ReshapeAliasBackward0>)
tensor([[1.0434],
[0.0800],
[1.1018]], grad_fn=<MulBackward0>)
tensor([[2.],
[2.],
[2.]])
所以grad
正在计算x
element-wise.
我是否应该将计算视为从 R^n 到 R^n 的 u 映射,其中 n 是我的批处理的大小?
我的回答是否定的,否则dx
应该是雅可比矩阵而不是向量。
这对 u' 很有效,但 u'' 到处都是零
鉴于上下文有限,我唯一能想到的是model(x)
关于x
的二阶导数为零。