Files
maths-cs-ai-compendium-zh/chapter 02: matrices/04. linear transformations.md
T
flykhan 2536c937e3 feat: 完整中文翻译 maths-cs-ai-compendium(数学·计算机科学·AI 知识大全)
翻译自英文原版 maths-cs-ai-compendium,共 20 章全部完成。

第01章 向量 | 第02章 矩阵 | 第03章 微积分
第04章 统计学 | 第05章 概率论 | 第06章 机器学习
第07章 计算语言学 | 第08章 计算机视觉 | 第09章 音频与语音
第10章 多模态学习 | 第11章 自主系统 | 第12章 图神经网络
第13章 计算与操作系统 | 第14章 数据结构与算法
第15章 生产级软件工程 | 第16章 SIMD与GPU编程
第17章 AI推理 | 第18章 ML系统设计
第19章 应用人工智能 | 第20章 前沿人工智能

翻译说明:
- 所有数学公式 $...$ / $$...$$、代码块、图片引用完整保留
- mkdocs.yml 配置中文导航 + language: zh
- README.md 已翻译为中文(兼 docs/index.md)
- docs/ 目录包含指向各章文件的 symlink
- 约 29,000 行中文内容,排除 .cache/ 构建缓存
2026-05-03 10:23:20 +08:00

