读完这一课,你将能够
- 读出任意 \(2\times2\) 矩阵把 \(\hat{\imath},\hat{\jmath}\) 搬到的两个落点(即两列),并用列视角手算 \(Av\),说出它把向量搬到了哪
- 判断一个变换是否线性(保加法、保数乘、原点不动),并说清 \(Wx+b\) 为什么是仿射而非线性
- 对给定矩阵算 \(\det\),并用大小、符号、为零三种情形解释面积缩放、定向翻转、压扁降维的几何后果
- 用 \((AB)x=A(Bx)\) 把矩阵乘法理解为变换复合,举例说明 \(AB\neq BA\),并默念形状契约 \((m\times n)(n\times p)=(m\times p)\)
- 对一个被压扁的矩阵亲手数出秩与零空间,验证"秩 + 零空间维 = 列数"
上一课我们确立了"万物皆向量",并用点积衡量两个向量的关系。这一课,我们让整个空间动起来:矩阵不再是一张死板的数表,而是一台变换空间的机器——它把每个向量搬到新位置,让网格被缩放、旋转、剪切、压扁。理解了这一点,你就拿到了打开线性代数(以及神经网络)的钥匙。
记号衔接:沿用上一课的约定,向量记作斜体 \(v\)(默认是列向量),矩阵记作大写 \(A\)。零向量特别记作粗体 \(\mathbf{0}\),以便和标量 \(0\) 区分开——本课里只有零向量加粗,普通向量都用斜体。
一、矩阵的双重身份
一个矩阵 \(A\) 同时是两样东西:
- 静态视角:一张数表。比如 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\),就是排成方阵的四个数。
- 动态视角:一个线性变换 linear transformation。它是一个函数,吃进一个向量 \(v\),吐出另一个向量 \(Av\)。它作用在整个平面的每一个点上,把空间"掰弯"成新形状。这里的"线性"是有严格含义的——它指变换保持加法和数乘(精确的三条性质我们第三节就给出)。
这门课最重要的心态转变:不要把 \(Av\) 看成"一堆乘加运算的结果",而要看成"把向量 \(v\) 搬到了哪里"。整张数表,编码的是"空间该怎么动"。
二、矩阵的列 = 基向量变换后的落点
这是全课最重要的一句话,值得你停下来反复咀嚼。
回忆平面里的两个基向量 basis vector:
\[ \hat{\imath}=\begin{bmatrix}1\\0\end{bmatrix},\qquad \hat{\jmath}=\begin{bmatrix}0\\1\end{bmatrix}. \]任何向量都是它们的线性组合,例如 \(v=\begin{bmatrix}x\\y\end{bmatrix}=x\,\hat{\imath}+y\,\hat{\jmath}\)。
线性变换有个关键性质:只要知道 \(\hat{\imath}\) 和 \(\hat{\jmath}\) 被搬到哪里,就知道所有向量被搬到哪里。这一步用到下一节会正式讲的两条性质——把和拆开(可加性)、把标量提到前面(齐次性)。我们一步步展开,看清楚它不是黑魔法而是机械的两步:
\[ A\,v = A(x\,\hat{\imath}+y\,\hat{\jmath}) \underset{\text{可加性}}{=} A(x\,\hat{\imath})+A(y\,\hat{\jmath}) \underset{\text{齐次性}}{=} x\,(A\hat{\imath}) + y\,(A\hat{\jmath}). \]现在看 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\) 怎么作用在基向量上:
\[ A\hat{\imath}=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\begin{bmatrix}1\\0\end{bmatrix}=\begin{bmatrix}2\\0\end{bmatrix},\qquad A\hat{\jmath}=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\begin{bmatrix}0\\1\end{bmatrix}=\begin{bmatrix}1\\3\end{bmatrix}. \]看出来了吗?\(A\hat{\imath}\) 恰好是 \(A\) 的第一列,\(A\hat{\jmath}\) 恰好是 \(A\) 的第二列。这不是巧合——这就是矩阵的定义方式。
要点
矩阵的每一列,就是对应基向量变换后的落点。于是矩阵-向量乘法 \(Av\) 等于"用 \(v\) 的分量去加权矩阵的各列":
\[ \begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix} = x\begin{bmatrix}a\\c\end{bmatrix}+y\begin{bmatrix}b\\d\end{bmatrix}. \]这叫"列视角",是理解一切矩阵运算的根基。
例题
用 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\) 作用在 \(v=\begin{bmatrix}1\\1\end{bmatrix}\)。
用列视角:\(Av = 1\cdot\begin{bmatrix}2\\0\end{bmatrix}+1\cdot\begin{bmatrix}1\\3\end{bmatrix}=\begin{bmatrix}2+1\\0+3\end{bmatrix}=\begin{bmatrix}3\\3\end{bmatrix}.\)
验算(逐行点积):第一行 \(2\cdot1+1\cdot1=3\);第二行 \(0\cdot1+3\cdot1=3\)。两种算法一致,得 \(\begin{bmatrix}3\\3\end{bmatrix}\)。
三、什么样的变换才算"线性"
上一节我们已经反复用到"线性变换"这个词,现在给它一个精确的定义。不是任何把向量搬来搬去的规则都叫线性变换——线性变换必须满足三条性质:
- 保持加法(可加性):\(A(u+v)=Au+Av\)。
- 保持数乘(齐次性):\(A(c\,v)=c\,(Av)\)。
- 原点不动:\(A\,\mathbf{0}=\mathbf{0}\)(这其实是齐次性取 \(c=0\) 的推论)。
回头看第二节那个把 \(Av\) 拆成 \(x(A\hat{\imath})+y(A\hat{\jmath})\) 的等式:第一步"把和拆开"正是性质 1,第二步"把标量提出来"正是性质 2。所以"列视角"不是凭空的魔法,而是这两条性质的直接推论。
用 3Blue1Brown 的直觉说:线性变换就是那种"网格线始终保持平行且等距,原点钉死不动"的变形。允许拉伸、旋转、斜切;但不允许把直网格弯成曲线,也不允许整体平移让原点跑掉。
这解释了一个常见困惑:神经网络里的 \(Wx+b\),那个 \(+b\)(平移)不是线性变换(它让原点动了),严格说是"仿射 affine"变换。这里先给仿射一个正面定义记住:仿射变换 = 一个线性变换再加一个平移,即 \(x\mapsto Ax+b\);当 \(b=\mathbf{0}\) 时它就退化成线性变换。后面讲神经网络层时还会回到这点。
四、五种最常见的 2D 变换
下表把几何动作翻译成矩阵。建议你对每个矩阵都心算一下它把 \(\hat{\imath},\hat{\jmath}\)(即两列)搬到了哪里。
| 变换 | 矩阵 | 几何效果 |
|---|---|---|
| 缩放 scaling | \(\begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}\) | 横向拉 \(s_x\) 倍、纵向拉 \(s_y\) 倍 |
| 旋转 rotation | \(\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}\) | 绕原点逆时针转 \(\theta\) |
| 剪切 shear | \(\begin{bmatrix} 1 & k \\ 0 & 1 \end{bmatrix}\) | 把竖直网格斜推成平行四边形 |
| 反射 reflection | \(\begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\) | 沿 \(x\) 轴镜像翻转 |
| 投影 projection | \(\begin{bmatrix} 1 & 0 \\ 0 & 0 \end{bmatrix}\) | 把整个平面压扁到 \(x\) 轴上 |
旋转矩阵从哪来?
用列视角秒推:逆时针转 \(\theta\) 后,\(\hat{\imath}=(1,0)\) 落到 \((\cos\theta,\sin\theta)\),\(\hat{\jmath}=(0,1)\) 落到 \((-\sin\theta,\cos\theta)\)。把这两个落点当列拼起来,就是旋转矩阵:
\[ R(\theta)=\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}. \]例题:旋转 90°
取 \(\theta=90^\circ\),\(\cos90^\circ=0,\ \sin90^\circ=1\),于是 \(R=\begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}\)。
作用在 \(\begin{bmatrix}3\\2\end{bmatrix}\) 上:\(R\begin{bmatrix}3\\2\end{bmatrix}=\begin{bmatrix}0\cdot3+(-1)\cdot2\\ 1\cdot3+0\cdot2\end{bmatrix}=\begin{bmatrix}-2\\3\end{bmatrix}.\)
几何检验:\((3,2)\) 在第一象限,逆时针转 90° 应进入第二象限(\(x\) 变负、\(y\) 变正),\((-2,3)\) 正符合。口诀:旋转 90° 就是 \((x,y)\mapsto(-y,x)\)。
五、行列式:面积的缩放因子
变换把空间拉伸或压缩,那"被放大了多少倍"?答案就是行列式 determinant,记作 \(\det A\) 或 \(|A|\)。对 \(2\times2\):
\[ \det\begin{bmatrix} a & b \\ c & d \end{bmatrix}=ad-bc. \]要点:行列式的三层含义
- 大小:\(|\det A|\) = 面积(三维则是体积)的缩放倍数。变换前面积为 1 的单位正方形,变换后面积变成 \(|\det A|\)。
- 符号:\(\det A>0\) 保持定向;\(\det A<0\) 说明空间被翻转了(像照镜子,左右手互换)。还记得第四节的反射 \(\begin{bmatrix}1&0\\0&-1\end{bmatrix}\) 吗?它的 \(\det=1\cdot(-1)-0\cdot0=-1<0\),正是它把右手系翻成左手系——这就是符号为负最干净的几何实例。
- 为零:\(\det A=0\) 意味着空间被压扁、降维——面积塌成 0,变换不可逆 non-invertible(信息丢失,搬不回来)。
例题:验证面积缩放
仍用 \(A=\begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix}\),先算 \(\det A=2\cdot3-1\cdot0=6\)。
把单位正方形的四个角 \((0,0),(1,0),(1,1),(0,1)\) 逐个变换(用列视角,\(A\) 的两列是 \((2,0)\) 和 \((1,3)\)):
- \((0,0)\mapsto(0,0)\)(原点不动)
- \((1,0)\mapsto(2,0)\)(即第一列)
- \((1,1)\mapsto(2,0)+(1,3)=(3,3)\)(两列之和)
- \((0,1)\mapsto(1,3)\)(即第二列)
变换后是顶点为 \((0,0),(2,0),(3,3),(1,3)\) 的平行四边形。它由两条边向量 \((2,0)\) 与 \((1,3)\) 张成,面积 = \(|2\cdot3-0\cdot1|=6\),正好等于 \(\det A=6\)。单位正方形(面积 1)被放大成面积 6,缩放因子 = 行列式。验证成功。
易错
\(\det\) 只对方阵有定义(输入输出维数相同才谈得上"面积/体积缩放")。另外别把"\(\det A=0\) 不可逆"忘了:它等价于"两列线性相关、把空间压扁"。一旦压扁,多个不同向量会被搬到同一点,再也分不开——这正是下面"零空间"的来源。
六、矩阵乘法 = 变换的复合
如果先做变换 \(B\)、再做变换 \(A\),整体效果是什么?把它作用在 \(x\) 上就是 \(A(Bx)\)。我们定义矩阵乘积 \(AB\),使得
\[ (AB)\,x = A\,(B\,x)\quad\text{对所有 } x \text{ 成立}. \]也就是说,矩阵乘法 \(AB\) 就是"先 \(B\) 后 \(A\)"这个复合变换对应的那个矩阵。注意书写顺序:靠近 \(x\) 的先作用,所以要从右往左读。(记个口诀:谁挨着 \(x\),谁先上场。)
为什么一般 \(AB\neq BA\)?
因为"先剪切后旋转"和"先旋转后剪切"在几何上根本是两件事。举例,取旋转 90° 的 \(A=\begin{bmatrix}0&-1\\1&0\end{bmatrix}\) 与缩放 \(B=\begin{bmatrix}2&0\\0&1\end{bmatrix}\):
\[ AB=\begin{bmatrix}0&-1\\1&0\end{bmatrix}\begin{bmatrix}2&0\\0&1\end{bmatrix}=\begin{bmatrix}0&-1\\2&0\end{bmatrix},\qquad BA=\begin{bmatrix}2&0\\0&1\end{bmatrix}\begin{bmatrix}0&-1\\1&0\end{bmatrix}=\begin{bmatrix}0&-2\\1&0\end{bmatrix}. \]两者不等,所以矩阵乘法不满足交换律。(但满足结合律 \((AB)C=A(BC)\),这正是复合变换天然成立的。)
例题:验证复合 = 相乘
取剪切 \(B=\begin{bmatrix}1&1\\0&1\end{bmatrix}\) 与拉伸 \(A=\begin{bmatrix}2&1\\0&3\end{bmatrix}\),作用向量 \(x=\begin{bmatrix}2\\1\end{bmatrix}\)。
路线一(分两步):先算 \(Bx=\begin{bmatrix}1\cdot2+1\cdot1\\0\cdot2+1\cdot1\end{bmatrix}=\begin{bmatrix}3\\1\end{bmatrix}\),再算 \(A(Bx)=\begin{bmatrix}2\cdot3+1\cdot1\\0\cdot3+3\cdot1\end{bmatrix}=\begin{bmatrix}7\\3\end{bmatrix}.\)
路线二(先乘矩阵):\(AB=\begin{bmatrix}2\cdot1+1\cdot0 & 2\cdot1+1\cdot1\\ 0\cdot1+3\cdot0 & 0\cdot1+3\cdot1\end{bmatrix}=\begin{bmatrix}2&3\\0&3\end{bmatrix}\),再算 \((AB)x=\begin{bmatrix}2\cdot2+3\cdot1\\0\cdot2+3\cdot1\end{bmatrix}=\begin{bmatrix}7\\3\end{bmatrix}.\)
两条路线都得 \(\begin{bmatrix}7\\3\end{bmatrix}\),验证 \((AB)x=A(Bx)\)。顺带一提 \(\det(AB)=\det A\cdot\det B=6\cdot1=6\):复合变换的面积缩放,就是各步缩放因子相乘。
七、形状契约:维数怎么对上
到这里前六节用的都是 \(2\times2\) 方阵——输入和输出都在同一个平面里。但矩阵不必是方的。一个 \(m\times n\) 矩阵代表一个把 \(n\) 维向量送到 \(m\) 维空间的线性变换(\(n\) 列、每列是 \(m\) 维落点)。这意味着它可以改变维数。
先用一个最小的非方阵建立画面:
\[ P=\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \end{bmatrix}. \]它是 \(2\times3\),把三维向量送到二维。看它怎么作用:\(P\begin{bmatrix}x\\y\\z\end{bmatrix}=\begin{bmatrix}x\\y\end{bmatrix}\)——它丢掉了 \(z\) 坐标,把 3D 空间压扁投影到 \(xy\) 平面上,这正是一次"降维"。反过来,一个 \(3\times2\) 矩阵则把平面"嵌入"到三维空间里(升维)。"\(m\neq n\) 到底在做什么",答案就是在维数之间搬运。
乘法要能进行,必须满足形状契约:
\[ (m\times n)\,(n\times p)=(m\times p). \]要点
左矩阵的列数必须等于右矩阵的行数(中间的 \(n\) 要相消),结果矩阵的形状是"外侧两个数" \(m\times p\)。在 ML 里 99% 的形状报错都是这条契约没对上——养成在脑中默念形状的习惯。
八、秩与零空间:被压扁到几维
当 \(\det A=0\)(或更一般地,非方阵情形),空间被压扁了。两个概念精确描述"压扁的后果":
- 秩 rank:变换后的输出实际填满了几维空间——即列向量张成空间的维数。满秩 = 没压扁;秩下降 = 被压扁了。例如投影 \(\begin{bmatrix}1&0\\0&0\end{bmatrix}\) 把整个平面压到一条直线上,秩 = 1。
- 零空间 null space(也叫核 kernel):所有被变换压到原点 \(\mathbf{0}\) 的向量集合,即满足 \(Av=\mathbf{0}\) 的 \(v\)。它衡量"丢失了哪些信息"。
例题:亲手数出秩与零空间
对投影矩阵 \(P=\begin{bmatrix}1&0\\0&0\end{bmatrix}\),我们把三件事都算出来:
- 列空间(决定秩):两列是 \((1,0)\) 与 \((0,0)\)。第二列是零向量、毫无贡献,输出只能落在第一列张成的 \(x\) 轴上。所以列空间 = \(x\) 轴(一维),秩 = 1。
- 零空间:解 \(Pv=\mathbf{0}\),即 \(\begin{bmatrix}1&0\\0&0\end{bmatrix}\begin{bmatrix}a\\b\end{bmatrix}=\begin{bmatrix}a\\0\end{bmatrix}=\begin{bmatrix}0\\0\end{bmatrix}\),要求 \(a=0\)、\(b\) 任意。于是零空间是全体 \(\begin{bmatrix}0\\t\end{bmatrix}\),正是整条 \(y\) 轴(一维),一个基是 \(\begin{bmatrix}0\\1\end{bmatrix}\)。
- 当场兑现守恒律:秩 1 +(零空间维数)1 = 2 = 输入维数(列数)。
这条"秩 + 零空间维 = 列数"的守恒律叫秩-零化度定理 rank–nullity theorem。直觉是:输入的每一维,要么被保留到输出里(贡献给秩),要么被压到原点(贡献给零空间),不会凭空消失。后续课会给出正式证明。
ML 和 ML 的联系
1. 神经网络每一层 = 线性变换 + 平移 + 非线性。一层的计算是 \(h=\sigma(Wx+b)\):权重矩阵 \(W\) 是线性变换(把上一层的特征"掰弯"重组),\(b\) 是平移——\(Wx+b\) 合起来正是上一节说的仿射变换(线性变换 + 平移),外面再套的 \(\sigma\)(如 ReLU)是非线性。正因为线性变换的复合还是线性变换(\(A(Bx)=(AB)x\)),如果没有中间的非线性,再多层叠起来也等价于单个矩阵 \(W=W_3W_2W_1\)——深度就白费了。非线性是深度网络的灵魂,而你刚证明的复合律正是"为什么需要它"的数学原因。
2. 注意力机制里的 \(QK^\top\) 就是一批线性变换 + 两两点积。把输入经线性变换得到查询 \(Q\) 和键 \(K\)(各是 \(Wx\) 形式),\(QK^\top\) 的第 \(i,j\) 个元素正是第 \(i\) 个查询向量与第 \(j\) 个键向量的点积——也就是上一课讲的"用点积衡量相似度",被矩阵乘法一次性批量算完。线性变换 + 点积,就是 Transformer 的核心算子。
九、用 numpy 把这一切跑一遍
下面的代码只用 numpy 和 print,几秒跑完。它打印基向量落点、行列式、并验证 \(A(Bx)=(AB)x\) 以及 \(\det(AB)=\det A\det B\)。
import numpy as np
A = np.array([[2., 1.],
[0., 3.]])
# 1) 矩阵的列 = 基向量变换后的落点
i_hat = np.array([1., 0.])
j_hat = np.array([0., 1.])
print("A @ i_hat =", A @ i_hat, " <- 应等于 A 的第一列", A[:, 0])
print("A @ j_hat =", A @ j_hat, " <- 应等于 A 的第二列", A[:, 1])
# 2) 行列式 = 面积缩放因子
print("det(A) =", round(np.linalg.det(A), 6)) # 期望 6.0
# 单位正方形四角 -> 验证面积
square = np.array([[0, 0], [1, 0], [1, 1], [0, 1]]).T # 每列一个角
print("正方形四角变换后(每行一个角):")
print((A @ square).T)
# 3) 旋转 90 度: (x,y) -> (-y,x)
theta = np.pi / 2
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
print("R @ [3,2] =", np.round(R @ np.array([3., 2.]), 6)) # 期望 [-2, 3]
# 4) 复合变换 = 矩阵相乘
B = np.array([[1., 1.],
[0., 1.]]) # 剪切
x = np.array([2., 1.])
print("A @ (B @ x) =", A @ (B @ x)) # 分两步
print("(A @ B) @ x =", (A @ B) @ x) # 先乘矩阵, 两者应相同
# 5) 乘法不可交换 + 行列式可乘
print("AB =\n", A @ B)
print("BA =\n", B @ A, " <- 与 AB 不同")
print("det(A)*det(B) =", round(np.linalg.det(A) * np.linalg.det(B), 6),
" det(AB) =", round(np.linalg.det(A @ B), 6))
运行后你会看到:基向量落点恰是 \(A\) 的两列;\(\det A=6\) 与四角围成的面积一致;\(R[3,2]^\top=[-2,3]^\top\);两条复合路线都给 \([7,3]^\top\);而 \(AB\neq BA\),但 \(\det(AB)=\det A\det B=6\)。
调一调,观察现象
下面三个小实验都只用 numpy 和 print,几秒跑完。每个都先猜结果再运行,重点是把"改一个数 → 几何上发生了什么"对应起来。
实验一:调剪切强度 k,看基向量落点变、行列式不变
改什么:把剪切矩阵 \(\begin{bmatrix}1&k\\0&1\end{bmatrix}\) 里的 \(k\) 从 0 调到 1 再到 3。
预期现象:\(\hat{\jmath}\) 的落点从 \((0,1)\) 滑到 \((1,1)\) 再到 \((3,1)\)(竖直网格越推越斜),但三种情况 \(\det\) 全是 \(1.0\)。
为什么:剪切只把平行四边形"推歪",底和高没变,面积不变,所以行列式恒为 1——这正是第五节"行列式 = 面积缩放因子"的体现。
import numpy as np
for k in [0., 1., 3.]:
S = np.array([[1., k],
[0., 1.]])
print("k =", k,
" j_hat 落点 =", S @ np.array([0., 1.]),
" det =", round(np.linalg.det(S), 6))
实验二:交换两行,看行列式符号翻转
改什么:把 \(A=\begin{bmatrix}2&1\\0&3\end{bmatrix}\) 的第一行和第二行对调。
预期现象:\(\det A = 6.0\),交换两行后变成 \(-6.0\),大小不变、符号翻了。
为什么:交换两行相当于额外做了一次反射,把空间的定向翻转了一次(右手系变左手系),所以行列式由正变负——正对应第五节"\(\det<0\) 表示翻转"。
import numpy as np
A = np.array([[2., 1.],
[0., 3.]])
A_swap = A[[1, 0], :] # 对调两行
print("det(A) =", round(np.linalg.det(A), 6)) # 期望 6.0
print("det(行交换) =", round(np.linalg.det(A_swap), 6)) # 期望 -6.0
实验三:换不同矩阵,看 det 落在哪个区间
改什么:分别取旋转矩阵、缩放 \(\mathrm{diag}(2,5)\)、投影 \(\begin{bmatrix}1&0\\0&0\end{bmatrix}\),各算一次行列式。
预期现象:旋转的 \(\det=1.0\)(保面积、不翻转),缩放的 \(\det=10.0\)(面积放大 \(2\times5\) 倍),投影的 \(\det=0.0\)(被压扁、不可逆)。
为什么:旋转只转不缩、缩放按两轴倍数相乘放大面积、投影把平面压到一条线上面积塌成 0——三档分别对应行列式 \(=1\)、\(>1\)、\(=0\) 三种几何命运。
import numpy as np
th = 0.7
R = np.array([[np.cos(th), -np.sin(th)],
[np.sin(th), np.cos(th)]]) # 旋转
D = np.diag([2., 5.]) # 缩放
P = np.array([[1., 0.],
[0., 0.]]) # 投影
print("det(旋转) =", round(np.linalg.det(R), 6)) # 期望 1.0
print("det(缩放) =", round(np.linalg.det(D), 6)) # 期望 10.0
print("det(投影) =", round(np.linalg.det(P), 6)) # 期望 0.0
动手练习
- 手算 + 列视角。给定 \(M=\begin{bmatrix}3&-1\\2&2\end{bmatrix}\),(a) 写出它把 \(\hat{\imath},\hat{\jmath}\) 搬到的落点;(b) 用列视角算 \(M\begin{bmatrix}1\\2\end{bmatrix}\);(c) 算 \(\det M\) 并说出面积放大几倍、有没有翻转。
import numpy as np M = np.array([[3., -1.], [2., 2.]]) # TODO: 打印 M 的两列、M @ [1,2]、det(M) print(M[:, 0], M[:, 1]) print(M @ np.array([1., 2.])) print(round(np.linalg.det(M), 6)) - 旋转复合。构造旋转 30° 与旋转 60° 的矩阵,验证它们相乘等于旋转 90° 的矩阵(提示:转 30° 再转 60° 当然等于转 90°)。
import numpy as np def rot(t): return np.array([[np.cos(t), -np.sin(t)], [np.sin(t), np.cos(t)]]) # TODO: 比较 rot(60度) @ rot(30度) 与 rot(90度) print(np.round(rot(np.pi/3) @ rot(np.pi/6), 6)) print(np.round(rot(np.pi/2), 6)) - 压扁、零空间与守恒律。对投影矩阵 \(P=\begin{bmatrix}1&0\\0&0\end{bmatrix}\):(a) 写出它零空间的一个基向量(一个非零 \(v\) 使 \(Pv=\mathbf{0}\));(b) 说出它的秩等于几;(c) 验证"秩 + 零空间维 = 2"这条守恒律;(d) 顺手算 \(\det P\) 确认它为 0。
import numpy as np P = np.array([[1., 0.], [0., 0.]]) # TODO: 找零空间的基, 数秩, 验证守恒律 v = np.array([0., 1.]) # 零空间的一个基向量? print("P @ v =", P @ v) # 期望 [0, 0] print("rank(P) =", np.linalg.matrix_rank(P)) # 期望 1 print("det(P) =", round(np.linalg.det(P), 6)) # 期望 0.0 - 不可交换的几何(含 det<0)。取剪切 \(S=\begin{bmatrix}1&1\\0&1\end{bmatrix}\) 与反射 \(F=\begin{bmatrix}1&0\\0&-1\end{bmatrix}\),算 \(SF\) 与 \(FS\),确认不相等,并各自把 \(\begin{bmatrix}1\\1\end{bmatrix}\) 变换一遍看落点差别;再算 \(\det F\) 确认它是负的(反射翻转了定向)。
- 形状契约。随机生成一个 \(2\times3\) 矩阵和一个 \(3\times4\) 矩阵相乘,打印结果形状,确认是 \(2\times4\);再试着把它们反过来乘,观察 numpy 报什么错。
掌握自检
- 看到任意 \(2\times2\) 矩阵,我能立刻说出它把 \(\hat{\imath},\hat{\jmath}\) 搬到哪两个点(即读出两列)。
- 我能用"列的线性组合"和"逐行点积"两种方式算 \(Av\),并得到相同结果。
- 我能说清线性变换的三条性质,能给出仿射变换的正面定义(\(x\mapsto Ax+b\)),并解释为什么 \(Wx+b\) 严格说是仿射而非线性。
- 给定一个矩阵,我能算 \(\det\) 并解释它的大小、符号、为零各意味着什么几何后果(包括反射的 \(\det=-1\) 为何代表翻转)。
- 我理解 \((AB)x=A(Bx)\),能举例说明为什么 \(AB\neq BA\),并知道形状契约 \((m\times n)(n\times p)=(m\times p)\)。
- 我能用"压扁到几维"解释秩,用"哪些向量被压到 0"解释零空间,并能亲手验证"秩 + 零空间维 = 列数"。
- 我能讲出为什么"线性层之间必须插非线性",以及 \(QK^\top\) 在算什么。
下一课,我们把"点积"升级为内积,用它一次讲透度量、正交、投影、最小二乘——也就是机器学习里"拟合"与"误差最小化"的几何本质。
可以先放过的点
- 秩-零化度定理"秩 + 零空间维 = 列数"的正式证明现在不必死磕,会用投影例子手验一次守恒律就够了,证明等到后面线性方程组那课再回来补。
- 零空间、核 kernel 这套词如果暂时觉得抽象,记住"被压到原点的向量"这一句直觉即可,等下一课《内积、范数与投影》讲到正交补、投影时,它会自然变清晰。
- 注意力机制里的 \(QK^\top\) 这段 ML 联系只需留个印象——知道它在"批量算点积相似度"就行,真正展开是 Transformer 专题的事,现在看不懂完全正常。
- 非方阵 \(m\times n\) 的升维/降维只要能看懂 \(2\times3\) 那个丢掉 \(z\) 的例子就够,更一般的形状变换等到神经网络层那课再细究。