深度必备的数学基础复习向
1 标量 Scalar
一个孤零零的数字,它没有维度,没有方向,只有大小。
温度 25℃,体重 55kg,长度 2 米 。这些都是标量。几何里,标量不像箭头,它更像是一个数值刻度,比如你在数轴上说 3,它只是一个位置对应的数字,不带方向信息。
2 向量 Vector
排成一排的数字,感觉就像是数组一列的感觉。在代码里生成的一个向量,b = torch.randn(3) 生成一个长度为 3 的一维数组(向量),比如 [0.1, -0.5, 0.8]。
标量:3
向量:[ 3 4 ] \begin{bmatrix}3\\4\end{bmatrix} [ 3 4 ]
标量只有1一个信息。向量多个信息打包在一起。例如一个人的两个特征⬇️
就可以写成向量:[ 160 50 ] \begin{bmatrix}160 \\50\end{bmatrix} [ 160 50 ] 表示这个对象里有两个数。上面是一个2维向量。
再比如 [ 4 − 1 2 ] \begin{bmatrix}4 \\-1 \\2\end{bmatrix} 4 − 1 2 这是一个 3 维向量。
几何里,向量通常可以看成一个箭头(arrow)。比如[2,3],表示
也就是一个从原点指向 (2,3) 的箭头,向量不是单纯一堆数字,它代表:方向 + 长度 。
那么向量里的维度是什么呢?里面有几个数字,就是几维。上面一个2维的例子和一个3维的例子已经给了。有10个数字,那肯定就是10维。
向量的长度
既然几何上向量是箭头,那自然会问这个箭头有多长?
[ 3 4 ] \begin{bmatrix}3 \\4\end{bmatrix} [ 3 4 ]
它的长度就是 3 2 + 4 2 = 5 \sqrt{3^2+4^2}=5 3 2 + 4 2 = 5
这其实就是勾股定理。所以二维向量 [ x y ] \begin{bmatrix}x \\y\end{bmatrix} [ x y ] 的长度就是 x 2 + y 2 \sqrt{x^2+y^2} x 2 + y 2
几何意义就是表示原点到点 (x,y) 的直线距离。向量为什么长度重要,因为向量不只是方向,还带有多大的信息。
[ 1 0 ] 和 [ 10 0 ] \begin{bmatrix}1 \\0\end{bmatrix}\quad \text{和} \quad\begin{bmatrix}10 \\0\end{bmatrix} [ 1 0 ] 和 [ 10 0 ]
它们方向一样,都是向右。 但第二个明显更长。所以长度在几何和机器学习里都很重要。
向量加法
假设有两个向量 a = [ 2 1 ] , b = [ 3 4 ] \mathbf{a}=\begin{bmatrix}2 \\1\end{bmatrix},\quad\mathbf{b}=\begin{bmatrix}3 \\4\end{bmatrix} a = [ 2 1 ] , b = [ 3 4 ]
它们相加 a + b = [ 2 + 3 1 + 4 ] = [ 5 5 ] \mathbf{a}+\mathbf{b}=\begin{bmatrix}2+3 \\1+4\end{bmatrix}=\begin{bmatrix}5 \\5\end{bmatrix} a + b = [ 2 + 3 1 + 4 ] = [ 5 5 ]
几何上怎么理解?向量加法就是。先走向量 a,再走向量 b。最后总效果就是 a + b 。几何上向量加法代表『 位移叠加』 。
向量乘法
首先这个说话比较容易混淆,因为向量乘法是有分类的,不同于我们平常说的标量的乘法,向量的乘法可不止一种。首先你要打破一下常规的乘法想法,并且,以后最好不要单说『 向量乘法』 ,而是说清楚是点积还是其他乘法。
首先说分类(也许这个分类不完美,但是是有意义的)
点积(dot product)
外积(outer product)
普通乘法
先说普通乘法好了。
逐元素乘法(Element-wise Multiplication)
这个重要性,不如点积。在 PyTorch 里,普通乘法用星号 * 表示(数学上叫作「 哈达玛积 Hadamard product」 )。核心思想就是互不干涉。互相独立。
首先就是普通的向量 * 标量的标乘
2 ∗ A = [ 1 2 3 4 ] = [ 2 4 6 8 ] 2* A=\begin{bmatrix}1 & 2\\3 & 4\end{bmatrix} = \begin{bmatrix}2 & 4\\6 & 8\end{bmatrix} 2 ∗ A = [ 1 3 2 4 ] = [ 2 6 4 8 ]
动作 :拿一个孤零零的数字(标量),去乘以一个向量。
底层发生了什么 :触发广播机制。标量会自动「 分身」 ,复制成和向量一样长,然后大家对号入座,各自相乘(普通乘法)。
结果 :形状不变。 输入一个长度为 3 的向量,输出还是长度为 3 的向量。只是里面的数字被等比例放大了。
物理意义 :「 等比例缩放」 。比如把所有的特征翻 2 倍。
import torch
v = torch.tensor([1 , 2 , 3 ])
scalar = 3
print (scalar * v)
如果是2个同形状矩阵
A = [ 1 2 3 4 ] , B = [ 5 6 7 8 ] A=\begin{bmatrix}1 & 2\\3 & 4\end{bmatrix},B=\begin{bmatrix}5 & 6\\7 & 8\end{bmatrix} A = [ 1 3 2 4 ] , B = [ 5 7 6 8 ]
逐元素乘法就位置对位置地乘。 本质就是同位置普通乘法,就跟数组一样。
A ⊙ B = [ 1 × 5 2 × 6 3 × 7 4 × 8 ] = [ 5 12 21 32 ] A \odot B=\begin{bmatrix}1\times5 & 2\times6\\3\times7 & 4\times8\end{bmatrix}=\begin{bmatrix}5 & 12\\21 & 32\end{bmatrix} A ⊙ B = [ 1 × 5 3 × 7 2 × 6 4 × 8 ] = [ 5 21 12 32 ]
假设你有两个向量(形状一模一样)
向量 A = [ 2 , 3 , 4 ] A = [2, 3, 4] A = [ 2 , 3 , 4 ]
向量 B = [ 5 , 2 , 1 ] B = [5, 2, 1] B = [ 5 , 2 , 1 ]
如果你执行 A * B,它会把第 1 个数和第 1 个数乘,第 2 个数和第 2 个数乘……
输出的结果,依然是一个形状完全相同的新向量,比如下面。
A ∗ B = [ 2 × 5 , 3 × 2 , 4 × 1 ] = [ 10 , 6 , 4 ] A * B = [2 \times 5, \ 3 \times 2, \ 4 \times 1] = \mathbf{[10, 6, 4]} A ∗ B = [ 2 × 5 , 3 × 2 , 4 × 1 ] = [ 10 , 6 , 4 ]
就好像你开了一家超市,今天卖了 2 个苹果、3 根香蕉、4 瓶水(向量A)。它们的单价分别是 5元、2元、1元(向量B)。普通乘法算出来的,是一张「 明细账单」 :苹果卖了 10 元,香蕉卖了 6 元,水卖了 4 元。每一个商品各自算各自的,没有任何交集。
点积(内积) dot product ⭐️
🔥 问了AI,点积和内积在此时是一个意思,以后都以英文为准,叫点积。
首先我要明白一点,点积和乘法 是不同的概念。在 PyTorch 里,普通乘法用星号 @ 表示
点积是向量和向量 之间的基础运算。其实就是乘法的进阶版。点积 = 先做乘法,再把所有结果加起来求和。最后出来一个标量 !
如果 a = [ a 1 a 2 ] , b = [ b 1 b 2 ] \mathbf{a}=\begin{bmatrix}a_1 \\a_2\end{bmatrix},\quad\mathbf{b}=\begin{bmatrix}b_1 \\b_2\end{bmatrix} a = [ a 1 a 2 ] , b = [ b 1 b 2 ] 那么它们的点积是 a ⋅ b = a 1 b 1 + a 2 b 2 \mathbf{a}\cdot\mathbf{b}=a_1b_1+a_2b_2 a ⋅ b = a 1 b 1 + a 2 b 2
例如 [ 2 3 ] ⋅ [ 4 5 ] = 2 × 4 + 3 × 5 = 8 + 15 = 23 \begin{bmatrix}2 \\3\end{bmatrix}\cdot\begin{bmatrix}4 \\5\end{bmatrix}=2\times4+3\times5=8+15=23 [ 2 3 ] ⋅ [ 4 5 ] = 2 × 4 + 3 × 5 = 8 + 15 = 23
再来一个举例
向量 A = [ 2 , 3 , 4 ] A = [2, 3, 4] A = [ 2 , 3 , 4 ]
向量 B = [ 5 , 2 , 1 ] B = [5, 2, 1] B = [ 5 , 2 , 1 ]
如果你执行 A @ B(严格来说是一维向量的点积),输出的结果⬇️,不再是向量,而是坍缩成了一个单数字(标量) :
A ⋅ B = ( 2 × 5 ) + ( 3 × 2 ) + ( 4 × 1 ) = 10 + 6 + 4 = 20 A \cdot B = (2 \times 5) + (3 \times 2) + (4 \times 1) = 10 + 6 + 4 = \mathbf{20} A ⋅ B = ( 2 × 5 ) + ( 3 × 2 ) + ( 4 × 1 ) = 10 + 6 + 4 = 20
🔥 结果是一个标量,也就是一个数。 这很重要,向量和向量点积出来的是一个数字!!也就是标量!
这个一定要知道,因为后面所谓的矩阵,也就是矩阵乘法 @ 的本质,就是拿第一个矩阵的每一个「 行向量」 ,去和第二个矩阵的每一个「 列向量」 ,疯狂的做点积。
几何意义上,两个向量怎么比较方向是否接近?这个时候就用到了点积。
点积大而且是正的 ➡️两个向量大致同方向
点积为 0 ➡️两个向量大致垂直
点积是负的 ➡️两个向量大致相反方向
[ 1 0 ] ⋅ [ 2 0 ] = 2 \begin{bmatrix}1 \\0\end{bmatrix}\cdot\begin{bmatrix}2 \\0\end{bmatrix}=2 [ 1 0 ] ⋅ [ 2 0 ] = 2 都是向右,所以结果是正的。
[ 1 0 ] ⋅ [ 0 3 ] = 0 \begin{bmatrix}1 \\0\end{bmatrix}\cdot\begin{bmatrix}0 \\3\end{bmatrix}=0 [ 1 0 ] ⋅ [ 0 3 ] = 0 一个向右,一个向上,互相垂直,所以点积是 0。
[ 1 0 ] ⋅ [ − 2 0 ] = − 2 \begin{bmatrix}1 \\0\end{bmatrix}\cdot\begin{bmatrix}-2 \\0\end{bmatrix}=-2 [ 1 0 ] ⋅ [ − 2 0 ] = − 2 一个向右,一个向左,所以点积是负的。
为什么点积对深度学习重要?
因为一个神经元最基础的计算就是 输入向量和权重向量做点积,再加偏置(bias)
wx + b 这就是单个神经元最底层的数学。
外积 outer product
学外积之前,先明白这个概念。
行向量(row vector)和列向量(column vector)是什么?
[ 3 4 ] \begin{bmatrix}3\\4\end{bmatrix} [ 3 4 ] 这是列向量 竖着排
[ 3 4 ] \begin{bmatrix}3 & 4\end{bmatrix} [ 3 4 ] 这是行向量 横着排
虽然里面都是 3 和 4。 但数学上它们不是同一个东西,因为形状不同 。
前者是 2 x 1 ➡️ 2 行 1 列
后者是 1x 2 ➡️ 1 行 2 列
为什么要分行和列呢?
因为后面一到乘法,顺序和形状就很重要。
比如你之前学过点积。 我们现在把点积写成更标准的样子
[ 1 0 ] [ 0 2 ] \begin{bmatrix}1 & 0\end{bmatrix}\begin{bmatrix}0\\2\end{bmatrix} [ 1 0 ] [ 0 2 ]
结果是 1 × 0 + 0 × 2 = 0 1\times0 + 0\times2 = 0 1 × 0 + 0 × 2 = 0 。所以点积常常写成 行向量 × 列向量 ,这一步很重要,因为后面矩阵乘法也是沿着这个格式长出来的。
为什么点积要写成「 行 × 列」 ?因为这样你就能直接看出:对应位置相乘,再相加
[ 2 3 ] [ 4 5 ] \begin{bmatrix}2 & 3\end{bmatrix}\begin{bmatrix}4\\5\end{bmatrix} [ 2 3 ] [ 4 5 ]
结果就是 2 × 4 + 3 × 5 = 8 + 15 = 23 2\times4 + 3\times5 = 8+15=23 2 × 4 + 3 × 5 = 8 + 15 = 23 。
而且列向量* 行向量 PK 行向量*列向量不是同一种运算。 这个非常之重要!
我们让 1 × 2 1 \times 2 1 × 2 的行向量,去乘以 2 × 1 2 \times 1 2 × 1 的列向量。
你可以做一下脑内算术题:(1 × \times × 2) @ (2 × \times × 1) → \rightarrow → (1 × \times × 1) 。
[ 3 4 ] @ [ 3 4 ] = [ 3 × 3 + 4 × 4 ] = [ 25 ] \begin{bmatrix} 3 & 4 \end{bmatrix} @ \begin{bmatrix} 3 \\ 4 \end{bmatrix} = [3 \times 3 + 4 \times 4] = [25] [ 3 4 ] @ [ 3 4 ] = [ 3 × 3 + 4 × 4 ] = [ 25 ]
结果 :内部的 2 抵消了,外部的 1 和 1 组合,生成了一个 1 × 1 1 \times 1 1 × 1 的矩阵(也就是一个标量单数字 25)。
现实意义 :把所有的特征对号入座相乘,最后全部加起来,挤压成了一个「 总分」 。这就是正宗的内积(点积) 。
🔥 上面说的都是内积,是坍缩。
现在,我们把它们的顺序倒过来!让 2 × 1 2 \times 1 2 × 1 的列向量,去乘以 1 × 2 1 \times 2 1 × 2 的行向量。
再做一次脑内算术题:(2 × \times × 1) @ (1 × \times × 2) → \rightarrow → (2 × \times × 2) 。
内部的 1 完美抵消,咬合通过,但外部留下了 2 和 2。两个数字相乘,生成一个包含 4 个格子的完整矩阵
[ 3 4 ] @ [ 3 4 ] = [ 3 × 3 3 × 4 4 × 3 4 × 4 ] = [ 9 12 12 16 ] \begin{bmatrix} 3 \\ 4 \end{bmatrix} @ \begin{bmatrix} 3 & 4 \end{bmatrix} = \begin{bmatrix} 3 \times 3 & 3 \times 4 \\ 4 \times 3 & 4 \times 4 \end{bmatrix} = \begin{bmatrix} 9 & 12 \\ 12 & 16 \end{bmatrix} [ 3 4 ] @ [ 3 4 ] = [ 3 × 3 4 × 3 3 × 4 4 × 4 ] = [ 9 12 12 16 ]
提取第 1 行的 3,分别去乘第 1 列的 3 和第 2 列的 4,填满第一行。
提取第 2 行的 4,分别去乘第 1 列的 3 和第 2 列的 4,填满第二行。
结果 :两个一维的向量碰撞,炸出了一个二维的面积!
现实意义 :这在数学里叫作「 外积」 。在当今最火爆的大语言模型(比如 GPT 的核心 Transformer)里,那个大名鼎鼎的「 注意力机制(Attention)」 ,就是靠这种「 列 @ 行」 的方式,把两个简单的向量膨胀成一个巨大的「 相关性打分矩阵」 的!
🔥 这个相当于是升维了
这两个操作都发生在两个向量 之间,但结果的维度走向完全相反
内积 (Dot Product) :行向量 × \times × 列向量 → \rightarrow → 标量 。
物理意义:计算重叠度、相似度、投影。
空间变换:把多维信息压缩成一个点。
外积 (Outer Product) :列向量 × \times × 行向量 → \rightarrow → 矩阵 。
物理意义:计算两两元素之间的全排列组合关联。
空间变换:把一维特征展开成二维平面。
向量数乘 (标量 * 向量)
在深度学习和 PyTorch 的世界里,向量的数乘(一个标量乘以一个向量)本质上就是我们刚刚聊过的触发了广播机制的普通乘法。
这是标量和向量第一次连接起来。向量可以乘以一个标量,这就是数乘。
动作 :拿一个孤零零的数字(标量),去乘以一个向量。
底层发生了什么 :触发广播机制。标量会自动「 分身」 ,复制成和向量一样长,然后大家对号入座,各自相乘(普通乘法)。
结果 :形状不变。 输入一个长度为 3 的向量,输出还是长度为 3 的向量。只是里面的数字被等比例放大了。
物理意义 :「 等比例缩放」 。比如把所有的特征翻 3 倍。
2 [ 3 1 ] = [ 6 2 ] 2\begin{bmatrix}3 \\1\end{bmatrix}=\begin{bmatrix}6 \\2\end{bmatrix} 2 [ 3 1 ] = [ 6 2 ] 意思就是每个分量都 * 2 。几何上表示方向不变,长度变成原来的 2 倍。
− 1 [ 3 1 ] = [ − 3 − 1 ] -1\begin{bmatrix}3 \\1\end{bmatrix}=\begin{bmatrix}-3 \\-1\end{bmatrix} − 1 [ 3 1 ] = [ − 3 − 1 ] 几何上表示就是长度不变,但是方向完全反过来。如果上面的看不懂,就用个笔记本自己画一个坐标轴就明白了。
所以标量乘向量,本质上是在改变向量的长度和方向。
import torch
v = torch.tensor([1 , 2 , 3 ])
scalar = 3
print (scalar * v)
广播机制
由于上面提到了广播机制,于是接下来说一下广播。广播(broadcasting)不是一种新乘法,它只是:当两个张量形状不完全一样时,框架允许你在某些维度上「 自动扩展」 后再做逐元素运算。
[ 1 2 3 4 ] \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix} [ 1 3 2 4 ] 乘上一个标量 10
就是下面⬇️
[ 1 2 3 4 ] ⊙ 10 = [ 10 20 30 40 ] \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix}\odot 10=\begin{bmatrix}10 & 20\\30 & 40\end{bmatrix} [ 1 3 2 4 ] ⊙ 10 = [ 10 30 20 40 ]
这里你可以理解成10 被「 广播」 成 [ 10 10 10 10 ] \begin{bmatrix}10 & 10\\10 & 10\end{bmatrix} [ 10 10 10 10 ] ,然后再逐元素乘。
再看一个广播到矩阵的例子,
A = [ 1 2 3 4 ] A=\begin{bmatrix}1 & 2\\3 & 4\end{bmatrix} A = [ 1 3 2 4 ] 和一个行向量 b = [ 10 100 ] b=\begin{bmatrix}10 & 100\end{bmatrix} b = [ 10 100 ]
如果做逐元素加法,很多框架会广播成
[ 1 2 3 4 ] + [ 10 100 ] = [ 11 102 13 104 ] \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix}+\begin{bmatrix}10 & 100\end{bmatrix}=\begin{bmatrix}11 & 102\\13 & 104\end{bmatrix} [ 1 3 2 4 ] + [ 10 100 ] = [ 11 13 102 104 ] 因为那个 1 × 2 1\times2 1 × 2 的向量,被自动复制成两行。
所以广播的意思,就是尺寸不完全一样,但能按规则扩展匹配。感觉就是拉伸。
在 PyTorch 的代码世界里,利用普通乘法 + 广播机制,你算出来的结果和「 外积(@)」 是百分之百一模一样的!*
回顾「 外积」 是怎么用 @ 算出来的
刚才我们说过,外积就是:列向量 @ 行向量 = 膨胀成一个大矩阵 。假设
列向量 A A A (形状 3 × 1 3 \times 1 3 × 1 ):[ 1 2 3 ] \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix} 1 2 3
行向量 B B B (形状 1 × 2 1 \times 2 1 × 2 ):[ 4 5 ] \begin{bmatrix} 4 & 5 \end{bmatrix} [ 4 5 ]
用矩阵乘法 @ 算外积:
内部的 1 完美咬合,外部的 3 和 2 组成了一个 3 × 2 3 \times 2 3 × 2 的大矩阵。
第一行是 1 去乘 4 和 5,第二行是 2 去乘 4 和 5……
最后的结果是:[ 4 5 8 10 12 15 ] \begin{bmatrix} 4 & 5 \\ 8 & 10 \\ 12 & 15 \end{bmatrix} 4 8 12 5 10 15
见证奇迹:用普通乘法 * 配合广播机制
现在,我们不用 @ 了,我们强行让这两个长得完全不一样的向量用普通乘法相乘!
列向量 A A A 的形状是 ( 3 , 1 ) (3, 1) ( 3 , 1 )
行向量 B B B 的形状是 ( 1 , 2 ) (1, 2) ( 1 , 2 )
根据之前的广播机制铁律,遇到 1 就像遇到了橡皮筋,PyTorch 会疯狂拉伸它们,直到形状一模一样
第一步:拉伸 A A A
PyTorch 发现 A A A 只有 1 列,而 B B B 有 2 列。于是它把 A A A 向右复制,脑补成了一个 3 × 2 3 \times 2 3 × 2 的矩阵:
A 拉伸 = [ 1 1 2 2 3 3 ] A_{拉伸} = \begin{bmatrix} 1 & 1 \\ 2 & 2 \\ 3 & 3 \end{bmatrix} A 拉伸 = 1 2 3 1 2 3
第二步:拉伸 B B B
PyTorch 发现 B B B 只有 1 行,而 A A A 有 3 行。于是它把 B B B 向下复制,也脑补成了一个 3 × 2 3 \times 2 3 × 2 的矩阵:
B 拉伸 = [ 4 5 4 5 4 5 ] B_{拉伸} = \begin{bmatrix} 4 & 5 \\ 4 & 5 \\ 4 & 5 \end{bmatrix} B 拉伸 = 4 4 4 5 5 5
第三步:对号入座相乘(真正的 Element-wise)
现在大家都是 3 × 2 3 \times 2 3 × 2 了,开始各自在格子里相乘:
A 拉伸 ∗ B 拉伸 = [ 1 × 4 1 × 5 2 × 4 2 × 5 3 × 4 3 × 5 ] = [ 4 5 8 10 12 15 ] A_{拉伸} * B_{拉伸} = \begin{bmatrix} 1\times4 & 1\times5 \\ 2\times4 & 2\times5 \\ 3\times4 & 3\times5 \end{bmatrix} = \begin{bmatrix} 4 & 5 \\ 8 & 10 \\ 12 & 15 \end{bmatrix} A 拉伸 ∗ B 拉伸 = 1 × 4 2 × 4 3 × 4 1 × 5 2 × 5 3 × 5 = 4 8 12 5 10 15
如果在代码里跑一下,会发现它们不仅结果一样,连底层逻辑都极其相似。
import torch
A = torch.tensor([[1 ], [2 ], [3 ]])
B = torch.tensor([[4 , 5 ]])
result_matmul = A @ B
result_elementwise = A * B
print ("A @ B 结果:\n" , result_matmul)
print ("A * B 结果:\n" , result_elementwise)
所以,你的联想非常准确。在深度学习的代码里,当你看到两个维度刚好错开(一个是 N × 1 N \times 1 N × 1 ,另一个是 1 × M 1 \times M 1 × M )的张量被硬生生用 * 乘在一起时,你不仅要知道它触发了广播,你脑海里更要瞬间拉响警报:「 小心!这家伙表面上在做普通乘法,实际上干的是外积的活儿,它在生成一个巨大的交叉矩阵!」
3 矩阵 Matrix
自动学习完了向量之后,如果你上面的向量都看懂了,才能接下来看这个。如果向量的没看懂,接下来也就不要看矩阵。
因为所谓的向量,就是特殊的矩阵罢了。
矩阵就是排成一个表格的数字,有行(Row)有列(Column)
**矩阵里的元素怎么表示?**通常写成 a i j a_{ij} a ij , 意思就是 第 i 行,第 j 列的元素 。
例如:A = [ 1 2 3 4 ] A=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix} A = [ 1 3 2 4 ]
a 11 a_{11} a 11 =1
a 12 a_{12} a 12 =2
a 21 a_{21} a 21 =3
a 22 a_{22} a 22 =4
在数学的底层逻辑里,根本就没有什么所谓独立的向量,无论是行向量还是列向量,它们本质上就是特殊的矩阵!
行向量,就是一个 1 × n 1 \times n 1 × n 的矩阵(只有 1 行)
列向量,就是一个 n × 1 n \times 1 n × 1 的矩阵(只有 1 列)
向量可以看成一种特殊矩阵。
[ 1 2 3 ] \begin{bmatrix}1 \\2 \\3\end{bmatrix} 1 2 3 这是 3 x 1 矩阵
[ 1 2 3 ] \begin{bmatrix}1 & 2 & 3\end{bmatrix} [ 1 2 3 ] 这是 1 x 3 矩阵
所以,**向量本质上就是只有一行或一列的矩阵。**在线性代数和机器学习里,向量非常常见。
为什么机器学习里要用矩阵呢?因为数据通常不是一个数。比如你有 3 个学生,每个人有 2 个特征,1身高 2体重。那么数据就可以写成。
X = [ 170 65 160 50 180 75 ] X=\begin{bmatrix}170 & 65 \\160 & 50 \\180 & 75\end{bmatrix} X = 170 160 180 65 50 75
每一行 ➡️ 一个样本(sample)
每一列 ➡️ 一个特征(feature)
所以矩阵非常适合表示数据集。
矩阵相等&相加
两个矩阵相等,必须同时满足
A = [ 1 2 3 4 ] , B = [ 1 2 3 4 ] A=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix},B=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix} A = [ 1 3 2 4 ] , B = [ 1 3 2 4 ]
那么 A=B。但如果一个元素不同,就不相等。
矩阵加法(addition)+ 矩阵减法(subtraction)
只有形状相同 的矩阵才能相加。
A = [ 1 2 3 4 ] , B = [ 5 6 7 8 ] A=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix},B=\begin{bmatrix}5 & 6 \\7 & 8\end{bmatrix} A = [ 1 3 2 4 ] , B = [ 5 7 6 8 ]
那么
A + B = [ 1 + 5 2 + 6 3 + 7 4 + 8 ] = [ 6 8 10 12 ] A+B=\begin{bmatrix}1+5 & 2+6 \\3+7 & 4+8\end{bmatrix}=\begin{bmatrix}6 & 8 \\10 & 12\end{bmatrix} A + B = [ 1 + 5 3 + 7 2 + 6 4 + 8 ] = [ 6 10 8 12 ]
本纸就是对应位置直接相加 。同样也是形状相同才能减。
A − B = [ 1 − 5 2 − 6 3 − 7 4 − 8 ] = [ − 4 − 4 − 4 − 4 ] A-B=\begin{bmatrix}1-5 & 2-6 \\3-7 & 4-8\end{bmatrix}=\begin{bmatrix}-4 & -4 \\-4 & -4\end{bmatrix} A − B = [ 1 − 5 3 − 7 2 − 6 4 − 8 ] = [ − 4 − 4 − 4 − 4 ]
标量乘法(scalar multiplication)
其实这个在向量的数乘里面已经学过了,原理是一样的。
2 A = 2 [ 1 2 3 4 ] = [ 2 4 6 8 ] 2A=2\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix}=\begin{bmatrix}2 & 4 \\6 & 8\end{bmatrix} 2 A = 2 [ 1 3 2 4 ] = [ 2 6 4 8 ]
规则就是矩阵里每个元素都乘这个数 ,也可以看广播。
矩阵乘法 Matrix Multiplication
重点要看的,这个最好建议和向量的点积一起混合食用。而且和向量一样,矩阵乘法也是一个很暧昧的说法。
本纸就是交叉点积运算 ,
在矩阵里,左边矩阵的列数 Col = 右边矩阵的行数 Row,才能相乘
A 是 2 × 3 , B 是 3 × 4 A \text{ 是 } 2\times 3, B \text{ 是 } 3\times 4 A 是 2 × 3 , B 是 3 × 4
那么 A B 可以乘,结果会是 2 × 4 2\times 4 2 × 4 。
下面是一个最简单的矩阵乘法。(其实就是点积加起来吧。
A = [ 1 2 3 4 ] , B = [ 5 6 ] A=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix},B=\begin{bmatrix}5 \\6\end{bmatrix} A = [ 1 3 2 4 ] , B = [ 5 6 ]
A 是 2 × 2 2\times 2 2 × 2
B 是 2 × 1 2\times 1 2 × 1
所以是可以计算的,结果是2 × 1 2\times 1 2 × 1 。怎么算呢?其实原理和向量的点积是一模一样的
第1行乘第1列 1 × 5 + 2 × 6 = 17 1\times 5 + 2\times 6 = 17 1 × 5 + 2 × 6 = 17
第2行乘第1列 3 × 5 + 4 × 6 = 39 3\times 5 + 4\times 6 = 39 3 × 5 + 4 × 6 = 39
最后结果 A B = [ 17 39 ] AB=\begin{bmatrix}17 \\39\end{bmatrix} A B = [ 17 39 ]
你要把矩阵乘法记成一句话 ➡️ 一行乘一列,对应元素相乘再相加
A = [ 1 2 3 4 ] , B = [ 5 6 7 8 ] A=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix},B=\begin{bmatrix}5 & 6 \\7 & 8\end{bmatrix} A = [ 1 3 2 4 ] , B = [ 5 7 6 8 ]
结果 AB 是 2 × 2 2\times 2 2 × 2 。
左上角 1 × 5 + 2 × 7 = 19 1\times 5 + 2\times 7 = 19 1 × 5 + 2 × 7 = 19
右上角 1 × 6 + 2 × 8 = 22 1\times 6 + 2\times 8 = 22 1 × 6 + 2 × 8 = 22
左下角 3 × 5 + 4 × 7 = 43 3\times 5 + 4\times 7 = 43 3 × 5 + 4 × 7 = 43
右下角 3 × 6 + 4 × 8 = 50 3\times 6 + 4\times 8 = 50 3 × 6 + 4 × 8 = 50
所以 A B = [ 19 22 43 50 ] AB=\begin{bmatrix}19 & 22 \\43 & 50\end{bmatrix} A B = [ 19 43 22 50 ]
⚠️ 矩阵乘法一般不满足交换律
普通数字里 2 x 3 = 3 x 2 但矩阵里通常 A B ≠ B A AB \ne BA A B = B A
甚至有时候 AB 能乘,BA 根本不能乘。
矩阵乘法是在做加权组合
A = [ 1 2 3 4 ] , d x = [ 5 6 ] A=\begin{bmatrix}1 & 2 \\3 & 4\end{bmatrix},dx=\begin{bmatrix}5 \\6\end{bmatrix} A = [ 1 3 2 4 ] , d x = [ 5 6 ] 结果是 A x = [ 17 39 ] Ax=\begin{bmatrix}17 \\39\end{bmatrix} A x = [ 17 39 ]
你也可以把它理解成 A x = 5 [ 1 3 ] + 6 [ 2 4 ] Ax=5\begin{bmatrix}1 \\3\end{bmatrix}+6\begin{bmatrix}2 \\4\end{bmatrix} A x = 5 [ 1 3 ] + 6 [ 2 4 ]
因为 5 [ 1 3 ] = [ 5 15 ] , 6 [ 2 4 ] = [ 12 24 ] 5\begin{bmatrix}1 \\3\end{bmatrix}=\begin{bmatrix}5 \\15\end{bmatrix},\quad6\begin{bmatrix}2 \\4\end{bmatrix}=\begin{bmatrix}12 \\24\end{bmatrix} 5 [ 1 3 ] = [ 5 15 ] , 6 [ 2 4 ] = [ 12 24 ]
相加得到 [ 17 39 ] \begin{bmatrix}17 \\39\end{bmatrix} [ 17 39 ]
矩阵乘列向量,本质上是在对矩阵的各列做线性组合(linear combination)。
转置(transpose)
转置就是 把行变列,列变行 记作 A T A^T A T
比如A = [ 1 2 3 4 5 6 ] A=\begin{bmatrix}1 & 2 & 3 \\4 & 5 & 6\end{bmatrix} A = [ 1 4 2 5 3 6 ] 这是 2 × 3 2\times 3 2 × 3 。
转置后 A T = [ 1 4 2 5 3 6 ] A^T=\begin{bmatrix}1 & 4 \\2 & 5 \\3 & 6\end{bmatrix} A T = 1 2 3 4 5 6 变成了 3 × 2 3\times 2 3 × 2 。
为什么转置很重要? 因为机器学习里常常要把
x = [ 1 2 3 ] x=\begin{bmatrix}1 \\2 \\3\end{bmatrix} x = 1 2 3 变成 x T = [ 1 2 3 ] x^T=\begin{bmatrix}1 & 2 & 3\end{bmatrix} x T = [ 1 2 3 ]
单位矩阵(identity matrix)
单位矩阵记作 I I I 。它像数字里的 1。无论什么乘以这个 I I I ,最后都是原来的数字。
例如 2 阶单位矩阵
I = [ 1 0 0 1 ] I=\begin{bmatrix}1 & 0 \\0 & 1\end{bmatrix} I = [ 1 0 0 1 ]
它有个性质 A I = I A = A AI = IA = A A I = I A = A 。只要维度匹配,就像普通数字里的乘以 1。
4 正向传播用的是什么
在正向传播里,用到的就是点积,也就是行*列的逻辑。
y ^ = W x + b \hat{y}=Wx+b y ^ = W x + b
这是只有一个特征时。如果有多个特征,就会写成向量形式
y ^ = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + b \hat{y}=w_1x_1+w_2x_2+\cdots+w_nx_n+b y ^ = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + b
这时候用矩阵/向量写会更简洁。
X = [ x 1 x 2 x 3 ] , w = [ w 1 w 2 w 3 ] \mathbf{X}=\begin{bmatrix}x_1 \\x_2 \\x_3\end{bmatrix},\quad\mathbf{w}=\begin{bmatrix}w_1 \\w_2 \\w_3\end{bmatrix} X = x 1 x 2 x 3 , w = w 1 w 2 w 3
假设样本有样本有三个特征,比如上面的 X X X , 在线性回归里,先把权重进行转置。也就是列变行。
w T x w^T x w T x ,其中 w T = [ w 1 w 2 w 3 ] w^T=\begin{bmatrix}w_1 & w_2 & w_3\end{bmatrix} w T = [ w 1 w 2 w 3 ] 所以⬇️
w T x = [ w 1 w 2 w 3 ] [ x 1 x 2 x 3 ] = w 1 x 1 + w 2 x 2 + w 3 x 3 w^T x=
\begin{bmatrix}
w_1 & w_2 & w_3
\end{bmatrix}
\begin{bmatrix}
x_1 \\
x_2 \\
x_3
\end{bmatrix}
=
w_1x_1+w_2x_2+w_3x_3 w T x = [ w 1 w 2 w 3 ] x 1 x 2 x 3 = w 1 x 1 + w 2 x 2 + w 3 x 3
**那么预测值本质上就是一种向量点积乘法。**假设有 5 条待处理的数据,构成输入矩阵 X X X (维度:5 × 3 5 \times 3 5 × 3 )。每一行代表一个独立的数据样本,每一列代表一种特征。
同时,定义权重矩阵 W W W (维度:3 × 1 3 \times 1 3 × 1 )。由于输出是 1 维的,权重就是一个包含 3 个参数的列向量。
X = [ 2 1 0 3 2 1 1 1 2 4 3 0 2 0 1 ] , W = [ 2 3 − 1 ] X = \begin{bmatrix} 2 & 1 & 0 \\ 3 & 2 & 1 \\ 1 & 1 & 2 \\ 4 & 3 & 0 \\ 2 & 0 & 1 \end{bmatrix}, \quad W = \begin{bmatrix} 2 \\ 3 \\ -1 \end{bmatrix} X = 2 3 1 4 2 1 2 1 3 0 0 1 2 0 1 , W = 2 3 − 1
输出结果 y ^ = X W \hat{y} = XW y ^ = X W 将是一个 5 × 1 5 \times 1 5 × 1 的列向量。
在这个计算中,矩阵 X X X 的每一行 都在与权重矩阵 W W W 的唯一一列 进行内积(点积) 。这正是「 行 × \times × 列」 逻辑的最佳体现。
具体的展开计算
y ^ = X W = [ ( 2 × 2 ) + ( 1 × 3 ) + ( 0 × − 1 ) ( 3 × 2 ) + ( 2 × 3 ) + ( 1 × − 1 ) ( 1 × 2 ) + ( 1 × 3 ) + ( 2 × − 1 ) ( 4 × 2 ) + ( 3 × 3 ) + ( 0 × − 1 ) ( 2 × 2 ) + ( 0 × 3 ) + ( 1 × − 1 ) ] = [ 4 + 3 + 0 6 + 6 − 1 2 + 3 − 2 8 + 9 + 0 4 + 0 − 1 ] = [ 7 11 3 17 3 ] \hat{y} = XW = \begin{bmatrix} (2 \times 2) + (1 \times 3) + (0 \times -1) \\ (3 \times 2) + (2 \times 3) + (1 \times -1) \\ (1 \times 2) + (1 \times 3) + (2 \times -1) \\ (4 \times 2) + (3 \times 3) + (0 \times -1) \\ (2 \times 2) + (0 \times 3) + (1 \times -1) \end{bmatrix} = \begin{bmatrix} 4 + 3 + 0 \\ 6 + 6 - 1 \\ 2 + 3 - 2 \\ 8 + 9 + 0 \\ 4 + 0 - 1 \end{bmatrix} = \begin{bmatrix} 7 \\ 11 \\ 3 \\ 17 \\ 3 \end{bmatrix} y ^ = X W = ( 2 × 2 ) + ( 1 × 3 ) + ( 0 × − 1 ) ( 3 × 2 ) + ( 2 × 3 ) + ( 1 × − 1 ) ( 1 × 2 ) + ( 1 × 3 ) + ( 2 × − 1 ) ( 4 × 2 ) + ( 3 × 3 ) + ( 0 × − 1 ) ( 2 × 2 ) + ( 0 × 3 ) + ( 1 × − 1 ) = 4 + 3 + 0 6 + 6 − 1 2 + 3 − 2 8 + 9 + 0 4 + 0 − 1 = 7 11 3 17 3
核心原理解析
独立性 :虽然这是一个完整的矩阵乘法,但 5 条数据的计算互不干扰。第 1 行数据的特征只负责生成第 1 行的输出。
物理意义 :权重列向量 W W W 就像是一把「 标尺」 。输入矩阵 X X X 中的每一行(即每一条数据),都在依次通过这把标尺进行测量(执行内积),最终得到 5 个独立的测量结果。
工程优势 :在底层代码中调用 @ 或 matmul 时,GPU 会同时并行执行这 5 次独立的内积运算,极大提高了计算效率。
走到这里我终于领悟了 🔥
直接看这个