VOL.I · 向量CH 02( 02 , 24 )

向量:一支箭,一列数

问大模型「国王」这个词是什么,它的第一反应不是一段释义,而是一列数:[0.13, −1.22, 0.87, …],整整 4096 个。这列数就是「国王」在模型心里的样子——一个向量。向量是整栋线性代数大厦的原子,也是 AI 世界里一切数据的最终形态:一个词、一张图、一段音频、你的用户画像,进了模型都得先变成向量。这一章我们把这个原子看清楚:它是什么,它能做什么,以及它凭什么能装下「意义」。

向量坐标加法与数乘embedding

同一个词,三种视角

「向量是什么」在不同人嘴里有三种答案,三种都对,而且你需要在三种之间自由切换:

  • 物理系的答案:一支箭。向量是「有方向、有长度」的量。速度、力、位移——箭头指哪儿、多长,就是全部信息。箭头画在哪个位置不重要,重要的只有方向和长度。
  • 计算机系的答案:一列数。向量是一个有序的数字列表,[170, 65, 28]——身高、体重、年龄。顺序不能乱:第一个位置永远是身高,交换两个数就变成了另一个人。
  • 数学系的答案:随便什么,只要守规矩。任何一种对象,只要能定义「相加」和「乘以一个数」,并且满足几条自然的公理,就配叫向量——多项式可以是向量,音频信号可以是向量,甚至函数也可以是向量。

这本书的策略是:用箭头思考,用数列计算,记住抽象定义的存在。箭头给你直觉——它能被画出来、拖动、旋转,你的视觉皮层天生擅长处理它;数列给你可操作性——计算机只认它;抽象定义给你迁移能力——当第 17 章说「一张图片是一个 2304 维向量」时,你不会觉得荒谬。

把箭头和数列钉在一起的,是坐标系。约定所有箭头从原点出发,那么每支箭的箭头尖端落在哪个点,就唯一对应一组坐标。v = (2, 1) 的意思是:从原点出发,沿 x 方向走 2 步,沿 y 方向走 1 步,箭尖钉在那里。箭头 ↔ 数列,从此可以随时互译——这是全书要用两百次的心智动作。

⚠ 坑

「向量就是它的坐标」——这句话差半步。坐标是在某组基下的读数,同一支箭换一套坐标系,读数会完全不同(第 13 章的主题)。现在可以暂时把两者画等号,因为我们始终用标准坐标系;但请在心里留个记号:箭头是客观的,数字是相对的。这个区分在理解 embedding 空间时会突然变得重要。

仅有的两种合法动作

线性代数的「代数」部分,建立在向量仅有的两种基本运算上。只有两种,不会更多了,整栋大厦全靠它们:

加法。数列视角:对应位置相加,(2, 1) + (−1, 1.5) = (1, 2.5),毫无悬念。几何视角有趣得多:把 w 平移到 v 的箭尖,首尾相接,从原点到 w 新箭尖的箭头就是 v + w。或者等价地:以两支箭为邻边张开一个平行四边形,对角线就是和。为什么「对应位置相加」恰好等于「首尾相接」?因为位移可以分解:先走完 v 的水平分量和垂直分量,再走完 w 的——水平方向总共走了 v₁ + w₁,垂直方向总共 v₂ + w₂。代数和几何在这里第一次咬合。

数乘。用一个普通数字 k(线代黑话叫「标量」,scalar,因为它只管缩放 scale)去乘向量:每个分量都乘 k。几何上就是把箭头拉长或压短 k 倍;k 是负数时,箭头调头指向反方向;k = 0 时,箭头塌缩成原点上的一个点——零向量。

减法不算新动作:vw = v + (−1)·w。但它的几何意义值得单独记住:vw 是从 w 的箭尖指向 v 的箭尖的那支箭——「从 w 到 v 还差多少」。这个「差值向量」在 AI 里会客串一个著名角色,第 23 章你会看到 国王 − 男人 + 女人 ≈ 女王 这个魔术,拆开看全是本节的加减法。

向量游乐场:加法与数乘DEMO 01

玩的时候试试这几件事:① 打开「v + w」,拖动任意一支箭,观察平行四边形怎么跟着变;② 把 w 拖到和 v 完全反向,看和向量缩短甚至归零——两个力互相抵消;③ 把滑杆拉到负数,看 v 调头。所有读数里的坐标,和你眼睛看到的箭头,是同一件事的两种记法。

顺带用它验证一下「线性」这个词在第 01 章的定义:先把两支箭加起来再想象整体拉长 2 倍,和先把每支箭各自拉长 2 倍再相加,落点相同——2(v+w) = 2v + 2w。数乘对加法的分配律,在坐标纸上是肉眼可见的。这类「代数恒等式 = 几何事实」的对子,后面每一卷都会出现,它们是线性代数让人上瘾的地方。

4096 维:不要想象,要操作

