张量 是什么
张量这个词听着难,其实是把已经知道的东西穿在一把梯子上的名字。一格 = 就是一个数,标量。排成一行是向量,铺成格子是矩阵,把格子叠成好几层是立方体。需要几个下标,就是阶 (rank)。0 个、1 个、2 个、3 个。两个向量向外相乘的外积 u⊗v = u vᵀ 造出最简单的 rank-1 矩阵,任何矩阵都能由这样的小块叠起来。SVD 就是这件事。矩阵也可以吃进两个向量,吐出一个数,uᵀ M v。一张图像、一捆训练样本,都是张量。梯子一阶一阶地往上爬。格子从点长成线、长成面、长成一块,就是这把梯子。外积的格子是最简单的矩阵,颜色通道叠上去,灰度格子就变成一块。
用按钮把阶一格一格升高。rank 0 是一格,就是一个数。不需要下标来指出位置。rank 1 把格子拉成一行,成为向量,要选哪一格就需要一个下标。rank 2 把行铺成格子,成为矩阵,第几行第几列,下标是两个。rank 3 是把格子叠成好几层的立方体,下标是三个。阶就是下标轴的个数,一眼能看见。形状也一起长,从点到线,从线到面,从面到体积。张量不是新怪物,是把知道的东西立在同一把梯子上的名字。
把两个向量向外相乘,造出矩阵。用滑块把 u = (u1, u2) 放在左边竖着,把 v = (v1, v2) 放在上边横着,格子 (i, j) 里就是 ui · vj。也就是 u⊗v = u vᵀ。左边的值乘上边的值,是那一格的数,格子按数值涂深涂浅。把 u 调大,整行变大。把 v 调大,整列变大。无论怎么转,这个矩阵的秩始终是 1。每一行都是 u 的倍数,每一列都是 v 的倍数,独立方向只有一个。外积是最简单的矩阵,rank-1 的砖。
普通的矩阵是把好几块 rank-1 的砖叠起来。用按钮一层一层加。第 1 层只有第一块 σ1·u1·v1ᵀ,只粗粗摹出目标矩阵的大轮廓。加上第 2 层,σ2·u2·v2ᵀ 补上剩下的差,和就对准目标。画面把现在重建的矩阵和目标并排放着,也把两者之差写成数。这就是 SVD 的核心。任何矩阵都是 A = Σ σk uk vkᵀ,也就是 rank-1 小块之和,只留下最大的几个 σ,形状也差不多还在。压缩从这里来。
矩阵也可以不当变换,而当成吃两个向量的机器。在固定矩阵 M 的左边放 u、右边放 v,就出来一个数,那是 uᵀ M v。这就是 rank 2 张量,矩阵接受两个向量、吐出一个标量的双线性形式。在坐标平面上拖动 u 和 v 的箭头,下方数字板立刻写出 uᵀ M v。固定一边、只把另一边加大,结果也按同样的倍数变大。对两个自变量各自线性,所以是双线性。量长度的内积、能量 ½ xᵀ K x、曲率、应力,凡是吃两个方向、给出一个数的量,都在这个框里。
最后看张量为什么是机器学习的基本容器。用按钮一根轴一根轴地加。一张灰度图像是像素亮度的格子,也就是矩阵 [H, W],rank 2。加上颜色,红、绿、蓝三个通道叠成立方体 [H, W, 3],rank 3。一次学习好几张,就把这个立方体重叠 N 个,成为 [N, H, W, 3],rank 4。画面在每加一根轴时,一起显示形状的名字和格子怎样叠。张量不是装饰,是把数据的好几根轴装进一个容器的实用容器。深度学习框架的名字里有 Tensor,原因在这里。