现在位置: 首页 > AI 数学基础 > 正文

矩阵加法与矩阵乘法

理解了向量运算之后,升级到矩阵。矩阵乘法是理解神经网络前向传播的关键——全连接层的本质就是矩阵乘法。

矩阵加法:对应位置相加

两个形状相同的矩阵,把对应位置的元素加起来——和向量加法一样直观。

矩阵乘法:行与列的点积

矩阵乘法没有「对应位置乘」那么简单。为什么?

矩阵的深层含义是「线性变换」——它会把一个向量映射到另一个向量。

两个矩阵相乘 AB,在几何上的意思是:先做 B 变换,再做 A 变换。所以 AB 的运算法则必须反映「复合变换」的数学结构,而不是简单的逐元素相乘。

例如:A 表示「水平拉伸 2 倍」, B 表示「逆时针旋转 90°」。AB 表示「先旋转再拉伸」——这与 BA(先拉伸再旋转)完全不同,所以矩阵乘法不满足交换律。

运算法则是:

左矩阵
第 i 行 →
·
右矩阵
第 j 列 ↓
=
结果
(i, j)

左矩阵的第 i 行与右矩阵的第 j 列做点积 → 结果矩阵的 (i, j) 位置的值。

维度匹配规则

\( (m \times \color{#e74c3c}{n}) \;\times\; (\color{#e74c3c}{n} \times p) = (m \times p) \)

A 的列数 必须等于 B 的行数。两个标红的 n 必须相等。

结果的形状 = (A 的行数, B 的列数)

矩阵乘法 不满足交换律:AB ≠ BA(通常情况)。

甚至维度可能不匹配导致 BA 无定义——这是初学者最容易出错的地方。

矩阵乘法的本质是线性变换的复合

乘以矩阵 A → 做完一次变换;再乘以矩阵 B → 做完第二次变换。

两次变换复合 = 一次 (BA) 变换。这就是矩阵乘法这样定义的原因。


生活例子

小卖部收入计算

三天的销量矩阵(行=日期,列=商品):

可乐薯片泡面
周一1053
周二874
周三1246

价格矩阵(行=商品,列=店铺):

店铺1店铺2
可乐33.5
薯片55.5
泡面44.0

销量矩阵 (3×3) × 价格矩阵 (3×2) = 收入矩阵 (3×2)。

结果的每一格 = 某天在某个店铺的总收入。


数学定义

矩阵加法

\[ (\mathbf{A} + \mathbf{B})_{ij} = a_{ij} + b_{ij} \]

前提:A 和 B 形状完全相同。

矩阵乘法

设 A 为 m×n,B 为 n×p,则 C = AB 为 m×p:

\[ c_{ij} = \sum_{k=1}^{n} a_{ik} b_{kj} \]

Python 动手实践

实例

import numpy as np

A_runoob = np.array([[10, 5, 3], [8, 7, 4], [12, 4, 6]])
price = np.array([[3, 3.5], [5, 5.5], [4, 4.0]])

# 矩阵加法(同形状)
bonus = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
total = A_runoob + bonus
print("A + bonus:\n", total)

# 矩阵乘法:(3×3) @ (3×2) = (3×2)
revenue = A_runoob @ price
print("\n收入矩阵 A @ price:\n", revenue)
print("形状:", revenue.shape)

# 手动验证第(0,0)位置
manual = A_runoob[0,0]*price[0,0] + A_runoob[0,1]*price[1,0] + A_runoob[0,2]*price[2,0]
print(f"\n手动验证 [0,0]: {manual} == {revenue[0,0]}")

# 维度不匹配的陷阱
print(f"\nA 形状: {A_runoob.shape}")     # (3, 3)
print(f"price.T 形状: {price.T.shape}")   # (2, 3)
# A @ price.T → (3,3) @ (2,3) 不匹配!
# 正确:price.T @ A → (2,3) @ (3,3) = (2,3)
print(f"price.T @ A 形状: {(price.T @ A_runoob).shape}")  # (2, 3)
收入矩阵 A @ price:
 [[67.  72. ]
 [75.  79.5]
 [80.  88. ]]
形状: (3, 2)

A 形状: (3, 3)
price.T 形状: (2, 3)
price.T @ A 形状: (2, 3)

交互式矩阵乘法可视化

下方演示 2×2 矩阵 A 乘以 2×1 向量 v,观察线性变换如何将圆上的点映射到椭圆上:


AI 中的应用场景

全连接层 = 矩阵乘法

nn.Linear(d_in, d_out) 的本质:权重矩阵 W(d_out × d_in)乘以输入向量 x(d_in 维),得到输出(d_out 维)。

处理 batch 数据时,输入 X 是 (batch, d_in) 矩阵,计算 \( Y = XW^T \) 或 \( Y = WX^T \),这是一次矩阵乘法完成整个 batch 的前向计算。GPU 对矩阵乘法有专门硬件加速(Tensor Core)。

注意力机制的 QK^T

Transformer 中 Q 和 K 都是 (seq_len, d_k) 矩阵。\( QK^T \) 是 seq_len×d_k 乘 d_k×seq_len,得到 (seq_len, seq_len) 的注意力分数矩阵。

GPT-4 级别的大模型中,seq_len 可达 128K,这个矩阵乘法的计算量占整个推理成本的很大一部分。FlashAttention 算法就是专门优化这个矩阵乘法的显存访问模式。

卷积的矩阵乘法实现(im2col)

卷积操作可以展开为矩阵乘法:把输入图像按滑动窗口展开为一个大矩阵(im2col),然后把卷积核也展平为矩阵,两者相乘。这让卷积能利用高度优化的 GEMM(通用矩阵乘法)库来加速。

LoRA 微调中的矩阵分解

LoRA 在预训练权重旁加两个小矩阵 A 和 B 的乘积:\( W' = W + AB \)。这里的 AB 就是矩阵乘法——A 是 d×r,B 是 r×d,乘积是 d×d 的低秩矩阵。一个矩阵乘法实现了参数高效的微调。