torch.autograd.functional.hessian¶
- torch.autograd.functional.hessian(func, inputs, create_graph=False, strict=False, vectorize=False, outer_jacobian_strategy='reverse-mode')[source][source]¶
计算给定标量函数的 Hessian 矩阵。
- 参数
func (function) – 一个 Python 函数,接受 Tensor 输入并返回一个包含单个元素的 Tensor。
create_graph (bool, optional) – 如果为
True
,Hessian 矩阵将以可微分的方式计算。请注意,当strict
为False
时,结果不能要求梯度或与输入断开连接。默认为False
。strict (bool, optional) – 如果为
True
,当我们检测到存在一个输入,使得所有输出都独立于它时,将引发错误。 如果为False
,对于所述输入,我们返回一个零张量作为 Hessian 矩阵,这是预期的数学值。默认为False
。vectorize (bool, optional) – 此功能为实验性功能。如果您正在寻找实验性较低且性能更高的功能,请考虑使用
torch.func.hessian()
。 当计算 Hessian 矩阵时,通常我们为 Hessian 矩阵的每一行调用一次autograd.grad
。如果此标志为True
,我们使用 vmap 原型功能作为后端来向量化对autograd.grad
的调用,因此我们只调用一次而不是每行调用一次。这应该会在许多用例中带来性能提升,但是,由于此功能尚不完善,可能存在性能悬崖。请使用 torch._C._debug_only_display_vmap_fallback_warnings(True) 来显示任何性能警告,如果您的用例存在警告,请向我们提交问题。默认为False
。outer_jacobian_strategy (str, optional) – Hessian 矩阵通过计算 Jacobian 矩阵的 Jacobian 矩阵来计算。内部 Jacobian 矩阵始终以反向模式 AD 计算。将策略设置为
"forward-mode"
或"reverse-mode"
决定了外部 Jacobian 矩阵将使用前向模式还是反向模式 AD 计算。目前,以"forward-mode"
计算外部 Jacobian 矩阵需要vectorized=True
。默认为"reverse-mode"
。
- 返回值
如果只有一个输入,这将是一个包含输入的 Hessian 矩阵的 Tensor。如果是元组,那么 Hessian 矩阵将是一个元组的元组,其中
Hessian[i][j]
将包含第i
个输入和第j
个输入的 Hessian 矩阵,其大小为第i
个输入的大小加上第j
个输入的大小之和。Hessian[i][j]
将具有与相应第i
个输入相同的 dtype 和设备。- 返回类型
Hessian (Tensor 或 tuple of Tensors 元组)
示例
>>> def pow_reducer(x): ... return x.pow(3).sum() >>> inputs = torch.rand(2, 2) >>> hessian(pow_reducer, inputs) tensor([[[[5.2265, 0.0000], [0.0000, 0.0000]], [[0.0000, 4.8221], [0.0000, 0.0000]]], [[[0.0000, 0.0000], [1.9456, 0.0000]], [[0.0000, 0.0000], [0.0000, 3.2550]]]])
>>> hessian(pow_reducer, inputs, create_graph=True) tensor([[[[5.2265, 0.0000], [0.0000, 0.0000]], [[0.0000, 4.8221], [0.0000, 0.0000]]], [[[0.0000, 0.0000], [1.9456, 0.0000]], [[0.0000, 0.0000], [0.0000, 3.2550]]]], grad_fn=<ViewBackward>)
>>> def pow_adder_reducer(x, y): ... return (2 * x.pow(2) + 3 * y.pow(2)).sum() >>> inputs = (torch.rand(2), torch.rand(2)) >>> hessian(pow_adder_reducer, inputs) ((tensor([[4., 0.], [0., 4.]]), tensor([[0., 0.], [0., 0.]])), (tensor([[0., 0.], [0., 0.]]), tensor([[6., 0.], [0., 6.]])))