从程序员的角度来看矩阵乘法
翻译小组成员介绍: Alex
Alex,英语爱好者,现工作于洛阳
翻译小组成员介绍: 向海飞
武汉市人,2002年华中理工大学应用电子技术专业本科毕业。现在洛阳工作。
文章: betterexplained.com/articles/matrix-multiplication/
译者: Alex 校对: 向海飞 版面: 公理
程序员看矩阵乘法
A Programmer's Intuition for Matrix Multiplication
矩阵乘法意义何在?常人的直觉是:
1)矩阵乘法缩放/旋转/扭曲几何图形
初学向量时,会觉得矩阵乘法是一种强有力的工具:向量与矩阵相乘,产生新向量。遗憾的是,这可能会使得思维过分依赖形象化。
20个家庭参加烧烤派对,如何估算热狗数量?(嗯...20个家庭,每个家庭3个人,每个人2个热狗...20*3*2=120个热狗。)
你可能不会考虑建一个“受邀家庭-家庭人数-食量”的三维矩阵。如果仅为处理数据,相比多维向量,我更习惯使用多维矩阵。
2)矩阵乘法构成线性运算
技术上的准确定义是:矩阵相乘产生新矩阵;新矩阵可视为两个原函数的复合函数。然而,有时参与运算的矩阵不是线性算子,而是一组矢量或数据点集。为此我们需要另一种直觉来体会其中的意涵。
我待会就从程序员视角解读矩阵乘法。
3)矩阵乘法与信息流有关,它将数据转换成代码,或者反之。
我把线性代数看做是“数学表格”:
我们将信息存储在各种电子表格中(“矩阵”);
部分数据被视为函数,另外可以当做数据点集;
我们的视角会从不同的上下文来变化;
有时我会把数据看作几何向量,有时我会把矩阵看作复合函数。但我更多的是考虑信息在分析系统中的流动。(有些纯粹主义者不愿意漂亮的代数结构堕落成乏味的电子表格,但对此我毫不介意。)
程序员直觉:代码即数据,数据即代码
Programmer's Intuition: Code Is Data Is Code
就线性代数而言, 以原始信息"3 4 5"为例。可依其书写形式,将它视为向量(vector, 下图右部)或视为函数(function, 下图左部所示):
标准解释
依惯例,纵列为向量(上图右),横列视为函数(上图左):
[3; 4; 5]是指 x = (3, 4, 5)。x 为向量(行间以分号;区分)
[3 4 5]是指f(a, b, c) = 3a + 4b + 5c,一个三输入参数单个输出结果的函数。
提示:代码即数据,数据即代码
代码与数据等价
水平形式的那个三元函数(三维行向量)等同于3个一维向量. 而垂直的1 个三维列向量等同于3个一元函数(每个函数可以传入一个参数)。
简而言之:依据目标输出,确定数据和代码的组合顺序。
矩阵转置
The Matrix Transpose
矩阵转置运算会交换行和列。例如:
若 x 是三维列向量([3; 4; 5]),则 x' 为:
1个三元函数([3 4 5])
x' 虽仍为向量,但已成为三个独立的个体。矩阵的转置运算将向量“劈”开了。
同理,若f = [3 4 5]为行向量,则f' 为:
1个列向量。
f' 被分成3个一元函数。
实际应用:
x' * x是指把向量 x 当做参数输入函数 x' 中,得到是点积后的结果。换言之,数据被应用于自身。
x * x' 是指一个单独数据 x' 输入到一组函数集 x 中,结果会输出一个网格。数据作用在函数之上,对应形成网格上的点。这里,数据被应用于自身所有排列之上。
应用直觉
Putting The Intuition To Use
唷!这对我们有什么帮助?下例中的式子来自机器学习中线性回顾章节(很快[遇见翻译小组]会介绍此部分):
程序员的初步印象:上式中,参数集 θ' 被视为函数,输入参数 x,得一单值结果。
再比如另外一个复杂推导结果如下所示:
上式难理解,是因为数据被以行向量(而非列向量)的形式存储于矩阵之中。但程序员总是有办法。利用矩阵转置,我们可以判断输出何时为单个数值,何时为“排列网格”。
几何缩放和线性组合各有所长,但是程序员还是喜欢站在“数据信息”的观点来看矩阵。“x 中的信息会视为函数,然后会被传入相应参数。”
简而言之,不要局限于单一直觉。乘法由重复的加法演变而来,可以看出在十进制数中能进行数值缩放,或是虚数可以理解为旋转, 再者积分为计算“面积”,等等。为何矩阵乘法就可以例外呢?
何以解忧,唯有数学!
附录:其他组合
Appendix: What About The Other Combinations?
读者也许会好奇,为什么不用其他组合,例如x x 或者 x' x'。原因很简单,相应的参数个数会对应不上:要么一个三元函数对应1个参数,要么一元函数对应3个参数。
应用直觉
Appendix: Javascript Interpretation
点积 x' x 可以描述为Java语句:
(function(a,b,c){ return 3*a + 4*b + 5*c; })(3,4,5)
定义1个三元函数,并赋予3个参数,返回结果为50。
利用简洁的数学符号,通过Octave/Matlab语言描述如下:
octave:2> [3 4 5] * [3 4 5]'
ans = 50
上式中,[3 4 5]为函数,[3; 4; 5]或者[3 4 5]' 为数据向量。
附录:ADEPT方法
Appendix: ADEPT Method
本文来自于学习TODO的课堂笔记:
TODO:直觉理解 X'X 的含义...直率地讲,该怎么做?
DONE:学习将代码看作数据,数据看作代码。列向量...数据,或者3个函数组成的序列。学习在它们之间自由切换;行向量...三元函数,或者3个数据元素。
所有组合的点积。第一行点乘第一行,第一行点乘第二行,第二行点乘第一行,第二行点乘第二行。
X'X=>自身点积,产生1个1*1矩阵
XX'=>所有组合的点积,产生1个n*n矩阵
作为程序员,我曾想用简洁的语言解释,为什么使用 x' x,而不用 xx' 。现在,我知道答案了。其实原因很简单:使用 x' x,我们可以将信息看作一个函数,并输入该信息作为函数的参数。(完)
「予人玫瑰, 手留余香」感谢支持遇见!