【老计带你懂线性代数】05:矩阵乘法,神经网络的核心运算
开头:AI算力烧在哪儿
当你听到训练大模型需要几万张GPU、耗电惊人,可能会问,这些算力到底在算什么?答案很朴素,绝大部分时间都在做矩阵乘法。
从最小的神经网络到千亿参数大模型,最核心、最耗算力的运算就是一个个巨大的矩阵相乘。矩阵乘法是AI发动机里转得最快的齿轮。可它也是线性代数里最让新手头疼的概念之一,尤其是"为什么要这么乘"。
这一篇不死背规则,而是从两个直觉讲透它:矩阵乘法是批量做点积,也是把两次变换组合成一次。懂了这两个视角,规则就不再莫名其妙。
矩阵乘向量:一次算出多个点积
先从简单的矩阵乘向量说起。
假设一个矩阵有3行、每行2个数(3乘2),拿它乘一个2维向量。怎么算?矩阵的每一行,分别和这个向量做一次点积,三个点积结果摞起来,得到一个3维的新向量。
回忆上一篇,一个神经元的核心是"输入向量和权重向量做点积"。如果一层网络里有3个神经元,每个神经元各有一组权重(各是一行),把这3组权重摞成一个矩阵。权重矩阵乘输入向量,就能一次性把3个神经元的点积全部算出来。矩阵乘法就是把一堆点积批量打包。
打个比方:一个考生有2项成绩(输入向量),3位评委各有一套打分权重(矩阵的3行),每位评委都把成绩按自己的权重算个总分(一次点积)。矩阵乘向量,就是让3位评委同时打分,一次得到3个结果。
这解释了矩阵乘法为什么那么定义,它不是数学家拍脑袋造怪规则,而是为了能把大量的点积(加权求和)整齐地批量算完。
为什么不是对应位置相乘
新手最自然的疑问是,矩阵也就是一张数字表,为什么相乘不直接把对应位置的数字相乘?NumPy里的*确实能这么做,这叫逐元素乘法,它不是没用,只是解决的是另一个问题。
逐元素乘法要求两个矩阵形状一样,结果也保持同样形状。它的含义是"每个位置只和相同位置互动",适合做掩码、缩放某些元素等操作。可它做不到一件AI最需要的事,让输入的每个特征和输出的每个神经元充分互动、重新组合。
矩阵乘法则让前一个矩阵的一整行,和后一个矩阵的一整列做点积。这意味着每个输出,都综合看了所有输入特征、按各自权重重新组合。神经网络要的正是这种"全盘综合后生成新特征"的能力,而不是只让第一个特征碰第一个权重、第二个碰第二个,彼此老死不相往来。
打个比方:逐元素相乘像一对一结对子,每个人只和固定搭档合作;矩阵乘法像开会,每个输出负责人都听取所有输入成员的意见,再按自己的权重综合成一个结论。后者能充分混合信息,表达能力强得多。所以矩阵乘法看似绕,实际上它的规则完全是被"批量加权综合"这个需求逼出来的,神经网络离不开它。
形状匹配:里面相同,外面留下
矩阵乘法最容易错的是形状。给你一句特别好记的口诀:里面的数字必须相同,外面的数字决定结果。
一个m乘n的矩阵,能乘一个n乘p的矩阵(中间两个n相同,才能对得上),结果是m乘p(留下外面的m和p)。写成形状就是:
m乘n 乘 n乘p = m乘p
为什么中间要相同?因为前一个矩阵每行有n个数,后一个矩阵每列也得有n个数,它们才能做点积。矩阵乘法本质是一行和一列做点积,长度必须一样。
打个比方:插头有3个脚,插座也必须有3个孔才能接上。中间的维度就是接口规格,必须匹配。接上之后,外面的维度决定最终设备的形状。编程时遇到matrix shape不匹配的报错,十有八九就是这个插头和插座没对上。
矩阵乘矩阵:批量的批量
矩阵乘向量是多个神经元同时算一个样本。那如果一次要处理一批样本呢?就用矩阵乘矩阵。
把100个样本的输入向量摞成一个100乘n的数据矩阵,再乘一个n乘m的权重矩阵,结果就是100乘m:100个样本、每个都同时通过了m个神经元,一次矩阵乘法全部算完。
这就是神经网络里的批处理(batch)。不是一个样本一个样本慢慢算,而是把一批样本堆成矩阵,和权重矩阵一次相乘。GPU最喜欢这种大批量、规则一致的计算,能调动成千上万个计算单元同时干活,速度飙升。
第二个直觉:矩阵乘法是在组合变换
除了批量点积,矩阵乘法还有个更深刻的几何直觉,它是把两次变换组合成一次。
上一篇说过,矩阵可以是一种变换。矩阵A把向量先旋转,矩阵B再把旋转后的结果拉伸。连续做这两个动作,等价于先把A和B乘起来得到一个新矩阵C,再用C一次作用在原向量上。两个矩阵相乘,得到的就是"先做第一个变换、再做第二个变换"的合成变换。
打个比方:照片编辑时,你先把图片旋转90度,再放大2倍,这是两个动作。如果经常要这么做,可以把两个动作合成一个快捷键,一按就同时旋转加放大。矩阵乘法就是在造这个组合快捷键。
这个视角解释了为什么矩阵乘法一般不满足交换律,A乘B通常不等于B乘A。先旋转再拉伸,和先拉伸再旋转,结果往往不一样,就像先穿袜子再穿鞋和先穿鞋再穿袜子不是一回事。变换有先后顺序,所以矩阵乘法有顺序,不能随便交换。
神经网络的前向传播:矩阵乘法加激活
现在把它落到AI最核心的地方。神经网络一层干的事,可以用一句话写完:
输出 = 输入矩阵 乘 权重矩阵 + 偏置,然后过激活函数。
输入矩阵是一批样本,权重矩阵代表这一层学到的变换,偏置做平移,激活函数注入非线性。前面几篇讲的向量、点积、矩阵,在这一句话里全部汇合了。
一个深度网络,就是把这个动作一层层重复:第一层矩阵乘法把原始特征变成一组初级特征,激活;第二层再乘另一个权重矩阵变成更高级特征;层层往下,最终得到预测。从线代视角看,神经网络就是一串"矩阵乘法加非线性"。矩阵乘法负责线性变换,激活函数负责把它掰弯,两者配合才有强大能力。
为什么GPU特别擅长矩阵乘法
矩阵乘法包含海量的"乘一下再加一下",而且每个元素的计算彼此独立、规则完全一样,特别适合并行。
CPU像几个全能的高级工,什么复杂活都能干,但人数少;GPU像成千上万个只会做简单乘加的小工人,单个不聪明,但一声令下能同时算矩阵里的不同位置。AI训练恰好有铺天盖地、格式整齐的乘加任务,正好喂饱GPU。
这也是我做AI Infra特别关注的核心,GPU、显存、并行策略、通信,最终都是为了让这些巨大矩阵乘法跑得更快、更高效。硬件在围着算法转,而算法的核心计算就是矩阵乘法。
输入和输出长什么样
- 输入:两个形状匹配的矩阵(或矩阵和向量)。
- 输出:一个新矩阵(或新向量),形状由外面的两个维度决定。
- NumPy里用
@或np.matmul做矩阵乘法,注意不是*(*是对应位置相乘,完全不同)。
上代码:从矩阵乘法到神经网络前向传播
# 依赖:pip install numpyimportnumpyasnp# 1.矩阵乘向量:3位评委(3行权重),给一个2项成绩的考生打分W=np.array([[0.8,0.2],[0.5,0.5],[0.2,0.8],])# 形状(3,2)x=np.array([90,70])# 形状(2,)y=W @ x# 结果形状(3,)print("3位评委的加权分:",y)print("形状:",W.shape,"@",x.shape,"=",y.shape)# 2.矩阵乘矩阵:一批4个样本,每个2特征,一次过3个神经元X=np.array([[1,2],[3,4],[5,6],[7,8]])# (4,2)W2=np.array([[0.1,0.2,0.3],[0.4,0.5,0.6]])# (2,3)Z=X @ W2# (4,3)print("\n批量计算结果:\n",Z)print("形状:",X.shape,"@",W2.shape,"=",Z.shape)# 3.极简神经网络一层:矩阵乘法+偏置+ReLU激活b=np.array([0.1,-0.2,0.3])# 3个神经元各一个偏置Z=X @ W2+b# 线性变换A=np.maximum(0,Z)# ReLU:负数变0print("\n神经网络一层输出(ReLU后):\n",A)# 4.证明顺序不能换:旋转和缩放先后结果不同rotate=np.array([[0,-1],[1,0]])# 旋转90度scale=np.array([[2,0],[0,1]])# x方向拉伸2倍v=np.array([1,1])print("\n先旋转再缩放:",scale @ rotate @ v)print("先缩放再旋转:",rotate @ scale @ v)运行输出(示例):
3位评委的加权分: [86. 80. 74.] 形状: (3, 2) @ (2,) = (3,) 批量计算结果: [[ 0.9 1.2 1.5] [ 1.9 2.6 3.3] [ 2.9 4. 5.1] [ 3.9 5.4 6.9]] 形状: (4, 2) @ (2, 3) = (4, 3) 神经网络一层输出(ReLU后): [[1. 1. 1.8] [2. 2.4 3.6] [3. 3.8 5.4] [4. 5.2 7.2]] 先旋转再缩放: [-2 1] 先缩放再旋转: [-1 2]运行你会看到:矩阵乘向量一次算出3个点积;矩阵乘矩阵一次处理4个样本和3个神经元;加偏置和ReLU就是完整的神经网络一层;最后先旋转再缩放和先缩放再旋转结果不同,证明矩阵乘法的顺序不能乱。
常见误区
@和*完全不同:@是矩阵乘法(行和列做点积),*是对应元素相乘。写错了可能不报错但结果完全错,是最危险的坑。- 形状必须匹配:记住"里面相同、外面留下",随时打印shape检查。
- 顺序不能换:矩阵乘法一般不满足交换律,因为变换的先后有影响。
- 别只背计算规则:始终抓住两个直觉,批量点积、组合变换,理解比手算重要。
小结与承上启下
- 矩阵乘法是批量点积:一次算多个神经元、多个样本,是批处理的数学基础。
- 形状口诀:里面相同、外面留下,m乘n乘n乘p得到m乘p。
- 矩阵乘法是组合变换:先做一个变换再做另一个,顺序不能乱。
- 神经网络核心:输入矩阵乘权重矩阵加偏置再过激活,深度网络就是这个动作层层重复。
- GPU为什么快:矩阵乘法有海量独立乘加,天生适合成千上万核心并行。
到这里,向量、点积、矩阵、矩阵乘法这几个最基本的零件都齐了。下一步我们把"矩阵是一种变换"这个视角彻底展开,看看一个矩阵怎么在几何空间里旋转、缩放、投影一个向量,又怎么把数据揉成模型容易分类的形状。
我们下一篇见。
延伸阅读
- 3Blue1Brown《线性代数的本质》:矩阵乘法与线性变换的组合:https://www.3blue1brown.com/topics/linear-algebra
- NumPy 官方文档:矩阵乘法np.matmul:https://numpy.org/doc/stable/reference/generated/numpy.matmul.html
- PyTorch 官方文档:线性层nn.Linear:https://pytorch.org/docs/stable/generated/torch.nn.Linear.html
(说明:以上为官方与经典公开资料地址,可能随版本调整,如打不开可用标题搜索。)