本文目录
先别背公式,点一个格子
下面右侧结果矩阵有四个格子。点其中任意一个,左矩阵的一行和右矩阵的一列会同时亮起。
矩阵乘法演示
点一个结果格,查看对应的行列计算
结果第 i 行第 j 列,来自 A 的第 i 行与 B 的第 j 列逐项相乘再相加。
C1,1 = 第 1 行 · 第 1 列
1×7 + 2×9 + 3×11 = 58
这说明矩阵乘法的最小动作并不神秘:一行和一列做向量点积,对应位置相乘,再把乘积相加。例如左上角是
一个点积产生一个标量(单独的数);所有“行 × 列”的结果排回表格,才组成新矩阵。
三种“乘”不要混用
向量点积把两个等长向量压成一个数。哈达玛积(Hadamard Product,逐元素乘法)则保留每一个对应位置,例如 [1,2] ⊙ [3,4] = [3,8]。矩阵乘法会重复执行“行乘列”,形状规则是:
因此 4×6 不能右乘 5×6,但可以右乘 6×5。口语里的“矩阵点乘”容易把点积和矩阵乘法混在一起,写公式时最好直接说清是哪一种。
从一个结果格推到整个结果矩阵
设左矩阵 A 是 2×3,右矩阵 B 是 3×2。A 有两行,表示有两组待处理数字;B 有两列,表示要生成两个输出特征。结果 C 的行数继承 A,列数继承 B,因此是 2×2。
点击交互中的 C₁₂ 时,程序取 A 的第 1 行 [1,2,3] 和 B 的第 2 列 [8,10,12]:
下标已经写明位置:第一个数字 1 表示取左矩阵第 1 行,第二个数字 2 表示取右矩阵第 2 列。换到 C₂₁,就改成 A 第 2 行与 B 第 1 列。只要能独立算出一个格子,整个矩阵乘法只是把同样动作覆盖到所有行列组合。
向量既能写成一行,也能写成一列
[5,6] 若作为行向量,形状是 1×2;竖着写则是列向量,形状是 2×1。两个数字相同,但它们参与矩阵乘法时的方向不同:
1×2乘2×1,得到1×1,也就是一个标量;2×1乘1×2,得到2×2,也叫外积(outer product);2×2矩阵乘2×1列向量,得到新的2×1向量。
所以“向量有几个数字”描述维度,“横着还是竖着”描述它在当前运算里的形状。写程序时,shape(形状)通常比肉眼看到的括号更重要。
转置为什么常出现
转置(Transpose)把行列互换。一个 4×3 矩阵转置后是 3×4,于是 4×3 可以乘 3×4,得到 4×4。
自注意力里的 QKᵀ 正是这个形状安排。设三个 Token、每个 Query/Key 两维:
Q形状3×2(行 = Token,列 = 特征)K也是3×2- 直接算
QK对不上:2 ≠ 3 - 先把
K转置成2×3,再算QKᵀ,得到3×3注意力分数矩阵
每个格子仍是一次向量点积:第 i 个 Query 与第 j 个 Key 的兼容分数。
全连接层两种写法:Wx 与 XW
教材常写列向量习惯:
此时 x 是 d_in×1,W 是 d_out×d_in,权重矩阵的一行对应一个输出神经元要用的整组权重。
深度学习代码与 Transformer 文章更常按“样本/Token 在行上”写:
此时 X 是 n×d_in(n 个样本或 Token),W 是 d_in×d_out,权重矩阵的一列对应一个输出神经元。两种写法数学等价,差一个转置:W_code = W_textbookᵀ。
读公式时先问一句:Token(或样本)是在行上,还是写成竖着的列向量? 不要把“W 的一行 = 一个输出”当成永恒真理——那只在 y=Wx 约定下成立。后面看到 XW_Q、XW_K、XW_V,用的就是行上排 Token 的约定。
为什么神经网络偏爱矩阵计算
若一层有 1000 个输入和 500 个输出神经元,逐个写公式需要重复 500 次点积。把权重排成矩阵后,一次矩阵乘法就能同时计算全部输出;再把多个样本叠成批次,还能让 GPU 并行处理。
矩阵不是另一套神秘神经网络,而是对重复计算的组织方式:一次“行 × 列”对应一次加权求和。理解这一点后,连续出现的 XW_Q、QKᵀ、AV 只需要继续追踪每个矩阵的行、列分别代表什么。
读式子时的两步检查
- 能不能乘:看中间维度是否相等(
n对上n)。 - 结果多大:外侧维度留下来(
m×p)。
再补第三步:标出“谁是样本维、谁是特征维”。这一步能避免把 QKᵀ 的 3×3 误读成特征维相乘,也能避免在 y=Wx 与 Y=XW 之间串台。