二维三维的箭头画得出来,那「国王」那个 4096 维向量呢?一个诚实的建议:别试图想象 4096 维空间。人类的视觉系统封顶三维,硬想只会头疼。正确的姿势是数学家的姿势:高维向量就是更长的数列,所有运算照旧按分量进行——加法还是对应位置相加,数乘还是每个分量都乘。你在二维 Demo 里建立的每一条直觉,都通过「按分量」这座桥,原封不动地搬进 4096 维。

高维向量还分两种气质,值得提前认识:稀疏稠密。稀疏向量绝大多数分量是 0,比如用 32000 维向量表示一个词、只在它的编号位置放一个 1(这叫独热编码,第 11 章再会);稠密向量每个分量都有值,embedding 就是典型。AI 发展史的一条暗线就是「从稀疏走向稠密」:稀疏表示里每个维度有明确含义但互相孤立,稠密表示里单个维度没有名字,含义摊在整体的几何关系上——却因此装得下「相似度」。

需要一点想象力时,用「滑杆面板」这个比喻:一个 4096 维向量是一块有 4096 个滑杆的调音台,每个滑杆是一个分量。「国王」是一种滑杆组合,「女王」是另一种,两者大部分滑杆位置相近,少数几个(也许对应「性别」概念的方向)不同。向量加减,就是逐个滑杆做加减。这个比喻不完美,但比「想象高维空间」健康得多。

◆ AI 连接

把对象变成向量,这个动作在 AI 里叫 embedding(嵌入)。词有词向量,句子有句向量,图片、商品、用户、歌曲都有。为什么非要这样?因为一旦万物皆向量,「比较两个东西像不像」就变成了可计算的几何问题(下一章的点积),「组合两种含义」就变成了向量加法,而模型的所有内部操作都可以用矩阵乘法统一表达。Embedding 是「现实世界 → 线性代数世界」的海关,一切数据入境时都在这里换装。顺便说:2013 年的 word2vec 论文发现词向量的加减法居然对应语义类比,是深度学习史上让最多人起鸡皮疙瘩的时刻之一。

▸ Android 类比

向量最贴切的工程对应物是 FloatArray——定长、有序、按下标访问。但语义上更接近一个不可变的值类型:两个向量相等当且仅当所有分量相等,运算返回新值而不改旧值,像 Kotlin 的 data classcopy()。你甚至写过向量而不自知:PointF 是二维向量,Matrix.mapPoints() 里流动的就是它们;RGB 颜色 (r, g, b) 是三维向量,两个颜色的中间色就是向量平均——你早就每天在做向量运算了。

第一个实战:lerp,以及它的高维亲戚

只用加法和数乘,能干什么正经事?能干的第一件正经事,你作为 Android 工程师其实天天在用:线性插值(lerp)。想从位置 v 平滑运动到位置 w,取一个从 0 走到 1 的参数 t,每一帧的位置就是:

p(t) = (1 − t)·v + t·w

t = 0 时纯粹是 v,t = 1 时纯粹是 w,t = 0.5 时是两者的正中点。整个表达式只有数乘和加法——这就是一个「线性组合」,下一章的主角在这里先露了半张脸。几何上,p(t) 的轨迹恰好是从 v 箭尖到 w 箭尖的线段:两支箭头之间的「直线通道」。

妙处在于,这条公式对维度完全无感。二维屏幕坐标能 lerp,RGB 颜色能 lerp(ArgbEvaluator 干的就是逐通道 lerp,虽然色彩空间上有更讲究的做法),4096 维的词向量同样能 lerp。在生成模型里,人们真的会在两个 embedding 之间插值:对两张人脸的隐向量取中间点,解码出来是一张「长得介于两人之间」的脸;对「猫」和「狗」的向量插值,模型的判断会平滑地从猫滑向狗。高维空间里的「语义过渡」,底层就是你写动画时那行 lerp。意识到这一点的瞬间,4096 维应该显得亲切了一些。

▸ Android 类比

ValueAnimator + TypeEvaluator 的本质就是「在某个向量空间里做 lerp」:FloatEvaluator 在一维空间,PointFEvaluator 在二维,ArgbEvaluator 在四维(ARGB)。你写自定义 Evaluator 时遵守的约定——「必须能加、能数乘、结果还是同类型」——正是数学系那条「向量的抽象定义」。框架作者没提线性代数,但 API 的形状出卖了它。

数据集就是一摞向量

再换一个每天都会遇到的视角:表格数据。假设你有一张用户表,每行一个用户,列是「日活跃分钟数、月消费、注册天数」。那么每一行就是一个三维向量,整张表是 n 个向量摞在一起——预告一下,这一摞向量摞出来的东西就是矩阵,而且是 AI 里矩阵最常见的身份之一:数据矩阵,每行一个样本,每列一个特征

这个视角下,很多业务问题瞬间变成几何问题:「找出和这个用户行为最像的 100 个用户」= 找向量空间里离他最近的 100 支箭(第 04、05 章);「用户群有没有自然分层」= 这堆箭尖是不是聚成了几团;「这三个特征是不是冗余」= 这些向量是不是其实趴在一个更低维的平面上(第 12、18 章)。机器学习教材开篇总说「样本是特征空间中的点」,说的就是这件事——点和向量在这里是同一个对象:点是箭尖的位置,向量是从原点指过去的箭

