尝试理解张量

2026-08-09 20:39:47 创建

2026-08-09 22:19:27 修改

尝试理解张量 (Pytorch)

映射的视角

一个张量是一个从 \(\mathbb{N}^n\) 的有界子集到 \(\mathbb{R}\) 的映射。比如,二维张量

$$\begin{align*}[\,&[a, b],\\ &[c, d]\,]\end{align*}$$

就是从 \(\{0, 1\}\times\{0, 1\}\)\(\mathbb{R}\) 的映射,其中

$$f: \begin{cases} (0, 0) \mapsto a,\\ (0, 1) \mapsto b,\\ (1, 0) \mapsto c,\\ (1, 1) \mapsto d.\\ \end{cases}$$

当尝试“交换”(PyTorch中的 transpose 方法)张量的两个维度时,我们只是在上述映射 \(f\) 中,交换了变量中的两个维度,即

$$f_{\text{transposed}}: \begin{cases} (0, 0) \mapsto a,\\ (1, 0) \mapsto b,\\ (0, 1) \mapsto c,\\ (1, 1) \mapsto d.\\ \end{cases}$$

坐标的视角

一个形状是 \((m, n, k)\) 的张量是一列有序的数,每个数有一个唯一id \(\in\{0,1,\dots,mnk-1\}\)(或许可以称为在内存中的顺序?)。如何获取每一个数的坐标?先用id除以 \(nk\),得到的商(整数)就是第一维的坐标;再用余数除以 \(k\),得到的商就是第二维的坐标;最后剩下的余数就是第三维的坐标。

当变换张量的形状(PyTorch中的 reshape)为 \((m', n', k')\) 时,我们可以按照同样的方式得到新的坐标。这种变换,不会改变数据的连续性。

当交换张量的维度顺序时(permute),即是交换通过上述方式中计算出的坐标中的维度顺序。

连续与不连续

根据上述坐标的视角,一个正常的在底层连续的 \(d\) 维张量,若设其维度为 \((m_0,m_1,\dots,m_{d-1})\),则当一坐标的第 \(i\) 维(\(i=1,2,\dots,d\))上的坐标+1时,数据id+

$$\prod_{k=i}^{d-1}m_k$$

即stride。当 \(i=d\) 时,上述连乘结果为1。当交换张量的维度顺序后,stride也会随之交换,因此张量不再连续。