torch.autograd.functional.hessian¶
- torch.autograd.functional.hessian(func, inputs, create_graph=False, strict=False, vectorize=False, outer_jacobian_strategy='reverse-mode')[原始碼][原始碼]¶
計算給定標量函式的 Hessian 矩陣。
- 引數
func (函式) – 一個接受 Tensor 輸入並返回單個元素的 Tensor 的 Python 函式。
create_graph (bool, 可選) – 如果為
True,將以可微分的方式計算 Hessian 矩陣。請注意,當strict為False時,結果不能需要梯度或與輸入斷開連線。預設為False。strict (bool, 可選) – 如果為
True,當我們檢測到某個輸入使得所有輸出都與其無關時,將引發錯誤。如果為False,我們將返回一個零 Tensor 作為這些輸入的 Hessian 矩陣,這是預期的數學值。預設為False。vectorize (bool, 可選) – 此功能尚處於實驗階段。如果您正在尋找一個更成熟且效能更好的替代方案,請考慮使用
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, 可選) – Hessian 矩陣透過計算 Jacobian 矩陣的 Jacobian 矩陣來獲得。內部 Jacobian 矩陣總是使用反向模式 AD 計算。將 strategy 設定為
"forward-mode"或"reverse-mode"決定外部 Jacobian 矩陣是使用前向模式 AD 還是反向模式 AD 計算。目前,使用"forward-mode"計算外部 Jacobian 矩陣需要設定vectorized=True。預設為"reverse-mode"。
- 返回
如果輸入為單個,則返回一個包含該輸入 Hessian 矩陣的單個 Tensor。如果輸入為一個 tuple,則返回一個 tuple 的 tuple,其中
Hessian[i][j]包含第i個輸入和第j個輸入的 Hessian 矩陣,其大小等於第i個輸入大小與第j個輸入大小之和。Hessian[i][j]的 dtype 和裝置將與對應的第i個輸入相同。- 返回型別
示例
>>> 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.]])))