图像也一样。一张 48×48 的灰度图,把像素逐行拉直,就是一个 2304 维向量——第 17 章的 SVD 压缩 Demo 正是这么处理图片的。音频是每毫秒采样值排成的长向量。所以「AI 把万物变成向量」不只是修辞:在进入模型之前,你的自拍照、语音、聊天记录,在数学上已经全部是 ℝⁿ 里的箭头了。全体 n 维向量组成的集合记作 ℝⁿ(读作「R n」,R 是实数 Real),这个记号后面章节随处可见:ℝ² 是平面,ℝ³ 是立体空间,ℝ⁴⁰⁹⁶ 是「国王」住的地方。

行着写,列着想

一个记号上的小事,现在说清楚能省掉后面无数困惑。向量可以横着写(行向量)也可以竖着写(列向量):

v = (2, 1)行着写,省纸  或  v = 21列着写,正统

线性代数的主流约定是:向量默认是列向量。原因下一卷就会揭晓——矩阵乘向量 Ax 时,x 竖着才能和 A 的行「咬合」。本书正文为了排版会经常横着写坐标,但每当它要和矩阵发生关系时,请自动在脑中把它竖起来。NumPy 里这个区别对应 shape:(4096,) 的一维数组、(1, 4096) 的行向量、(4096, 1) 的列向量是三种东西,第 19 章会专门算这笔账——AI 代码里一半的 shape 报错源于此。

一列数,凭什么装得下「意义」

看到「国王 = 4096 个数」时,一个自然的抗拒是:意义这么微妙的东西,怎么可能塞进一列数?值得在第一卷就给出诚实的回答:数字本身不携带意义,意义在于向量与向量之间的相对位置。单独看「国王」的 4096 个数,毫无信息量,换一套训练随机种子它们会完全不同;但「国王」和「女王」的向量彼此靠近、和「土豆」的向量彼此疏远,这个关系网在任何一次成功的训练里都会稳定出现。

这些位置是怎么学出来的?核心思想朴素得惊人:「一个词的含义,由它的邻居决定」(语言学家 Firth 的名言:You shall know a word by the company it keeps)。模型读海量文本,不断微调每个词的向量,让经常出现在相似上下文里的词被推得更近。「国王」和「女王」总在相似的句式里出现,于是被推到一起;没人在同一种句子里谈论「国王」和「土豆」,于是它们分开。意义不是被编码进坐标的,而是被几十亿次「推近/推远」的小动作雕刻成的几何结构。这也解释了为什么坐标本身可以随机而关系稳定——就像城市地图旋转平移之后,街道相对位置不变。

这个认识对后面几章至关重要:既然意义住在「相对位置」里,那么衡量位置关系的工具——距离和夹角——就是打开语义的钥匙。这正是第 04、05 章的全部内容。

零向量、单位向量与两个特殊角色

几个后面章节点名率很高的特殊向量,提前认识一下:

  • 零向量 0:所有分量为 0,几何上是「原地不动」。它是加法的单位元:v + 0 = v。任何线性变换都必须把零向量留在原地——这是第 06 章判断「是不是线性变换」的快速测试之一。
  • 标准基向量 î, ĵ:î = (1, 0),ĵ = (0, 1),沿坐标轴的单位箭头。它们是坐标系的「度量衡原器」:说 v = (2, 1),其实是在说 v = 2î + 1ĵ。这个改写看着像废话,却是下一章「张成」和第 06 章「矩阵」的钥匙——请记住它。
  • 单位向量:长度恰好为 1 的向量,常用来表示「纯方向」。任何非零向量除以自己的长度就能「归一化」成单位向量,第 05 章细讲。
✋ 动手自测

合上书(或者别往上滚),试着只用这一章的内容回答:

(3, −1) + (−3, 1) 是什么?它的几何画面是什么?

② 一支箭乘以 −0.5 后,方向和长度各发生了什么?

③ 「把两张人脸照片的隐向量取平均」对应本章哪个公式、t 取多少?

④ 为什么说 v = (2, 1) 「其实是」2î + 1ĵ?如果第④题让你犹豫,正好——下一章开篇就是它。

小结

向量是箭头(直觉),是数列(计算),是任何守「加法 + 数乘」规矩的对象(推广)。它只有两种基本动作,而这两种动作按分量进行,因此二维直觉可以平移到任意高维。AI 把万物 embedding 成向量,为的是让「相似」「组合」「变换」全部变成可计算的代数;而意义并不住在坐标数字里,它住在向量之间的相对位置构成的几何结构中——这句话值得抄下来贴在屏幕边上。你已经见过 v = 2î + 1ĵ 这个不起眼的改写——下一章我们就沿着它出发,问一个咸鱼翻身式的问题:只用两支箭头,靠缩放和相加,能到达平面上的哪些地方?答案是本书书名。