Shortcuts

torch.gradient

torch.gradient(input, *, spacing=1, dim=None, edge_order=1) List of Tensors

使用二阶精确中心差分法和边界处的一阶或二阶估计,估计函数g:RnRg : \mathbb{R}^n \rightarrow \mathbb{R}在 一个或多个维度上的梯度。

使用样本估计gg的梯度。默认情况下,当未指定spacing时,样本完全由input描述,输入坐标到输出的映射与张量索引到值的映射相同。例如,对于三维的input,所描述的函数是g:R3Rg : \mathbb{R}^3 \rightarrow \mathbb{R},并且g(1,2,3) ==input[1,2,3]g(1, 2, 3)\ == input[1, 2, 3]

当指定spacing时,它会修改input和输入坐标之间的关系。 这在下面的“关键字参数”部分中有详细说明。

梯度是通过独立估计gg的每个偏导数来估计的。如果ggC3C^3(它至少有3阶连续导数),并且可以通过提供更接近的样本来改进估计。数学上,每个内点处的偏导数值是使用泰勒定理带余项来估计的。 设xx为内点,且xhlx-h_lx+hrx+h_r分别为左右相邻的点,f(x+hr)f(x+h_r)f(xhl)f(x-h_l)可以使用以下方法估计:

f(x+hr)=f(x)+hrf(x)+hr2f(x)2+hr3f(ξ1)6,ξ1(x,x+hr)f(xhl)=f(x)hlf(x)+hl2f(x)2hl3f(ξ2)6,ξ2(x,xhl)\begin{aligned} f(x+h_r) = f(x) + h_r f'(x) + {h_r}^2 \frac{f''(x)}{2} + {h_r}^3 \frac{f'''(\xi_1)}{6}, \xi_1 \in (x, x+h_r) \\ f(x-h_l) = f(x) - h_l f'(x) + {h_l}^2 \frac{f''(x)}{2} - {h_l}^3 \frac{f'''(\xi_2)}{6}, \xi_2 \in (x, x-h_l) \\ \end{aligned}

利用fC3f \in C^3 的事实并求解线性系统,我们推导出:

f(x)hl2f(x+hr)hr2f(xhl)+(hr2hl2)f(x)hrhl2+hr2hlf'(x) \approx \frac{ {h_l}^2 f(x+h_r) - {h_r}^2 f(x-h_l) + ({h_r}^2-{h_l}^2 ) f(x) }{ {h_r} {h_l}^2 + {h_r}^2 {h_l} }

注意

我们估计复数域中函数的梯度 g:CnCg : \mathbb{C}^n \rightarrow \mathbb{C} 的方式相同。

在边界点处,每个偏导数的值以不同的方式计算。请参见下面的 edge_order。

Parameters

输入 (Tensor) – 表示函数值的张量

Keyword Arguments
  • 间距 (标量, 标量列表, 张量列表, 可选) – 间距 可以用来修改 输入 张量的索引如何与样本坐标相关联。如果 间距 是一个标量,那么 索引将乘以该标量以生成坐标。例如,如果 间距=2, 索引 (1, 2, 3) 变为坐标 (2, 4, 6)。如果 间距 是一个标量列表,那么相应的 索引将被乘以。例如,如果 间距=(2, -1, 3),索引 (1, 2, 3) 变为坐标 (2, -2, 9)。 最后,如果 间距 是一个一维张量列表,那么每个张量指定 相应维度的坐标。例如,如果索引是 (1, 2, 3) 并且张量是 (t0, t1, t2),那么 坐标是 (t0[1], t1[2], t2[3])

  • dim (int, list of int, 可选) – 要近似梯度的维度或多个维度。默认情况下,计算每个维度的偏导数。请注意,当指定了dim时,spacing参数的元素必须与指定的维度相对应。”

  • edge_order (int, 可选) – 1 或 2,分别用于一阶二阶 边界(“边缘”)值的估计。

示例:

>>> # 估计f(x)=x^2在点[-2, -1, 2, 4]处的梯度
>>> coordinates = (torch.tensor([-2., -1., 1., 4.]),)
>>> values = torch.tensor([4., 1., 1., 16.], )
>>> torch.gradient(values, spacing = coordinates)
(tensor([-3., -2., 2., 5.]),)

>>> # 估计R^2 -> R函数的梯度,其样本由张量t描述。最外层维度的隐式坐标为[0, 1],
>>> # 最内层维度的隐式坐标为[0, 1, 2, 3],并估计两个维度的偏导数。
>>> t = torch.tensor([[1, 2, 4, 8], [10, 20, 40, 80]])
>>> torch.gradient(t)
(tensor([[ 9., 18., 36., 72.],
         [ 9., 18., 36., 72.]]),
 tensor([[ 1.0000, 1.5000, 3.0000, 4.0000],
         [10.0000, 15.0000, 30.0000, 40.0000]]))

>>> # 间距的标量值通过乘以索引来修改张量索引与输入坐标之间的关系,以找到坐标。
>>> # 例如,下面最内层维度的索引0, 1, 2, 3转换为坐标[0, 2, 4, 6],
>>> # 最外层维度的索引0, 1转换为坐标[0, 2]。
>>> torch.gradient(t, spacing = 2.0) # dim = None (隐式为[0, 1])
(tensor([[ 4.5000, 9.0000, 18.0000, 36.0000],
          [ 4.5000, 9.0000, 18.0000, 36.0000]]),
 tensor([[ 0.5000, 0.7500, 1.5000, 2.0000],
          [ 5.0000, 7.5000, 15.0000, 20.0000]]))
>>> # 将样本之间的间距加倍会使估计的偏导数减半。

>>>
>>> # 仅估计维度1的偏导数
>>> torch.gradient(t, dim = 1) # spacing = None (隐式为1.)
(tensor([[ 1.0000, 1.5000, 3.0000, 4.0000],
         [10.0000, 15.0000, 30.0000, 40.0000]]),)

>>> # 当间距是标量列表时,张量索引与输入坐标之间的关系会根据维度变化。
>>> # 例如,下面最内层维度的索引0, 1, 2, 3转换为坐标[0, 3, 6, 9],
>>> # 最外层维度的索引0, 1转换为坐标[0, 2]。
>>> torch.gradient(t, spacing = [3., 2.])
(tensor([[ 4.5000, 9.0000, 18.0000, 36.0000],
         [ 4.5000, 9.0000, 18.0000, 36.0000]]),
 tensor([[ 0.3333, 0.5000, 1.0000, 1.3333],
         [ 3.3333, 5.0000, 10.0000, 13.3333]]))

>>> # 以下示例是前一个示例的复制,带有显式坐标。
>>> coords = (torch.tensor([0, 2]), torch.tensor([0, 3, 6, 9]))
>>> torch.gradient(t, spacing = coords)
(tensor([[ 4.5000, 9.0000, 18.0000, 36.0000],
         [ 4.5000, 9.0000, 18.0000, 36.0000]]),
 tensor([[ 0.3333, 0.5000, 1.0000, 1.3333],
         [ 3.3333, 5.0000, 10.0000, 13.3333]]))