程序员对矩阵乘法(Matrix Multiplication)的直觉理解

矩阵乘法是什么意思?这里有几种理解方式 常见直觉:

1) 矩阵乘法缩放/旋转/扭曲一个几何平面。

matrix intuition

这在初学向量时很有用:向量输入,新向量输出。不幸的是,这可能导致过度依赖几何可视化。

如果有20个家庭来参加你的烧烤,你如何估算需要的热狗数量?(嗯…20个家庭,就算每个家庭3人,每人2个热狗…大约20 * 3 * 2 = 120个热狗。)

你可能不会想“哦,我需要一个邀请-家庭规模-饥饿棱柱的体积!”。处理大型矩阵时,我不会去想500维向量,只把它们看作待修改的数据。

2) 矩阵乘法组合线性操作。

这是技术上准确的定义:是的,矩阵乘法产生一个新矩阵,它组合了原始的函数。然而,有时被操作的矩阵并不是一个线性运算,而是一组向量或数据点。我们需要另一种直觉来理解正在发生的事情。

我来提出一个程序员的视角:

3) 矩阵乘法关乎信息流,将数据转换为代码再转换回来。

matrix pour

我把线性代数看作“数学电子表格”(如果你是线性代数新手, 阅读引言):

  • 我们将信息存储在各种电子表格("矩阵")中
  • 有些数据被视为应用的函数,有些则被视为使用的数据点。
  • 我们可以根据需要,在向量解释和函数解释之间切换。

有时我把数据视为几何向量,有时我把矩阵看作组合函数。但大多数时候,我考虑的是信息在系统中流动。(有些纯粹主义者对将优美的代数结构简化为乏味的电子表格感到畏缩;我晚上睡得很好。)

程序员的直觉:Code is Data is Code

以你最喜欢的食谱为例。如果你把文字解释为 指令,你会得到一个馅饼、松饼、蛋糕等。

如果你把文字解释为 数据,文本就是可以调整的散文:

  • 将测量值转换为公制单位。
  • 因过敏更换食材。
  • 针对海拔或不同设备进行调整。

结果是一个新食谱,可以进一步调整,或者作为指令来制作不同的馅饼、松饼、蛋糕等。(编译器将程序视为文本,修改它,最终输出“指令”——这些指令又可以是另一层的文本。)

这就是线性代数。我们获取原始信息如“3 4 5”,根据其书写方式将其视为向量或函数:

operation and data

按照惯例,垂直列通常是向量,水平行通常是函数:

  • [3; 4; 5] 表示 x = (3, 4, 5). 这里, x 是一个数据向量(我使用 ; 来分隔每一行)。
  • [3 4 5] 表示 f(a, b, c) = 3a + 4b + 5c. 这是一个接受三个输入并返回一个结果的函数。

而顿悟时刻:数据即代码,代码即数据!

code and data are equivalent

包含水平函数的行实际上可以是三个数据点(每个点只有一个元素)。数据的垂直列实际上可以是三个不同的函数,每个函数接受一个参数。

啊。这变得简洁了:根据期望的结果,我们可以以不同的顺序组合数据和代码。

矩阵转置(Matrix Transpose)

矩阵转置交换行和列。以下是它在实践中的含义。

如果 x 是一个有3个元素的列向量([3; 4; 5]),那么 x' 是:

  • 一个接受3个参数的函数([3 4 5])
  • x' 仍然可以保持为一个数据向量,但作为三个独立的条目。转置"将其拆分"。

类似地,如果 f = [3 4 5] 是我们的行向量,那么 f' 可以表示:

  • 一个单独的数据向量,位于垂直列中。
  • f' 被分离成三个函数(每个接受单个输入)。

让我们在实践中使用它。

当我们看到 x' * x 我们意思是: x' (作为一个单一函数)作用于 x (一个单一向量)。结果是 点积(dot product) (了解更多)。换句话说,我们将数据应用于自身。

x transform linear algebra

当我们看到 x * x' 我们意思是 x (作为一组函数)作用于 x' (一组单独的数据点)。结果是一个网格,其中我们将每个函数应用于每个数据点。在这里,我们以所有可能的排列方式将数据与自身混合。

x transpose linear algebra

我认为 xx 重写为 x(x)。它是“函数 x”作用于“向量 x”。(这有助于计算 协方差矩阵,一种衡量数据中自相似性的指标。)

应用直觉

呼!这如何帮助我们?当我们看到像这样的方程时(来自 机器学习课程):

\displaystyle{\[h_{\theta}(x)=\theta^Tx\] }

我现在立刻就能感受到发生了什么。在第一个方程中,我们将 $\theta$(通常是一组数据参数)视为一个函数,并将 $x$ 作为参数传入。这应该给我们一个单一的值。

更多 复杂推导 像这样:

\displaystyle{\[\theta=(X^TX)^{-1}X^Ty\]}

可以逐步推导出来。在某些情况下,这会变得棘手,因为我们将数据存储为矩阵中的行(而不是列),但现在我有更好的工具来跟上。你可以开始估计何时会得到一个单一的值,何时会得到一个“置换网格”作为结果。

几何缩放和线性组合有其用武之地,但在这里我想思考信息。“x中的信息正在变成一个函数,我们将自身作为参数传入。”

长话短说,不要局限于一种直觉。乘法从重复加法演变为缩放(小数),再到旋转(虚数),再到将一个数“应用”到另一个数(积分),以此类推。对于矩阵乘法不也一样吗?

数学愉快。

附录:其他组合呢?

你可能好奇为什么我们不能使用其他组合,比如 x x 或者 x' x'。简单来说,参数不匹配:我们会有期望3个输入的函数只被传入一个参数,或者期望单一输入的函数被传入3个。

附录:Javascript Interpretation

点积(Dot Product) x' * x 可以看作以下javascript命令:

((x, y, z) => x*3 + y*4 + z*5)(3, 4, 5)

我们定义一个具有3个参数的匿名函数(Anonymous Function),并立即传入3个参数。这返回50(点积: 3*3 + 4*4 + 5*5 = 50).

数学符号非常紧凑,所以我们只需(在Octave/Matlab中)写:

octave:2> [3 4 5] * [3 4 5]' ans = 50

记住 [3 4 5] 是函数, [3; 4; 5] 或者 [3 4 5]' 是我们如何写数据向量的方式。

附录:ADEPT Method

这篇文章源于我TODO中的一个 机器学习课堂笔记 使用 ADEPT方法:

我想用通俗的英文向自己解释——为什么我们要 x' x 而不是反过来。现在,用通俗英语来说:我们将信息视为一个函数(Function),并将相同的信息作为参数(Parameter)传递。

本系列其他文章

  1. 虚数(Imaginary Numbers)的直观可视化指南
  2. 复数的直观算术
  3. 理解复数乘法为何成立
  4. 角度、度数与弧度(Radians)的直观指南
  5. 欧拉公式(Euler's Formula)的直观理解
  6. 傅里叶变换(Fourier Transform)的交互式指南
  7. 卷积(Convolution)的直观指南
  8. 正弦波(Sine Waves)的直观理解
  9. 线性代数(Linear Algebra)直观指南
  10. 程序员对矩阵乘法(Matrix Multiplication)的直觉
  11. 虚数乘法 vs. 虚数指数
  12. 双曲函数(Hyperbolic Functions)的直观指南

加入 45 万月度读者

喜欢这篇文章?还有更多内容能帮你建立持久、直观的数学理解。加入通讯以获取额外内容和最新更新。