目录
矩阵
1. 先回顾一下向量
你刚才已经掌握:
- snippet.text
A = [1, 2, 3]
这是一个 3 维向量。
可以把它想成:
- snippet.text
CPU Memory GPU ↓ ↓ ↓ 80 60 90
也就是:
- snippet.text
A = [80, 60, 90]
一个对象的一组特征。
2. 那么矩阵是什么?
最简单的理解:
**矩阵就是把很多向量按照一定规则排在一起。**
例如:
- snippet.text
A = [ 1 2 3 4 5 6 7 8 9 ]
这个矩阵有:
- snippet.text
3 行 3 列
所以叫:
**3 × 3 矩阵**
—
3. 用你的测试工作理解矩阵
假设你测试了 4 台服务器:
| Server | CPU | Memory | GPU |
| ——– | –: | —–: | –: |
| Server A | 80 | 60 | 90 |
| Server B | 70 | 50 | 80 |
| Server C | 90 | 70 | 95 |
| Server D | 50 | 40 | 60 |
可以变成:
- snippet.text
X = [ 80 60 90 70 50 80 90 70 95 50 40 60 ]
那么:
- snippet.text
X.shape = 4 × 3
意思就是:
- snippet.text
4 个对象 3 个特征
这其实已经非常接近机器学习中的真实数据了。
4. 矩阵的行和列分别是什么?
例如:
- snippet.text
X = [ 80 60 90 70 50 80 90 70 95 50 40 60 ]
第一行
- snippet.text
[80,60,90]
代表:
Server A
### 第二行
- snippet.text
[70,50,80]
代表:
Server B
而第一列:
- snippet.text
80 70 90 50
代表:
CPU
第二列:
- snippet.text
60 50 70 40
代表:
Memory
第三列:
- snippet.text
90 80 95 60
代表:
GPU
所以可以记:
**行通常代表样本,列通常代表特征。**
当然这不是数学上的硬性规定,实际工程里可以根据数据组织方式不同而变化。
5. 矩阵的“形状”
这个概念以后你会天天遇到。
比如:
- snippet.text
X = [ 1 2 3 4 5 6 ]
它有:
- snippet.text
2 行 3 列
所以:
- snippet.text
shape = (2,3)
注意:
- snippet.text
(行, 列)
所以:
- snippet.text
(2,3)
不是:
- snippet.text
3行2列
而是:
**2 行 3 列**
—
6. 为什么 AI 特别需要矩阵?
假设你有:
- snippet.text
10000 个样本
每个样本:
- snippet.text
100 个特征
如果每个样本都是一个向量:
- snippet.text
x1 x2 x3 ... x10000
就可以把它们组成:
形状:
- snippet.text
10000 × 100
于是整个数据集可以一次性交给 GPU:
- snippet.text
CPU ↓ Tensor ↓ GPU ↓ 矩阵运算
而不是:
- snippet.text
for 每一个样本: 一个一个算
这就是 AI 为什么喜欢批量计算。
7. 矩阵加法
这个非常简单。
假设:
- snippet.text
A = [ 1 2 3 4 ]
- snippet.text
B = [ 5 6 7 8 ]
那么:
- snippet.text
A+B
就是对应位置相加:
- snippet.text
[ 1+5 2+6 3+7 4+8 ]
得到:
- snippet.text
[ 6 8 10 12 ]
注意:
**两个矩阵必须具有相同的形状,才能直接做矩阵加法。**
—
8. 矩阵乘法才是重点
这部分我们慢慢来。
假设:
- snippet.text
A = [ 1 2 3 4 ]
- snippet.text
B = [ 5 6 7 8 ]
计算:
- snippet.text
A × B
很多人第一次会误以为:
- snippet.text
[ 1×5 2×6 3×7 4×8 ]
这是:
- snippet.text
[ 5 12 21 32 ]
但是这个结果不是矩阵乘法。
9. 矩阵乘法真正的规则
记住一句:
**左边矩阵的“行”,乘右边矩阵的“列”。**
还是:
- snippet.text
A = [ 1 2 3 4 ]
- snippet.text
B = [ 5 6 7 8 ]
先算结果左上角:
- snippet.text
A[第一行] · B[第一列]
也就是:
- snippet.text
[1,2] · [5,7]
刚才我们已经学过点积:
- snippet.text
1×5 + 2×7
所以:
- snippet.text
= 19
10. 再算右上角
A 第一行:
- snippet.text
[1,2]
B 第二列:
- snippet.text
[6,8]
点积:
- snippet.text
1×6 + 2×8
得到:
- snippet.text
22
所以结果第一行:
- snippet.text
[19,22]
11. 再算第二行
A 第二行:
- snippet.text
[3,4]
B 第一列:
- snippet.text
[5,7]
点积:
- snippet.text
3×5 + 4×7
得到:
- snippet.text
43
然后:
- snippet.text
[3,4] · [6,8]
得到:
- snippet.text
3×6 + 4×8 = 50
所以最终:
- snippet.text
A × B = [ 19 22 43 50 ]
12. 现在你应该发现一个很重要的东西
矩阵乘法:
- snippet.text
A × B
其实就是:
**大量的向量点积。**
也就是说:
- snippet.text
矩阵乘法 ↓ 很多次点积 ↓ 很多次乘法 + 加法
这就开始和 GPU 联系起来了。
13. 为什么 GPU 特别擅长 AI?
刚才一个 2×2 矩阵,计算量很小。
但是如果:
- snippet.text
A = 4096 × 4096 B = 4096 × 4096
那么需要做海量的:
- snippet.text
乘法 + 加法
而 GPU 可以同时处理大量这些操作。
于是:
- snippet.text
神经网络 ↓ 矩阵乘法 ↓ 大量乘加 ↓ GPU ↓ Tensor Core
你作为测试工程师以后会经常看到:
- snippet.text
FLOPS TFLOPS Matrix Multiplication GEMM Tensor Core
现在你已经知道它们背后的数学基础是什么了。
14. 一个非常重要的规则:维度必须匹配
假设:
- snippet.text
A.shape = (2,3)
也就是:
- snippet.text
A = [ 1 2 3 4 5 6 ]
如果:
- snippet.text
B.shape = (3,4)
那么:
- snippet.text
A × B
是可以计算的。
因为:
- snippet.text
(2 × 3) × (3 × 4)
中间两个:
- snippet.text
3 3
匹配。
结果:
- snippet.text
(2 × 4)
所以:
- snippet.text
(2×3) × (3×4) = (2×4)
这个规则非常重要。
15. 记一个口诀
矩阵:
- snippet.text
(m × n)
乘:
- snippet.text
(n × p)
结果:
- snippet.text
(m × p)
也就是:
- snippet.text
(m × n) × (n × p) ↑ 中间必须相同
最终:
- snippet.text
(m × p)
你以后看到 PyTorch:
- snippet.python
A @ B
如果报:
- snippet.text
mat1 and mat2 shapes cannot be multiplied
基本就是:
**矩阵维度对不上。**
—
16. 用神经网络理解矩阵乘法
假设一个神经网络有:
- snippet.text
输入层:3 个特征 输出层:2 个神经元
输入:
- snippet.text
X = [CPU, Memory, GPU]
比如:
- snippet.text
X = [80,60,90]
模型有一个权重矩阵:
- snippet.text
W = [ 0.1 0.2 0.3 0.4 0.5 0.6 ]
那么:
- snippet.text
X × W
就是:
- snippet.text
[80,60,90] × [ 0.1 0.2 0.3 0.4 0.5 0.6 ]
得到两个输出:
- snippet.text
Neuron 1 Neuron 2
所以你可以把神经网络的一层粗略理解成:
**输入向量 × 权重矩阵 → 输出向量**
也就是:
- snippet.text
XW
这就是你以后会反复看到的:
- snippet.text
Y = XW + b
17. 这就是“权重”到底是什么
以后你看到:
- snippet.text
Model Parameters Weights Parameters
不要觉得玄学。
最简单的理解:
- snippet.text
输入 ↓ 乘上一堆数字 ↓ 得到输出
这些“数字”就是:
**模型参数/权重。**
训练过程实际上就是:
**不断调整这些数字,让模型的预测越来越好。**
这就又和我们上一节说的:
- snippet.text
Loss ↓ Gradient ↓ 调整参数
连接起来了。
18. 到这里,把两节课串起来
你现在已经可以看到 AI 的一个基本骨架:
- snippet.text
现实世界 ↓ 数字 ↓ 向量 ↓ 矩阵 ↓ 矩阵乘法 ↓ 神经网络 ↓ 预测 ↓ Loss ↓ Gradient ↓ 调整矩阵里的参数
这条链非常重要。
19. 再往前一步:转置
最后讲一个以后一定会遇到的概念:
**Transpose,转置。**
例如:
- snippet.text
A = [ 1 2 3 4 5 6 ]
这是:
- snippet.text
2 × 3
转置之后:
- snippet.text
Aᵀ = [ 1 4 2 5 3 6 ]
变成:
- snippet.text
3 × 2
简单理解:
**行和列交换。**
所以:
- snippet.text
(2×3)
转置:
- snippet.text
(3×2)
20. 为什么转置很重要?
因为矩阵乘法经常需要调整维度。
例如:
- snippet.text
Q × Kᵀ
你以后学 Attention 时一定会看到这个。
现在你已经知道:
- snippet.text
Kᵀ
就是:
**把 K 的行列交换。**
所以以后看到:
- snippet.text
QKᵀ
至少不会觉得像某种外星文明的符号。
21. 今天先到这里
你现在已经掌握了:
- snippet.text
向量 ↓ 维度 ↓ 向量加减 ↓ 向量长度 ↓ 点积 ↓ 矩阵 ↓ 矩阵形状 ↓ 矩阵加法 ↓ 矩阵乘法 ↓ 矩阵维度匹配 ↓ 转置
其中最重要的是这三个:
① 点积
- snippet.text
[a,b,c] · [x,y,z] = ax + by + cz
② 矩阵乘法
③ 维度规则
- snippet.text
(m×n) × (n×p) = (m×p)
