讲解稿 · 第02章 第04节 · 线性变换¶
口播时长:约 15–20 分钟|建议语速:中速偏慢,公式处停两拍|字数:约 3800 字
开场钩子¶
嘿,先做一件事:把手机拿起来,随手拍一张照片,然后在相册里点"编辑",把它旋转 90 度。
你看,图像整齐地转过去了。像素没错乱、直线还是直线、平行的边还平行。
我问你——手机在这一瞬间到底干了啥?
它没有一个像素一个像素地问"你要去哪儿"。它做的事只有一件:把一张矩阵,套在你照片的每一个像素坐标上。一次矩阵乘法,全部像素就到了新位置。
这就是这一节要讲的东西——线性变换。你今天用过的每一个滤镜、每一次拖拽缩放、每一款游戏里角色的转身,背后都是同一个动作:拿一个矩阵,去乘一个向量。
更关键的是:现在最火的那些大模型,Gemini、ChatGPT、Claude、DeepSeek——它们之所以叫 Transformer,是因为整个网络的骨头,就是一层一层的线性变换。数据一路穿过去,穿一层就被变换一次。
所以这一节,你别只当是学"矩阵在几何上代表什么"。你在学的是从图像编辑器一路通到大模型的同一个动作。
扶稳了,我们开始。
复习昨日 & 今日路线¶
先花 30 秒把上下文对齐。
昨天我们讲了 §03 矩阵运算——你会加、会乘、知道 \(AB \ne BA\)。再往前 Ch01 §05,我们讲了基变换:换一组坐标看同一个向量,口诀是——
"\(P\) 的列是新基,\(P\) 把新坐标搬回旧描述。"
今天这一节,我们把这两个东西钉在一起:矩阵不只是数字表,矩阵本身就是一个变换。你乘一个矩阵,就是在对向量施加一次几何动作。
下一节 §05 我们会讲矩阵分解——把一个复杂矩阵拆成几个简单变换的连乘,SVD、LU、QR 都是干这个的。所以今天你先把"矩阵 = 变换"这个直觉锁死,下一节拆解才有得拆。
好,进正题。
核心概念一 · 什么样的映射才配叫"线性"(约 3 分钟)¶
先给直觉。
想象一张网格纸,横竖都是直线,格子都是正方形。现在有一台"变形机器",你把网格纸塞进去,它出来的时候——
- 直线还是直线(不能扭成弧);
- 平行线还是平行(不能一边张开一边收拢);
- 原点还在原点(网格中心那个点不能挪)。
只要这台机器满足这三条,我们就叫它线性变换 (linear transformation),也叫线性映射 (linear map)。
正式定义。线性变换 \(T : V \to W\) 是一个函数,把 \(V\) 里的向量映到 \(W\) 里的向量,并且满足下面这套公理。
好,这里到了 Ch02 第一次正式给公理,我给你三件套——每条公理都是"名字 + 大白话 + 反例",别背符号,背反例。
公理 1 · 加性 (additivity):\(T(\mathbf{u} + \mathbf{v}) = T(\mathbf{u}) + T(\mathbf{v})\)。
大白话:先把两个向量加起来再变换,跟分别变换完再加,结果一样。
反例:\(T(x) = x^2\) 不是线性的。为什么?\(T(1 + 1) = T(2) = 4\),但 \(T(1) + T(1) = 1 + 1 = 2\)。\(4 \ne 2\),加性破了。
公理 2 · 齐次性 (homogeneity):\(T(c\mathbf{u}) = c \, T(\mathbf{u})\)。
大白话:先缩放再变换,跟先变换再缩放,结果一样。缩放的因子可以"穿过"变换。
反例:\(T(x) = x + 1\) 不是线性的。\(T(2 \cdot 1) = T(2) = 3\),但 \(2 \cdot T(1) = 2 \cdot 2 = 4\)。\(3 \ne 4\),齐次破了。
公理 3 · 零映射 (maps zero to zero):\(T(\mathbf{0}) = \mathbf{0}\)。
大白话:原点必须待在原点,不许挪。
反例:平移(translation)不是线性的。若 \(T(\mathbf{x}) = \mathbf{x} + (3, 0)^\top\),那 \(T(\mathbf{0}) = (3, 0)^\top \ne \mathbf{0}\)。零点跑了,线性性直接破产。
顺便说一句,公理 3 其实是从前两条推出来的(把 \(c = 0\) 代进公理 2),但我们把它单列出来,是因为这条最直观、最容易用来一眼判断"这个变换是不是线性的"——先看原点动没动,动了就不是。
符号首现——今天要用到 \(T\) 这个符号,四件套走一遍。
\(T\) — 变换 (transformation):一个从向量空间到向量空间的函数,写作 \(T(\mathbf{v})\) 或 \(T\mathbf{v}\)。例子:\(T(x, y) = (2x + y,\ x + 2y)\) 是从 \(\mathbb{R}^2\) 到 \(\mathbb{R}^2\) 的一个线性变换。
你验证一下这个例子:\(T(\mathbf{0}) = (0, 0)\) ✓;\(T((1, 0) + (0, 1)) = T(1, 1) = (3, 3)\),而 \(T(1, 0) + T(0, 1) = (2, 1) + (1, 2) = (3, 3)\) ✓。三条公理都过。
一句话总结:线性变换 = 保持加法 + 保持缩放 + 原点不动。三件缺一,不是线性。
核心概念二 · 矩阵就是变换本身(约 2.5 分钟)¶
现在我要跟你说这一节最重要的一句话。
每一个线性变换,都可以写成一次矩阵乘法。矩阵不是"表示"变换——矩阵就是变换本身。
怎么理解?我们从一个观察出发。
在 \(\mathbb{R}^2\) 里,你随便一个向量 \(\mathbf{v} = (x, y)\),其实是 \(x \hat{\mathbf{i}} + y \hat{\mathbf{j}}\),其中 \(\hat{\mathbf{i}} = (1, 0)\)、\(\hat{\mathbf{j}} = (0, 1)\) 是标准基。
现在一个线性变换 \(T\) 来了,因为 \(T\) 保加法、保缩放,所以
看到没?只要我知道 \(T\) 把 \(\hat{\mathbf{i}}\) 和 \(\hat{\mathbf{j}}\) 送到哪里,剩下所有向量的去处就全定了。
那我把 \(T(\hat{\mathbf{i}})\) 摆成矩阵的第一列,把 \(T(\hat{\mathbf{j}})\) 摆成第二列,这个矩阵就完整刻画了 \(T\)。
数字例子。取 🟢
看第一列 \((2, 1)^\top\)——这告诉你 \(\hat{\mathbf{i}} = (1, 0)\) 被送到 \((2, 1)\)。看第二列 \((1, 2)^\top\)——\(\hat{\mathbf{j}} = (0, 1)\) 被送到 \((1, 2)\)。
现在拿个具体向量算:\(\mathbf{v} = (3, 4)\),套 \(A\) 上去:
这一步在黑板上,我会画:先把 \((3, 4)\) 拆成"三份 \(\hat{\mathbf{i}}\) + 四份 \(\hat{\mathbf{j}}\)",然后把 \(\hat{\mathbf{i}}\) 换成 \((2, 1)\)、\(\hat{\mathbf{j}}\) 换成 \((1, 2)\),三份加四份,得到 \((10, 11)\)。
记住这句口诀:矩阵的每一列 = 对应基向量被送到的位置。整章的几何直觉都靠它。
⏸️ 暂停思考 · 第一次
停一下。矩阵 $$ B = \begin{bmatrix} 0 & 1 \ 1 & 0 \end{bmatrix} $$ 在几何上干了什么? 提示:看看它的两列,\(\hat{\mathbf{i}}\) 跑哪去了?\(\hat{\mathbf{j}}\) 跑哪去了?把标准坐标系画出来,你就一眼看出来了。
(答案:\(\hat{\mathbf{i}}\) 跑到 \((0,1)\)、\(\hat{\mathbf{j}}\) 跑到 \((1,0)\)——两者交换。这就是沿直线 \(y = x\) 的反射。)
核心概念三 · 五种典型变换的形状(约 3.5 分钟)¶
现在我们把最常见的几种线性变换,一个一个过。你别死记矩阵长啥样,就记住"两列 = 基向量送去哪"。
🟢 旋转 (rotation)¶
想让 \(\hat{\mathbf{i}}\) 顺时针不动、转到 \((\cos\theta, \sin\theta)\);\(\hat{\mathbf{j}}\) 从 \((0, 1)\) 转到 \((-\sin\theta, \cos\theta)\)。摆成矩阵:
代 \(\theta = 90°\):\(\cos 90° = 0\)、\(\sin 90° = 1\),得到
验证:\(\hat{\mathbf{i}} = (1, 0)\) 送到 \((0, 1)\)(第一列),确实转了 90 度。
旋转矩阵有两个漂亮的性质:长度不变、行列式为 \(+1\)。
🟢 缩放 (scaling)¶
沿 \(x\) 轴拉 \(s_x\) 倍、沿 \(y\) 轴拉 \(s_y\) 倍:
数字例:\(S(2, 0.5)\) 把 \((1, 4)\) 送到 \((2, 2)\)。对角矩阵永远是一次缩放。当你在电脑上把图片长边缩到一半,就是在对每个像素乘 \(S(0.5, 0.5)\)。
🟢 反射 (reflection)¶
沿 \(x\) 轴照镜子——\(y\) 分量翻负号:
\((3, 2)\) 变成 \((3, -2)\)。反射矩阵的行列式是 \(-1\),负号提醒你朝向翻了。旋转和反射合起来叫刚体变换——保距离、保角度,只是可能翻个身。
🟡 错切 (shearing)¶
想象一副印刷字,正体和斜体的差别就是错切。水平错切因子 \(k\):
含义:\(\hat{\mathbf{i}}\) 不动、\(\hat{\mathbf{j}}\) 从 \((0, 1)\) 挪到 \((k, 1)\)。\(k = 0.5\)、高度为 2 的点会向右滑 1。底不动,顶跑了。斜体字就是这样做出来的。
🔴 退化变换 (degenerate)¶
这是最有意思的一种:信息被压塌。看这个矩阵:
两列 \((1, 2)\) 和 \((2, 4)\)——第二列是第一列的 2 倍。也就是说,\(\hat{\mathbf{i}}\) 和 \(\hat{\mathbf{j}}\) 变换后落在同一条直线上。整个二维平面被这个矩阵压塌成一条直线。
行列式为零,\(\det D = 1 \cdot 4 - 2 \cdot 2 = 0\)。信息永久丢失,这个变换没有逆。
生活里的例子:彩色图转灰度。RGB 三通道压到亮度一维,就是一次退化变换——你没法从灰度图恢复出原来的颜色。
核心概念四 · 平移为什么"不算"线性(约 2.5 分钟)¶
到这里你可能会问:那平移呢?我把整张图往右挪 3 格,是不是也是一种线性变换?
答案是——不是。
回想公理 3:\(T(\mathbf{0}) = \mathbf{0}\)。平移 \(T(\mathbf{x}) = \mathbf{x} + \mathbf{t}\) 把零向量送到了 \(\mathbf{t}\),只要 \(\mathbf{t} \ne \mathbf{0}\),公理 3 直接破产。
那问题来了:电子游戏里角色明明又转又平移,怎么做到"一个矩阵搞定"的?
答案是——仿射变换 (affine transformation) + 齐次坐标 (homogeneous coordinates)。
仿射变换定义为:
它是"线性变换 + 平移"的组合。仿射保直线、保平行,但不保距离和角度。
trick 在这里:为了把 \(A\mathbf{x} + \mathbf{t}\) 写成一次矩阵乘法,我们给每个向量后面补一个 1:
\(n\) 维空间的仿射变换就升到 \((n+1) \times (n+1)\) 的矩阵。这样"平移"也被塞进矩阵乘法框架里了。
数字例。在 \(\mathbb{R}^2\) 里,"旋转 90 度再平移 \((3, 0)\)"合起来就是
用它去乘 \((1, 0, 1)^\top\):得到 \((0 + 0 + 3,\ 1 + 0 + 0,\ 1)^\top = (3, 1, 1)^\top\)。前两位是 \((3, 1)\)——原点先转 90 度还在原点(因为旋转不动原点),再平移到 \((3, 0)\)……等等,我说错了,我们送的是 \((1, 0)\)。\((1, 0)\) 旋转 90 度到 \((0, 1)\),再平移 \((3, 0)\) 到 \((3, 1)\)。对上了。
⏸️ 暂停思考 · 第二次
OpenGL 里,一个 3D 顶点的坐标写成 \((x, y, z, 1)\)——四个数。为什么末尾多一个 1? 想想我们刚刚干的事情。
(答案:因为要让 3D 空间里的平移也能用一次矩阵乘法表示。补 1 就是齐次坐标的 trick,让 \(4 \times 4\) 矩阵同时装下旋转、缩放和平移。整个计算机图形学的坐标变换管线,靠的就是这个。)
核心概念五 · 换基后同一个变换长什么样(约 3 分钟)¶
到这一步,你已经会用矩阵刻画变换、会算复合变换、会区分线性和仿射。但还有最后一件事:同一个变换,在不同基下写出来的矩阵不一样。
回想 Ch01 §05 那条口诀——
"\(P\) 的列是新基,\(P\) 把新坐标搬回旧描述。"
设有个线性变换 \(T\)。在标准基下,它的矩阵是 \(A\);在新基 \(\{\mathbf{b}_1, \mathbf{b}_2\}\) 下,它的矩阵是 \(\tilde A\)。它俩什么关系?
相似变换公式(记牢,Ch02 后面对角化整节都靠它):
新 = \(P^{-1}\) · 旧 · \(P\)。别写反,写反了后面特征值全崩。
怎么理解?直观上:拿一个"用新坐标写的向量",先用 \(P\) 把它翻译回旧坐标(因为 \(A\) 只会读旧坐标),扔进 \(A\) 变换一下,得到旧坐标下的结果,最后用 \(P^{-1}\) 把结果翻译回新坐标。三步合起来就是 \(P^{-1} A P\)。
好,这里 Ch01 遗留了一个断层:\(P^{-1}\) 具体怎么算?我们把这个坑今天填上。
\(2 \times 2\) 的逆矩阵有闭式:若
则
口诀:主对角调换,副对角变号,除以行列式。这是 \(2 \times 2\) 唯一需要背的公式。\(3 \times 3\) 及以上一般走高斯消元,我们放到 §05 讲矩阵分解时再展开。
完整数字例子(2×2 相似变换)。🟡
设标准基下的变换 $$ A = \begin{bmatrix} 2 & 0 \ 0 & 3 \end{bmatrix} $$——沿 \(x\) 拉 2 倍、沿 \(y\) 拉 3 倍。
新基 \(\mathbf{b}_1 = (1, 1)^\top\)、\(\mathbf{b}_2 = (1, -1)^\top\)。按口诀,\(P\) 的列 = 新基旧坐标:
\(\det P = 1 \cdot (-1) - 1 \cdot 1 = -2\),主对角调换、副对角变号:
(这里巧了,\(P^{-1}\) 和 \(\frac{1}{2} P\) 长得一样,因为 \(P\) 是对称的正交阵除以常数。别死记这个巧合,一般矩阵不这样。)
算 \(AP\):
再算 \(\tilde A = P^{-1}(AP)\):
看结果:\(A\) 在标准基下是对角阵,但在 \(\{\mathbf{b}_1, \mathbf{b}_2\}\) 下变成了带副对角元的矩阵。为什么?因为新基不再和 \(A\) 的拉伸轴对齐——沿 \(\mathbf{b}_1\) 方向拉一下,会同时改变 \(\mathbf{b}_1\) 和 \(\mathbf{b}_2\) 方向的分量。
这个例子你先揣着。§05 讲特征分解时,你会看到反过来的操作:选一组特别的基,让 \(\tilde A\) 变成对角阵——那就是"对角化",也是 PCA 的核心操作。
\(3 \times 3\) 及以上矩阵求逆的具体算法(高斯消元、LU 分解),我们放到 Ch03 §05 讲。这一节你先把 \(2 \times 2\) 求逆手算会。
一个走完全程的例子(约 2.5 分钟)¶
现在把今天所有零件串起来,跟我一起做一遍。
任务:拿向量 \(\mathbf{v} = (2, 1)\),依次施加三个变换——先旋转 90 度、再沿 \(x\) 拉 2 倍、再做因子 \(k = 1\) 的水平错切——最后落在哪?
我给你两条路,一条逐步算、一条合成矩阵一次算,你看它们结果一致。
路径 1 · 逐步算。
第一步,旋转 90 度:$$ R = \begin{bmatrix} 0 & -1 \ 1 & 0 \end{bmatrix} $$。
第二步,沿 \(x\) 拉 2 倍:$$ S = \begin{bmatrix} 2 & 0 \ 0 & 1 \end{bmatrix} $$。
第三步,水平错切 \(k = 1\):$$ \text{Sh} = \begin{bmatrix} 1 & 1 \ 0 & 1 \end{bmatrix} $$。
最终点:\((0, 2)\)。
路径 2 · 合成矩阵。
把三个矩阵先乘起来,\(M = \text{Sh} \cdot S \cdot R\)。注意顺序——最先作用的写在最右边,因为它先撞上向量。
先算 \(\text{Sh} \cdot S\):
再乘 \(R\):
对 \(\mathbf{v} = (2, 1)\) 施加 \(M\):
对上了。
这个例子想让你记住三件事:
- 复合变换 = 矩阵乘积,顺序不能换(\(AB \ne BA\))。
- "最先作用的矩阵写最右边"——因为向量从右边被推进去。
- 你可以逐步算(省脑子),也可以先合并成一个矩阵再一次算(省时间,尤其在 GPU 上批量处理时)。
易错点回头看(约 1 分钟)¶
有三个坑,学生反复掉。
坑一 · 很多人以为"矩阵的每一行是新基",其实是"每一列是基向量的落点"。看到 $$ \begin{bmatrix} 2 & 1 \ 1 & 2 \end{bmatrix} $$,第一列 \((2, 1)\) 才是 \(\hat{\mathbf{i}}\) 去的地方。搞反的话,\(AB\) 和 \(BA\) 就分不清了。原因:我们用列向量做默认,\(A \mathbf{v}\) 是"左行乘右列",\(\hat{\mathbf{i}} = (1, 0)^\top\) 挑出的正是第一列。
坑二 · 很多人以为"先旋转再缩放 = 先缩放再旋转",其实一般不相等。原因:矩阵乘法不满足交换律,\(SR \ne RS\)。游戏引擎里"先转身再前进"和"先前进再转身"角色落在不同位置,就是这个道理。
坑三 · 很多人以为"平移是线性变换",其实不是。原因:平移把原点挪走,破坏了 \(T(\mathbf{0}) = \mathbf{0}\)。要用矩阵表达平移,必须升到仿射 + 齐次坐标,多补一维、多补一个 1。
与下节的钩子¶
到这里,你已经知道每个矩阵都能读成一次变换,也会算复合变换、会算相似变换。
但你有没有觉得——一个复杂矩阵,看它数字表根本看不出它到底在干嘛?$$ \begin{bmatrix} 2.5 & -0.5 \ -0.5 & 2.5 \end{bmatrix} $$ 你光看数字,能想到它其实就是一次伪装成"沿新基拉伸"的对角阵吗?
下一节 §05,我们回答一个问题:能不能把任意矩阵,拆成几个我们已经认识的简单变换的乘积? 比如"旋转 × 缩放 × 旋转",或者"下三角 × 上三角"。
那就是矩阵分解——SVD、LU、QR、特征分解,全都是把复杂矩阵拆成简单积木。而 PCA、最小二乘、注意力机制,全都建立在这些分解之上。
下一节见。