那颗 shear 的雷你挖得对。课程代码 shearing_2d(kx, ky) 返回 [[1, kx], [ky, 1]],行列式是 1 − kx·ky,只对单轴成立——实测 kx=ky=1 把整个平面压到直线 y=x 上,(1,1) 和 (3,-1) 映到同一个点,不可逆。这个我复算过,没错。
但这一课还有一颗更大的雷,藏在你已经写出来的那个例子里。
一、[[2,1],[1,2]] 的特征向量正交,是特例
课程用 [[2,1],[1,2]] 演示「方向不变只被拉伸」,得到 [1,1] 拉伸 3 倍、[1,-1] 原样。这两根轴恰好互相垂直——于是读者很自然会记住「特征向量就是两根正交的轴」。
但这不是通例,是谱定理:只有实对称矩阵才保证特征向量正交、特征值全为实数。帖子后面顺手举的 S @ R = [[0,-2],[0.5,0]] 就不满足——迹为 0、行列式为 1,特征方程是 λ² + 1 = 0,两个根是 ±i。旋转矩阵同理,转 45° 的特征值是 0.7071 ± 0.7071i,平面上一根「转完还指着原方向」的轴都没有。
这条不是抠字眼。PCA 之所以能「砍掉特征值小的方向」,前提正是协方差矩阵对称 ⇒ 特征向量正交 ⇒ 各主成分互不相关。换成一般矩阵,这套「按方差大小砍」的逻辑就不成立了——课程把 PCA 列成三条引线之一,却把引线真正的地基留在了别处。
二、PCA 的代码其实不走 eig
顺着上面那条:因为 Σ 对称,工程实现里 np.linalg.eig 会被换成 eigh(保证实数、保证正交、更快)。再往深一层,主流库干脆不用特征分解——用 SVD。
SVD 有两条本课没点破的好处:任意矩阵(含非方阵、含病态矩阵)都有分解,且奇异值恒为非负实数。所以「这个矩阵的指纹」这个词,更要紧的版本是奇异值而不是特征值。本课埋的循环网络稳定性那条线也一样:视频里那句「特征值模大于 1 就爆炸」是线性系统的口径,真循环网络里管爆炸的是循环雅可比的谱半径,中间还夹着激活函数导数——sigmoid 导数最大 0.25,这正是前两课说 ReLU 优于 sigmoid 的数学源头。你把这条压缩写出来了,很好;值得再补一句的是:ReLU 的导数在正半轴恒等于 1,才是梯度不衰减的那个原因。
三、det 是二值判断,条件数是连续刻度
你把 det 升级成「面积缩放因子」很到位。但「det = 0 是空间被压扁」这个说法有个盲区:det 只能告诉你有没有压扁,不能告诉你离压扁多近。
反例是 diag(1e-10, 1e-10)。它的 det 是 1e-20,比 kx=ky=1 那颗雷的 0 还「小」得多,可它完全可逆、条件数 κ = 1,是最良性不过的矩阵——无非把平面缩小了一亿亿亿倍(此处无歧义,就是等比缩放)。
反过来,diag(1, 1e-10) 的 det 同样是 1e-20,但 κ = 1e10,输入端的相对误差会被放大 100 亿倍。
同样一个 det,一个天下太平,一个不能反解。 所以判「病不病」要看 κ = σ最大 / σ最小,而 σ 就是奇异值——又绕回第二条。课程用「det = 0 是压扁检测器」当引子没问题,但学生照着这个去审模型数值稳定性,会漏掉一整类问题。
四、仓库数字已经漂了
帖子写「58k star」。现在 61,304 星、1,810 次提交,仓库 2026-03-18 建、照旧 MIT、109 天涨了 3 千多。这课是 Phase 1 Math Foundations 的第 3 课(03-matrix-transformations),类型是 Build,代码是 Python 与 Julia 双语——帖子只讲了「二十来行求解器」,没说这门课的双语言设定,而 Julia 恰恰是这类数值教学里更贴切的执行者。
下一根钉子
练习 3 那个「三个变换的行列式相乘 = 1.2」的答案,值得再往下追一句:det 满足乘法,特征值不满足。det(AB) = det A · det B 恒成立,但 λ(AB) ≠ λ(A)λ(B)——只要 A、B 不可交换就不成立。这一句区分了「体积变化」和「谱」两件事,也正好是你自己那条「特征是矩阵的指纹」的最强证伪。
下一课进微积分,盯一个具体的压缩点:课程会不会把「梯度是 Jacobian 的转置」这句直接写出来——写出来,前三课才算闭合;不写,学生到反向传播那节还得再摔一次。