torch.gradient
- torch.gradient(input, *, spacing=1, dim=None, edge_order=1) → 张量列表
-
使用二阶中心差分法估计函数$g : \mathbb{R}^n \rightarrow \mathbb{R}$在一维或多维中的梯度,并在边界处采用一阶或二阶的近似值。
$g$ 的梯度是通过样本进行估计的。默认情况下,如果没有指定
spacing
参数,那么样本完全由input
描述,并且输入坐标的映射到输出与张量索引到值的映射相同。例如,对于一个三维的input
,描述的函数是 $g : \mathbb{R}^3 \rightarrow \mathbb{R}$,并且 $g(1, 2, 3) == input[1, 2, 3]$。当指定
spacing
时,它会改变input
和输入坐标的关联关系。这部分内容在下方的“关键字参数”小节中进行了详细介绍。梯度是通过独立估计$g$的每个偏导数来计算的。如果$g$属于$C^3$空间(即至少有三个连续的导数),这种估计是准确的,并且可以通过提供更接近的样本点来提高精度。从数学上讲,每个偏导数内部点处的值可以使用泰勒定理带余项进行估算。设$x$为一个内部点,并且>x-h_l$和$x+h_r$分别为其左侧和右侧的相邻点,$f(x+h_r)$ 和 $f(x-h_l)$ 可以通过以下方式估算:
$\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}$利用$f \in C^3$这一事实,并通过求解线性系统,我们得出:
$f'(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 : \mathbb{C}^n \rightarrow \mathbb{C}$ 的梯度。
每个偏导数在边界点的计算方法不同。详见下文的 edge_order。
- 参数
-
input (
Tensor
) – 表示函数值的张量 - 关键字参数
-
-
spacing (
标量
,标量列表
,张量列表
, 可选) – 参数spacing
用于调整输入张量的索引与采样坐标的关联方式。如果spacing
是一个标量,那么索引将乘以该标量来生成坐标。例如,当spacing=2
时,索引 (1, 2, 3) 变为坐标 (2, 4, 6)。如果spacing
是一个标量列表,则相应的索引将分别乘以这些标量。例如,当spacing=(2, -1, 3)
时,索引 (1, 2, 3) 变为坐标 (2, -2, 9)。最后,如果spacing
是一维张量列表,则每个张量指定相应维度的坐标值。例如,当索引是 (1, 2, 3),而张量分别是 (t0, t1, t2) 时,坐标为 (t0[1], t1[2], t2[3])。 -
dim (
int
,list of int
, 可选) – 要近似梯度的维度。默认情况下,会计算每个维度上的偏导数。注意,当指定dim
时,spacing
参数中的元素必须与指定的维度相对应。 -
edge_order (
int
, optional) – 1 或 2,分别表示使用 一阶 或 二阶 方法来估计边界(“边缘”)值。
-
示例:
>>> # Estimates the gradient of f(x)=x^2 at points [-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.]),) >>> # Estimates the gradient of the R^2 -> R function whose samples are >>> # described by the tensor t. Implicit coordinates are [0, 1] for the outermost >>> # dimension and [0, 1, 2, 3] for the innermost dimension, and function estimates >>> # partial derivative for both dimensions. >>> 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]])) >>> # A scalar value for spacing modifies the relationship between tensor indices >>> # and input coordinates by multiplying the indices to find the >>> # coordinates. For example, below the indices of the innermost >>> # 0, 1, 2, 3 translate to coordinates of [0, 2, 4, 6], and the indices of >>> # the outermost dimension 0, 1 translate to coordinates of [0, 2]. >>> torch.gradient(t, spacing = 2.0) # dim = None (implicitly [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]])) >>> # doubling the spacing between samples halves the estimated partial gradients. >>> >>> # Estimates only the partial derivative for dimension 1 >>> torch.gradient(t, dim = 1) # spacing = None (implicitly 1.) (tensor([[ 1.0000, 1.5000, 3.0000, 4.0000], [10.0000, 15.0000, 30.0000, 40.0000]]),) >>> # When spacing is a list of scalars, the relationship between the tensor >>> # indices and input coordinates changes based on dimension. >>> # For example, below, the indices of the innermost dimension 0, 1, 2, 3 translate >>> # to coordinates of [0, 3, 6, 9], and the indices of the outermost dimension >>> # 0, 1 translate to coordinates of [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]])) >>> # The following example is a replication of the previous one with explicit >>> # coordinates. >>> 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]]))