164 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 线性变换
*每个矩阵乘法都是一个线性变换——一个在保持线性性质的同时重塑、旋转或投影向量的函数。本文涵盖旋转、反射、缩放、剪切、投影、映射的核与像,以及神经网络层如何串联这些变换。*
- **线性变换**(或线性映射)是一个接收向量并产生另一个向量的函数,同时保持加法和缩放性质。如果 $T$ 是线性的,则:
- $T(\mathbf{u} + \mathbf{v}) = T(\mathbf{u}) + T(\mathbf{v})$
- $T(c\mathbf{u}) = cT(\mathbf{u})$
- 每个线性变换都可以表示为矩阵乘法。矩阵*就是*变换本身。当你用一个矩阵乘以一个向量时,就是在对它施加一个线性变换。
- 可以把一个 $2 \times 2$ 矩阵想象成一个机器:它接收二维向量,输出新的二维向量。矩阵的列告诉你标准基向量 $\hat{\mathbf{i}}$ 和 $\hat{\mathbf{j}}$ 经过变换后到了哪里。其余一切都由线性性质导出。
![矩阵的列显示了基向量落在何处](../images/basis_transform.svg)
- 例如,如果
```math
A = \begin{bmatrix} 2 & 1 \\ 1 & 2 \end{bmatrix}
```
那么 $\hat{\mathbf{i}} = [1, 0]^T$ 落在 $[2, 1]^T$(第1列),$\hat{\mathbf{j}} = [0, 1]^T$ 落在 $[1, 2]^T$(第2列)。其他所有向量都是这两个向量的组合,因此其输出自动遵循。
- 将两个矩阵相乘可以理解为依次施加两个变换。如果 $B$ 将向量从一个空间变换,然后 $A$ 变换结果,那么 $AB$ 按顺序完成这两个操作。在游戏引擎中,先旋转角色再向前移动,与先移动再旋转,结果完全不同——这就是矩阵乘法不满足交换律的原因。
- **旋转**将向量绕一定角度 $\theta$ 转动而不改变其长度。向量大小不变,只是指向新的方向。
![旋转保持长度不变但改变方向](../images/rotation.svg)
- 二维中的旋转矩阵为:
```math
R(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}
```
- 当 $\theta = 90°$ 时:
```math
R = \begin{bmatrix} 0 & -1 \\ 1 & 0 \end{bmatrix}
```
因此 $[1, 0]^T$ 变成 $[0, 1]^T$。原来指向右侧的向量现在指向上方。旋转矩阵是正交的,且行列式始终为1。当你在手机上旋转照片时,就是对每个像素坐标应用这个矩阵。
- 在三维中,每个坐标轴都有对应的旋转矩阵。机械臂的每个关节绕特定轴旋转,每个关节就是一个旋转矩阵。绕z轴旋转看起来像是嵌入三维的二维情况:
```math
R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}
```
- **缩放**沿每个坐标轴独立地拉伸或压缩向量:
```math
S(s_x, s_y) = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}
```
![缩放沿每个轴以不同因子拉伸](../images/scaling.svg)
- $S(2, 1.5)$ 将x分量加倍,y分量乘以1.5。沿某轴缩放 $-1$ 会翻转该分量。对角矩阵总是缩放变换。当你将图片缩小到50%时,就是对每个像素坐标应用 $S(0.5, 0.5)$。
- **反射**像镜子一样将向量翻转到某个轴或直线的另一侧。沿x轴的反射保持x分量不变,取反y分量:
```math
\text{Ref}_x = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}
```
![沿x轴反射翻转y分量](../images/reflection.svg)
- 例如,$[3, 2]^T$ 变成 $[3, -2]^T$。当你的手机水平翻转自拍照使文字正确显示时,就是在应用反射矩阵。沿直线 $y = x$ 的反射交换两个分量:
```math
\text{Ref}_{y=x} = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}
```
- 反射矩阵的行列式为 $-1$,表明它们翻转了方向。
- 旋转和反射都是**刚性变换**:它们保持距离和角度不变。表示这些变换的矩阵是正交矩阵,这就是为什么正交矩阵的行列式总是 $+1$(旋转)或 $-1$(反射)。
- **剪切**沿一个坐标轴按另一坐标轴的比例倾斜向量。水平剪切因子 $k$:
```math
\text{Sh}_x(k) = \begin{bmatrix} 1 & k \\ 0 & 1 \end{bmatrix}
```
![剪切使顶部侧向滑动而底部保持不动](../images/shearing.svg)
- 每个点水平滑动 $k$ 倍于其高度的距离。当 $k = 0.5$ 时,高度为2的点向右移动1。最下面一行保持不动,最上面一行滑动最多。这就是斜体文字的工作原理:正立的字母被剪切,从而向右倾斜。
- 以上所有变换(旋转、缩放、反射、剪切)都是**线性**变换。它们保持原点固定,并保持直线为直线。但**平移**(将所有点按固定量移动)呢?
- 平移*不是*线性变换,因为它移动了原点。如果将每个点向右移动3,零向量会移动到 $[3, 0]^T$,从而破坏了线性性质。为了处理平移,我们使用**仿射变换**,它将线性变换与平移结合起来:
$$\mathbf{y} = A\mathbf{x} + \mathbf{t}$$
- 为了将其表示为单个矩阵乘法,我们使用**齐次坐标**:为每个向量添加一个额外的1,并使用一个 $(n+1) \times (n+1)$ 的矩阵:
```math
\begin{bmatrix} A & \mathbf{t} \\ \mathbf{0}^T & 1 \end{bmatrix} \begin{bmatrix} \mathbf{x} \\ 1 \end{bmatrix} = \begin{bmatrix} A\mathbf{x} + \mathbf{t} \\ 1 \end{bmatrix}
```
- 仿射变换保持直线和平行性,但不一定保持角度或长度。电子游戏中的每个物体都使用仿射变换来定位:旋转它、缩放它,然后放置到正确的位置——所有这些都编码在一个矩阵中。
- **退化变换**(奇异矩阵)将空间坍缩到更低维度。
- 例如,矩阵
```math
\begin{bmatrix} 1 & 2 \\ 2 & 4 \end{bmatrix}
```
将每个二维向量映射到一条直线上,因为两列指向同一方向。行列式为零,信息丢失,且该变换不可逆。
- 将彩色图像(每个像素有3个值:红、绿、蓝)转换为灰度图(每个像素1个值)就是退化变换:颜色信息永久丢失。
- 在机器学习中,线性变换是神经网络的核心。数据被表示为矩阵(向量的堆叠,这些向量代表对象的特征——人、飞机、文本、图像……任何东西!)
- 每一层应用一个矩阵乘法(线性变换),详细内容在其他章节中提供,我们需要解释如何组织这些数据并恰当地引出神经网络。
- 然而,当今最常用的技术几乎完全是将数据通过一系列线性变换传递,我们称之为**Transformer**。
- Gemini、ChatGPT、Claude、Qwen、DeepSeek以及当今世界上性能最好的AI,都是Transformer
## 编程练习(使用CoLab或Jupyter Notebook
1. 对向量应用旋转矩阵,并绘制原始向量和旋转后的向量。尝试不同的角度。
```python
import jax.numpy as jnp
import matplotlib.pyplot as plt
theta = jnp.pi / 3
R = jnp.array([[jnp.cos(theta), -jnp.sin(theta)],
[jnp.sin(theta), jnp.cos(theta)]])
v = jnp.array([1.0, 0.0])
v_rot = R @ v
plt.figure(figsize=(5, 5))
plt.quiver(0, 0, v[0], v[1], angles='xy', scale_units='xy', scale=1, color='red', label='original')
plt.quiver(0, 0, v_rot[0], v_rot[1], angles='xy', scale_units='xy', scale=1, color='blue', label='rotated')
plt.xlim(-1.5, 1.5); plt.ylim(-1.5, 1.5)
plt.grid(True); plt.legend(); plt.gca().set_aspect('equal')
plt.show()
```
2. 对构成正方形的一组点应用剪切变换,并可视化变形后的形状。
```python
import jax.numpy as jnp
import matplotlib.pyplot as plt
square = jnp.array([[0,0],[1,0],[1,1],[0,1],[0,0]]).T
k = 0.5
shear = jnp.array([[1, k],
[0, 1]])
sheared = shear @ square
plt.figure(figsize=(6, 4))
plt.plot(square[0], square[1], 'r-o', label='original')
plt.plot(sheared[0], sheared[1], 'b-o', label='sheared')
plt.grid(True); plt.legend(); plt.gca().set_aspect('equal')
plt.show()
```