Files
maths-cs-ai-compendium-zh/chapter 02: matrices/03. operations.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

147 lines
6.7 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.
# 矩阵运算
*矩阵运算是深度学习的计算引擎。本文涵盖矩阵加法、标量乘法、矩阵-向量积、矩阵乘法、逐元素运算、Kronecker积和广播——支撑每一次前向传播和梯度更新的运算。*
- 矩阵可以像向量一样进行加法和缩放。
- 加法要求两个矩阵维度相同,然后逐元素相加:
```math
\begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} + \begin{bmatrix} 5 & 6 \\ 7 & 8 \end{bmatrix} = \begin{bmatrix} 6 & 8 \\ 10 & 12 \end{bmatrix}
```
- 标量乘法将每个元素乘以标量:
```math
3 \times \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} = \begin{bmatrix} 3 & 6 \\ 9 & 12 \end{bmatrix}
```
- 矩阵能做的最简单的事情是乘以一个向量。**矩阵-向量乘法** $A\mathbf{x}$ 使用 $\mathbf{x}$ 的分量作为权重来组合 $A$ 的列:
```math
\begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} \begin{bmatrix} 5 \\ 6 \end{bmatrix} = 5 \begin{bmatrix} 1 \\ 3 \end{bmatrix} + 6 \begin{bmatrix} 2 \\ 4 \end{bmatrix} = \begin{bmatrix} 17 \\ 39 \end{bmatrix}
```
- 这是机器学习中的核心运算。每个神经网络层都计算 $A\mathbf{x} + \mathbf{b}$:矩阵乘以输入向量,再加上偏置。
- 一般情况是**矩阵乘法**。给定 $A$$m \times n$)和 $B$$n \times p$),乘积 $C = AB$ 是一个 $m \times p$ 矩阵,每个元素都是一个点积:
$$C_{ij} = \sum_{k=1}^{n} A_{ik} B_{kj}$$
- 结果中的每个条目都是 $A$ 的一行与 $B$ 的一列的点积。内部维度必须匹配($n$),结果取外部维度($m \times p$)。
- 另一种理解方式:结果的每一列都是 $A$ 的列的**加权和**,其中权重来自 $B$ 的对应列。
- 如果 $B$ 的某一列为 $[2, 3]^T$,则结果列就是 $2 \times (\text{A的第1列}) + 3 \times (\text{A的第2列})$。
- 一个有用的特例:矩阵与其转置相乘总是得到一个方阵。$AA^T$ 是 $m \times m$$A^TA$ 是 $n \times n$
```math
\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{bmatrix} \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix} = \begin{bmatrix} 14 & 32 \\ 32 & 77 \end{bmatrix}
```
- 矩阵乘法有重要的运算规则:
- **不满足交换律**:通常 $AB \neq BA$。顺序很重要。
- **满足结合律**$(AB)C = A(BC)$。你可以任意分组乘法。
- **满足分配律**$A(B + C) = AB + AC$。
- **单位矩阵**$AI = IA = A$。
- **Hadamard积**(逐元素乘积)将两个相同大小的矩阵逐项相乘,记作 $A \odot B$
```math
\begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} \odot \begin{bmatrix} 5 & 6 \\ 7 & 8 \end{bmatrix} = \begin{bmatrix} 5 & 12 \\ 21 & 32 \end{bmatrix}
```
- 与标准矩阵乘法不同,Hadamard积满足交换律($A \odot B = B \odot A$),且要求两个矩阵维度相同。它在机器学习中广泛用于门控机制:通过与一个取值在0到1之间的掩码逐元素相乘,控制每个条目"通过"多少。
- 两个向量 $\mathbf{u}$ 和 $\mathbf{v}$ 的**外积**产生一个矩阵:$\mathbf{u}\mathbf{v}^T$。每个条目是 $\mathbf{u}$ 的一个元素与 $\mathbf{v}$ 的一个元素的乘积:
```math
\begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix} \begin{bmatrix} 4 & 5 \end{bmatrix} = \begin{bmatrix} 4 & 5 \\ 8 & 10 \\ 12 & 15 \end{bmatrix}
```
- 结果总是秩为1,因为每一行都是 $\mathbf{v}^T$ 的缩放版本。任何矩阵都可以写成秩-1外积之和,这正是SVD所做的事情(见分解章节)。
- 矩阵乘法的计算开销很大。两个 $n \times n$ 矩阵相乘需要 $O(n^3)$ 次运算。对于一个 $1000 \times 1000$ 的矩阵,那就是十亿次乘法。
- 当矩阵是**稀疏的**(大部分为零)时,朴素的乘法会浪费时间乘以零。**压缩稀疏行(CSR)**格式只存储非零元素及其位置:
- **值**:按行顺序排列的非零条目
- **列索引**:每个值属于哪一列
- **行偏移**:每一行在值列表中的起始位置
- 例如,矩阵:
```math
A = \begin{bmatrix} 5 & 0 & 0 & 2 \\ 0 & 0 & 3 & 0 \\ 0 & 0 & 0 & -1 \end{bmatrix}
```
- 存储为:values = [5, 2, 3, -1], columns = [0, 3, 2, 3], row offsets = [0, 2, 3, 4]。这跳过了所有零,使稀疏运算快得多。
- 矩阵的一个核心用途是求解**线性方程组**。方程组 $A\mathbf{x} = \mathbf{b}$ 问的是:"什么向量 $\mathbf{x}$ 被 $A$ 变换后,会得到 $\mathbf{b}$"
- 例如,假设你在买水果。苹果每个 $x_1$ 元,香蕉每个 $x_2$ 元。已知2个苹果和1个香蕉共5元,1个苹果和3个香蕉共10元。用矩阵形式表示:
```math
\begin{bmatrix} 2 & 1 \\ 1 & 3 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \end{bmatrix} = \begin{bmatrix} 5 \\ 10 \end{bmatrix}
```
- 矩阵逐行乘以向量(每一行与 $[x_1, x_2]^T$ 点积)得到两个方程:
$$2x_1 + 1x_2 = 5 \qquad \text{(第1行)} \qquad \qquad x_1 + 3x_2 = 10 \qquad \text{(第2行)}$$
- 从第1行得 $x_2 = 5 - 2x_1$。代入第2行:$x_1 + 3(5 - 2x_1) = 10$,解得 $x_1 = 1$,则 $x_2 = 3$。苹果每个1元,香蕉每个3元。
- 验证——结果正确:
```math
\begin{bmatrix} 2 & 1 \\ 1 & 3 \end{bmatrix} \begin{bmatrix} 1 \\ 3 \end{bmatrix} = \begin{bmatrix} 2 + 3 \\ 1 + 9 \end{bmatrix} = \begin{bmatrix} 5 \\ 10 \end{bmatrix}
```
- 如果 $A$ 有逆矩阵,解就是简单的 $\mathbf{x} = A^{-1}\mathbf{b}$。但直接计算逆矩阵代价高昂且数值不稳定。实践中我们使用分解方法。
- 并非所有矩阵都是方阵,也不是所有方阵都可逆。**伪逆** $A^+$ 将逆推广到任意矩阵。它总是存在,并提供"尽可能好的"逆:
$$A^+ = (A^TA)^{-1}A^T$$
- 当 $A$ 是下三角矩阵时,通过**前向代入**求解 $L\mathbf{x} = \mathbf{b}$ 很容易:先解出 $x_1$,然后用它求出 $x_2$,依此类推。
- 当 $A$ 是上三角矩阵时,通过**回代**求解 $U\mathbf{x} = \mathbf{b}$:先解出最后一个变量,然后向上求解。
- 这就是为什么将矩阵分解为三角因子(如分解章节所述)如此有用——它将一个难题转化为两个简单问题。
## 编程练习(使用CoLab或Jupyter Notebook
1. 将两个矩阵相乘并验证维度。然后交换顺序,观察结果如何变化(或者,如果维度不匹配,运算失败)。
```python
import jax.numpy as jnp
A = jnp.array([[1.0, 2.0],
[3.0, 4.0]])
B = jnp.array([[5.0, 6.0],
[7.0, 8.0]])
print(f"A @ B:\n{A @ B}")
print(f"B @ A:\n{B @ A}")
print(f"Equal: {jnp.allclose(A @ B, B @ A)}")
```
2. 求解线性方程组 $A\mathbf{x} = \mathbf{b}$,并通过回代乘法验证解。尝试改变 $\mathbf{b}$,观察解如何变化。
```python
import jax.numpy as jnp
A = jnp.array([[2.0, 1.0],
[5.0, 3.0]])
b = jnp.array([4.0, 7.0])
x = jnp.linalg.solve(A, b)
print(f"Solution x: {x}")
print(f"A @ x: {A @ x}")
```