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^nR^nu 映射,其中 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]

这些是 xdxddx 的输出:

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正在计算xelement-wise.

的梯度

我是否应该将计算视为从 R^n 到 R^n 的 u 映射,其中 n 是我的批处理的大小?

我的回答是否定的,否则dx应该是雅可比矩阵而不是向量。

这对 u' 很有效,但 u'' 到处都是零

鉴于上下文有限,我唯一能想到的是model(x)关于x的二阶导数为零。