线性代数
基本知识
核心概念
线性代数的核心概念包括:
- 标量 scalar,就是一个单独的数
- 向量 vector,就是一列数,一般用于将一个复杂信息映射到一个连续数值空间作为特征表示,是数据的数学化身
- 矩阵 matrix
- 张量 tensor
Vector
在物理中,向量代表空间中的箭头;在CS中,向量大多数时候代表有序的数字列表。一个长度为2的列表,就被称为2维向量。
向量在书面表达上有两种主要的排列方式:
- 列向量(Column Vector): 竖着写的形式,如 \(\boldsymbol{x} = \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{pmatrix}\)。
- 行向量(Row Vector): 横着写的形式,如 \(\boldsymbol{x} = (x_1, x_2, \dots, x_n)\)。
在数学规范中,如果不加特殊说明,通常默认向量是列向量。为了节省排版空间,我们经常把原本应该竖着写的列向量横着写,并加上一个上标 \(\text{T}\) ,这就是 转置 。
单位向量是具有单位范数的向量。
Norm
简单来说,范数就是用来衡量向量“长度”或“大小”的一个函数。范数(Norm) 并不是两个向量相加,它是作用在 单个向量 上的一个函数,用来计算这个向量的 “长度” 或 “大小” 。
要称一个函数为“范数”,它必须像我们直觉中的“长度”一样,满足三个核心性质:
- 正定性(Positivity): 向量的长度不能是负数。只有当向量本身是零向量时,它的长度才等于 0。
- 绝对齐次性(Homogeneity): 如果你把向量放大 \(a\) 倍,它的长度也应该相应地放大 \(|a|\) 倍。
- 三角不等式(Triangle Inequality): 两边之和大于等于第三边。即两个向量相加后的长度,不会超过它们各自长度的和:
对于一个 \(n\) 维向量 \(\boldsymbol{x}\),其 \(L_p\) 范数的通式为:
假设有一个 \(n\) 维向量 \(\boldsymbol{x} = [x_1, x_2, \dots, x_n]^\text{T}\),其各项公式如下:
\(L_1\) 范数 (Manhattan Norm)
又称“绝对值之和范数”或“曼哈顿距离”。
\(L_2\) 范数 (Euclidean Norm)
最常用的范数,即通常意义上的“几何长度”或“欧几里得距离”。
\(L_\infty\) 范数 (Maximum Norm)
又称“无穷范数”或“切比雪夫范数”,取向量分量中绝对值最大的那一个。
\(L_0\) 范数 (Zero Norm)
严格来说它不是数学定义的范数,但在工程中常用于表示向量的 稀疏性 。它表示向量中非零元素的个数。
在计算机科学(CS)和人工智能(AI)中,向量确实表现为一组有序数列,但我们计算它的“长度”(范数),本质上是在 量化某种“代价”、“差异”或“重要性” 。如果没有范数,向量就只是一堆静止的数字;有了范数,我们就能比较这些数字。以下是范数在 AI 和 CS 中的核心意义:
- 衡量两个东西有多像,比如搜索一个商品的时候,搜索引擎可以计算搜索词向量和商品向量之间的距离,来进行搜索结果排序,并展示推荐
- 限制模型的复杂度,训练模型的时候,如果参数(权重向量w)的数值太大,模型容易想太多(过拟合),因此可以把参数向量加入损失函数,让模型在学习规律的同时保持参数尽可能小或者尽可能稀疏
Tensor
这里的值得注意的是tensor,标量其实就是0阶(rank)张量,比如损失值、温度;向量就是1阶张量,比如一个词的embedding、一个人的特征序列等;矩阵就是2阶张量,比如权重矩阵W、灰度图;3阶张量如一张彩色照片,有高、宽、颜色通道共3个序列;4阶张量如一个批次的图片(图片张数x高x宽x通道)。
在机器学习中,一个向量就是一个样本(sample),向量的每一个数字被称为一个特征(feature),矩阵则代表一个数据集。比方说,在一个矩阵中,每一行代表一个样本(如一个房子),每一列则代表一个特征(比如房屋面积)。
在传统机器学习中张量很少出现,只有处理时序数据或者图像时才会用到3维及以上的张量。
而在深度学习中,几乎所有的数据、所有模型参数、所有中间计算结果都是张量。深度学习框架如PyTorch、TensorFlow可以看作是一个专门处理张量的加工厂。
Rank(阶)
阶(Rank) 类似于坐标轴的“轴”,比如说3维空间坐标轴有3个阶。比方来说,对于一个3阶的tensor,每个阶都是一个包含100个数字的序列,那么每一个阶就是100维。
当然,每一个rank里头的数字不一定需要一样多。比如说,一张彩色照片的tensor shape通常是:[1080, 1920, 3],这代表了一个3阶张量,其中:
- 1080代表高度,即照片的纵向像素有1080行
- 1920代表宽度,即照片的横向像素有1920行
- 3代表颜色,即RGB三个颜色
对于这个3阶张量,如果我们进行可视化,它的形状将是一个长方体。
我们可以把每一个rank视作一把尺子,每一阶的长度决定了尺子有多长。
在深度学习中,有一个叫做“变形”(reshape)的动作。比方说,我们可以把一个[10, 512]的tensor(代表10个单词,每个单词被映射为512维的数列)直接揉成一个[5120]的长向量,从而让rank从2变成1。
在实际使用中,一般张量的阶从1到5不等,且要考虑到批次(batch)轴。
Broadcasting
在深度学习中,我们经常使用一种不那么常规的简写符号,允许 矩阵和向量相加 ,产生另一个矩阵。这种操作被称为广播(broadcasting):
- \(C = A + b\),其中 \(C_{i,j} = A_{i,j} + b_j\)
在数学上,矩阵加法要求两个矩阵必须 完全一样大 。但如果我们要给 1000 个特征向量(矩阵 \(A\))都加上同一个偏移量(向量 \(b\)),手动把 \(b\) 复制 1000 遍会非常浪费内存。
当你写 \(A + b\) 时,计算机发现 \(b\) 的维度比 \(A\) 少。它会 逻辑上 (而不是真的在内存里)把 \(b\) 沿着缺失的维度拉长。
- 例子 :矩阵 \(A\) 是
[100, 512],向量 \(b\) 是[512]。 - 广播机制会让 \(b\) 像“涂抹”一样,平铺到 \(A\) 的每一行上。
- 结果 :\(A\) 的第 1 行加了 \(b\),第 2 行也加了 \(b\)……直到第 100 行。
Batching
Batching(批次处理) 就是把一群孤立的向量(比如多个词、多张图)整齐地堆叠成一个更高阶张量的过程。
在深度学习中,如果不用 Batching,模型的工作效率会极低。比方说,如果你一个一个地处理向量,GPU 的强大算力就会被浪费在反复读取数据上。我们将多个 1 阶张量(向量)横向或纵向堆叠,变成一个 2 阶张量(矩阵)。GPU 就像一辆拥有几千个座位的超级大巴,而每一个神经元计算就像是一个乘客。如果你一次只送一个向量进去,大巴每次只载一个人就发车,电力和带宽都被浪费在了路上。将多个向量合并成矩阵后,原本需要做 100 次的“向量 \(\times\) 矩阵”运算,变成了 1 次高效的“ 矩阵 \(\times\) 矩阵 ”运算。这种并行计算速度要快出几十甚至上百倍。
当你把一队数据(Batch)送进模型时,我们刚才总结的那些“数学招式”就开始配合了:
- 排队进场 :数据以
[Batch, Features]的形式进入。 - 统一变换 :模型里的权重矩阵 \(W\) 会一次性作用于这一整队人。
- 广播叠加 :如果你有一个偏置项 \(b\)(比如加 5 分),广播机制会叠加到队里的每一个人身上。你不需要为 32 个人准备 32 个 \(b\),只需要一个 \(b\),广播会自动“复印”并分发。
在实践中,你会经常听到这三个词,它们描述了“排队”的不同规模:
| 术语 | 含义 | 形象化比喻 |
|---|---|---|
| Batch Size | 一个批次里有多少个样本(比如 32、64)。 | 大巴车一次载多少人。 |
| Iteration (迭代) | 完成一个 Batch 的训练过程。 | 大巴车跑一趟。 |
| Epoch (轮次) | 所有训练数据(全校学生)都排队过了一遍模型。 | 全校学生都坐过车了。 |
.
矩阵
一个 \(m\) 行 \(n\) 列的矩阵 \(\boldsymbol{A}\) 通常表示为:
- 元素 :\(a_{ij}\) 表示第 \(i\) 行第 \(j\) 列的数字。
- 主对角线 :指 \(a_{11}, a_{22}, \dots, a_{kk}\) 所在的线。
一般矩阵用来表示数据表,一行是一个样本,一列是一个特征。
转置是将矩阵的行和列互换的操作,记作 \(\boldsymbol{A}^\text{T}\)。
- 公式 :若 \(\boldsymbol{B} = \boldsymbol{A}^\text{T}\),则 \(b_{ij} = a_{ji}\)。
- 性质 :\((\boldsymbol{A}^\text{T})^\text{T} = \boldsymbol{A}\)
单位矩阵(Identity Matrix)主对角线全为 1,其余全为 0 的方阵,记作 \(\boldsymbol{I}\):
任何矩阵乘以单位矩阵都等于它本身(\(\boldsymbol{A}\boldsymbol{I} = \boldsymbol{A}\)),相当于数字中的 “1”。
对角矩阵(Diagonal Matrix)除了主对角线上的元素外,其余元素全部为 0 的矩阵。\(\boldsymbol{D} = \text{diag}(d_1, d_2, \dots, d_n)\),即当 \(i \neq j\) 时,\(a_{ij} = 0\)。对角矩阵常用于缩放数据特征。
矩阵的范数
矩阵也有“长度”的概念。最常用的是 Frobenius 范数 (类似于向量的 \(L_2\) 范数):
- 直观理解 :把矩阵里所有的数都平方加起来,最后开根号。这在深度学习中用来衡量整个神经网络参数的“总量”。
矩阵加法
只要矩阵的 形状(Shape)一样 ,就可以把两个矩阵相加:
- \(C = A + B\),即对应位置的元素分别相加:\(C_{i,j} = A_{i,j} + B_{i,j}\)
标量与矩阵相乘或相加时,只需将其与矩阵的每一个元素分别相乘或相加:
- \(D = a \cdot B + c\),其中 \(D_{i,j} = a \cdot B_{i,j} + c\)。
点积
如果矩阵 \(A\) 的形状是 \(m \times n\),矩阵 \(B\) 的形状是 \(n \times p\),那么 \(A\) 的列数必须等于 \(B\) 的 行数 。乘完之后,\(C\) 的形状是 \(m \times p\)。
点积与矩阵乘法的计算逻辑如下:
结果矩阵中第 \(i\) 行、第 \(j\) 列的那个数字,是由 \(A\) 的第 \(i\) 行和 \(B\) 的第 \(j\) 列进行 点积 (对应相乘再求和)得到的。

这个乘法方式看起来非常奇怪。这里我们必须要理解“线性”的含义。
如果我们有几个向量 \(\vec{v}_1, \vec{v}_2, \dots, \vec{v}_n\),给它们每个都配上一个常数系数 \(c_1, c_2, \dots, c_n\),那么:
这个结果就叫做这组向量的一个 线性组合 。在整个过程中,向量只发生了 伸缩 (乘常数)和 相加 (平移),没有把向量拿去平方,也没有让两个向量互相乘。这保证了在空间中,这些变换始终是“直”(线性)的。
看下面这个矩阵乘法:
如果你换个视角看,它其实是在做线性组合:
它意味着:用右边的数字作为系数,去给左边的列向量“配料”。
- 你拿了 5 份列向量 1。
- 你拿了 7 份列向量 2。
- 把它们加起来。
矩阵乘法和我们小时候学习的数字乘法规则大不相同:
- 不满足交换律,\(AB\) 通常不等于 \(BA\)
- 满足结合律,\(A(BC) = (AB)C\)
- 满足分配率,\(A(B + C) = AB + AC\)
- 乘积的转置等于转置后的矩阵以相反顺序相乘,即 \((AB)^\top = B^\top A^\top\)
对于两个一阶向量,\(x\) 和 \(y\) 的点积可以写成 \(x^\top y\)。
注意,如果你只想让两个矩阵对应位置相乘,那叫“元素对应乘积”或 Hadamard 乘积 ,记作 \(A \odot B\)。
线性组合
当你用矩阵 \(A\) 乘以向量 \(\mathbf{b}\) 时:
- 矩阵 \(A\)* 的维度是 *\(m \times n\)(\(m\) 行,\(n\) 列 )。
- 向量 \(\mathbf{b}\)* 的维度是 *\(n \times 1\)(\(n\) 行 ,1 列)。
只有当 \(A\) 的列数 (\(n\)) 等于 \(\mathbf{b}\) 的行数 (\(n\)) 时,乘法才有意义。
假设我们有 3 个人,每个人的特征是“身高”和“体重”:
- 矩阵 \(A\)(数据矩阵): 每一行代表一个人,每一列代表一种特征。 $$ A = \begin{bmatrix} 180 & 75 \ 160 & 50 \ 175 & 80 \end{bmatrix} \begin{matrix} \leftarrow \text{张三} \ \leftarrow \text{李四} \ \leftarrow \text{王五} \end{matrix} $$
- 向量 \(\vec{x}\)(权重向量): 代表你对不同特征的“重视程度”。 $$ \vec{x} = \begin{bmatrix} 0.6 \ 0.4 \end{bmatrix} \begin{matrix} \leftarrow \text{身高的权重} \ \leftarrow \text{体重的权重} \end{matrix} $$
- 结果 \(A\vec{x}\)(得分向量): 矩阵乘以向量的过程,本质上是让矩阵的每一行与向量做 点积(Dot Product) : $$ A\vec{x} = \begin{bmatrix} 180 \times 0.6 + 75 \times 0.4 \ 160 \times 0.6 + 50 \times 0.4 \ 175 \times 0.6 + 80 \times 0.4 \end{bmatrix} = \begin{bmatrix} 138 \ 116 \ 137 \end{bmatrix} \begin{matrix} \leftarrow \text{张三得分} \ \leftarrow \text{李四得分} \ \leftarrow \text{王五得分} \end{matrix} $$
你刚才描述的这个逻辑,其实就是人工神经网络(Neural Networks) 中最基础的运算单元。
- 特征提取: 在 AI 领域,矩阵 \(A\) 就是输入数据,向量 \(\vec{x}\) 是模型学习出来的参数。
- 降维/压缩: 你把多维的特征(身高、体重)通过加权求和,压缩成了一个一维的分数。
在之前的例子里,你只有一个权重向量(比如只算“健康分”)。但如果现在,你想根据同样的身高、体重,同时算出三个指标: 健康分、体能分、魅力分 ,该怎么办?
这时候,你就不止一个权重向量了,而是有三个权重向量。把这三个向量并排摆在一起,就成了一个 权重矩阵 \(W\)**** 。
- 矩阵 \(A\) (数据): 还是那 3 个人的身高、体重。
- 矩阵 \(B\) (权重集): * 第一列:健康分的权重。
- 第二列:体能分的权重。
- 第三列:魅力分的权重。
在结果矩阵 \(C\) 中,每一行依然代表一个人,但 每一列代表一个不同的评价指标 。
直观理解: 矩阵乘以矩阵,本质上是 多组权重同时作用于同一组数据 。它一次性帮你完成了所有的评价计算。
矩阵乘以矩阵,既可以看作是多个线性变换的“打包”,也可以看作是多个线性变换的“叠加”。
这取决于你从哪个角度去看。为了让你彻底理解,我们分两个视角来拆解:
视角一:横向“打包”(并行的评价系统)
这就是你刚才提到的理解方式。假设矩阵 \(A\) 是数据,矩阵 \(B\) 是由两个权重向量 \([w_1, w_2]\) 组成的。
在这个视角下,矩阵乘法就是“批量处理”。
- 你把原本需要算两次的线性变换(一次算健康分,一次算体能分),打包成了一个动作。
- 结论: 它是 多个线性变换同时作用于同一组数据 。
视角二:纵向“叠加”(复合变换)
这是数学家和计算机科学家最常用的视角。如果我们考虑两个变换矩阵 \(W_1\) 和 \(W_2\),以及一个向量 \(\vec{x}\)。
当我们将它们相乘 \((W_2 \times W_1) \vec{x}\) 时:
- 先由 \(W_1\) 对 \(\vec{x}\) 做一次变换(比如旋转)。
- 再由 \(W_2\) 对变换后的结果做第二次变换(比如拉伸)。
矩阵乘法 \(W_2 W_1\) 的结果,本身就是一个新的矩阵 \(M\)。 这个 \(M\) 代表了一个“复合变换”:它直接把两次连续的动作合二为一了。
直观比喻:
- \(W_1\) 是“把衣服洗了”。
- \(W_2\) 是“把衣服烘干”。
- 矩阵乘法 \(W_2 W_1\) 就是一个“洗烘一体机”。你扔进去一件脏衣服(向量 \(\vec{x}\)),它直接吐出来一件干净且干燥的衣服。你不需要关心中间经历了两个步骤,因为这个新的矩阵已经把这两个功能融合在一起了。
总结:它算线性变换吗?
算!
在线性代数中,有一个非常重要的性质:两个线性变换的复合,依然是一个线性变换。
- 即使你连续做了 100 次矩阵乘法(\(W_{100} \dots W_2 W_1\)),只要它们都是纯粹的矩阵相乘,最终都可以简化成唯一一个巨大的矩阵 \(M\)。
- 这个 \(M\) 依然是一个单一的线性变换。
关键点拨:为什么神经网络需要“非线性”?
既然你提到了 \(y = Wx + b\),这里有个非常深刻的逻辑:
如果神经网络里只是单纯的“矩阵乘以矩阵”,那么无论你叠多少层,它最终都等同于单层矩阵运算(因为 \(W_2(W_1x) = (W_2W_1)x\))。
这就是为什么我们在神经网络的层与层之间,必须加入 激活函数 (比如 ReLU)。
它的作用就是打破这种“矩阵叠加依然是线性变换”的魔咒,让模型能理解更复杂、非线性的世界(比如判断一张照片是猫还是狗,这种逻辑不是简单的加权求和能搞定的)。
例1
比方说,我们要考虑两个因素(特征):\(x_1\) 是电影的“动作成分”,\(x_2\) 是电影的“喜剧成分”。
- 对于 用户 A ,他很喜欢动作片,对喜剧一般。他的评分逻辑可能是: \(5 \times x_1 + 1 \times x_2 = 评分\)
- 对于 用户 B ,他很讨厌暴力,喜欢大笑。他的评分逻辑可能是: \(0 \times x_1 + 5 \times x_2 = 评分\)
如果有成千上万个用户和电影特征,我们不可能写几万个方程。这时我们就用矩阵:
这里:
- 左边矩阵 (A/W) :存储了不同用户的偏好“知识”。
- 中间向量 (x) :是当前电影的属性(比如 \(x_1=0.9, x_2=0.1\) 代表这基本是一部纯动作片)。
- 右边向量 (b/y) :是模型一次性为所有用户计算出的预测评分。
GPU可以利用这种形式,同时并行计算几百万个神经元的输出,大大提升效率。
例2
我们来通过一个具体的例子看一下计算过程:
- \(x\) (输入向量) :是贷款申请人的个人资料。\(x = [年龄, 收入, 信用分]^\top\)
- \(A\) (权重矩阵) :是银行的 内部评估规则 。它决定了“年龄”占多少权重,“信用分”占多少权重。
- \(b\) (预测结果) :是模型算出来的分值(比如大于 0 准予贷款,小于 0 拒绝)。
假设 \(x = [25, 8000, 700]^\top\)(25岁,月入8k,信用700分)。
如果此时银行的审批逻辑(矩阵 \(A\))是:
(这里年龄前的 \(-0.1\) 表示年龄越大风险越高,信用分前的 \(0.5\) 表示信用分很重要)
计算 \(Ax = b\):
分值很高,准予贷款。
在现实中,银行并没有这一串精确的权重数字。所谓的“训练 AI”,其实就是为了填满矩阵 \(A\) 里的那些空格。
假设我们有几百万个人作为样本,那么我们就可以训练AI:
- 初始状态 :刚开始,矩阵 \(A\) 里的数字是随机乱填的(比如全是 0.001)。
- 喂入数据 :我们把银行过去 10 年里的几百万个真实案例(每个人对应的 \(x\) 和最终还钱没还钱的标签 \(b_{true}\))喂给 AI。
- 发现错误 :
- AI 用当前的 \(A\) 算了一下张三,觉得张三能还钱(\(b=300\))。
- 但历史记录显示张三最后违约了(\(b_{true}=-100\))。
- 微调 \(A\)* :AI 发现自己“算错了”,它就会去调整矩阵 *\(A\) 里的数字。比如它发现张三虽然收入高但信用极低,于是它就把 \(A\) 里面对应“信用分”那个格子的权重调得更高一点。
在求解过程中,我们不能用逆矩阵法求解。这是因为,在几百万人里,很高概率有两个人的资料看起来一样,但是结果却不同(一个还了钱,一个没还钱)。这叫做方程矛盾,即不存在一个完美的A能让所有等式同时成立。而且,现实中A可能是1000x10000的规模,计算量大到无法求逆。此外,现实逻辑不是简单的加减法。为了让模型变聪明,我们会在 \(Ax\) 之后加一个“激活函数”(比如负数变 0),这一下就把公式变成了非线性的,逆矩阵那套线性规则直接失效了。
下面我们来看看训练过程。训练过程就是把这几百万人一个一个拉出来试,每错一个,就把 \(A\) 里的数字拧一拧。直到这套逻辑在大多数人身上都算得准,这个矩阵 \(A\) 就算练成了。这个过程就像是在黑盒子里调旋钮: 你不知道内部结构,你只能输入 \(x\),看输出 \(b\),如果输出不对,你就把旋钮(矩阵 \(A\) 里的元素)往左或往右转一点点。转了几百万次后,你就得到了那个最完美的旋钮组合。
这就是为什么我们在深度学习里不谈“解方程”,而谈优化(Optimization)。
下面我们来看一下这个宁旋钮是怎样的过程。在拧旋钮之前,AI 必须先知道自己错得有多离谱。我们用 张三 的例子来量化这个差距:
- AI 预测分值 (\(b\)) :\(300\)
- 历史真实结果 (\(b_{true}\)) :\(-100\)
- 误差 (Error) :\(b - b_{true} = 300 - (-100) = 400\)
这个 \(400\) 就是我们要消灭的目标。在数学上,我们会把这个误差平方一下,称之为“损失(Loss)”。损失越大,说明矩阵 \(A\) 现在的逻辑越烂。我们的训练目标就是让损失函数最小化。
现在,我们来看一下整个训练过程大概是什么样的。
初始设定:
- 初始权重矩阵 \(A\)* :假设随机初始化为 *\([0, 0, 0.1]\) (即:年龄权重为 0,收入权重为 0,信用分权重为 \(0.1\))。
- 判断标准 :如果计算结果 \(b > 50\),AI 预测为“准予贷款(1)”;否则为“拒绝(0)”。
- 微调步长(学习率) :假设每次出错,我们固定把权重调整 \(0.02\) 。
第一步:输入数据 1(张三):
- 数据 \(x_1\)* :*\([25, 8000, 700]^\top\)(信用分 700)。
- 真实结果 \(y_1\)* :*\(1\)(还钱了)。
- 模型计算结果 \(b\)* :*\(0.1 \times 700 = 70\)。
- AI 预测 :\(70 > 50\),预测为 \(1\)。
- 对比与调整 :预测正确。权重 \(A\) 保持 \([0, 0, 0.1]\) 不变。
第二步:输入数据 2(李四):
- 数据 \(x_2\)* :*\([30, 6000, 450]^\top\)(信用分 450)。
- 真实结果 \(y_2\)* :*\(0\)(没还钱)。
- 模型计算结果 \(b\)* :*\(0.1 \times 450 = 45\)。
- AI 预测 :\(45 < 50\),预测为 \(0\)。
- 对比与调整 :预测正确。权重 \(A\) 依然保持 \([0, 0, 0.1]\) 不变。
第三步:输入数据 3(王五):
- 数据 \(x_3\)* :*\([40, 30000, 650]^\top\)(信用分 650)。
- 真实结果 \(y_3\)* :*\(0\)(虽然信用分高,但意外违约了)。
- 模型计算结果 \(b\)* :*\(0.1 \times 650 = 65\)。
- AI 预测 :\(65 > 50\),预测为 \(1\)(AI 认为他会还钱)。
- 对比与调整 :预测错误! 结果应该是 \(0\)。
- AI 的纠错逻辑 :它发现现在的权重 \(0.1\) 对于高分者太宽松了。
- 微调动作 :为了让计算结果 \(b\) 降下来,它把信用分权重减掉一个步长 \(0.02\)。
- 权重 \(A\) 变为 :\([0, 0, 0.08]\)。
矩阵 \(A\) 的进化路径总结如下:
- 初始状态 :\(A = [0, 0, 0.10]\)
- 过完张三 :\(A = [0, 0, 0.10]\)(无变化)
- 过完李四 :\(A = [0, 0, 0.10]\)(无变化)
- 过完王五 :\(A = [0, 0, 0.08]\)(因为出错而下调)
如果你接着输入 几百万个人 ,权重 \(A\) 就会像这样不断微调:
- 遇到“信用高且还钱”的,它会想往上调一点。
- 遇到“信用高但违约”的,它会想往下调一点。
最终经过几百万次的拉扯,权重会停在一个“全局胜算最大”的数字上(比如 \(0.075\))。这就是为什么我们说 \(Ax=b\) 的过程是在“优化”。矩阵 \(A\) 里的数字不是解出来的,而是被这几百万人“磨”出来的。
在上面的例子中,我们把王五的信用分代入公式\(b = A \times x\),算出\(b=65\),由于 \(65 > 50\),模型给出了“准予贷款”的预测。这是信息从输入层流向输出层。然而,我们立刻发现预测结果(准予)和真实标签(违约)不符。误差 = 预测值 - 真实值。这是反向传播的“发令枪”。没有误差,就没有反向传播。
当结果出错时,AI 会问:“为了让误差变小,我该动谁?” 在你的例子里,公式只有 \(A \times 650\)。链式法则(微积分核心): 数学上,误差对权重 \(A\) 的导数就是 \(650\)。这告诉 AI:“信用分 \(x\) 越大,它对最终错误结果的‘责任’就越大。”这种“把错误从后往前推,计算出每个权重该负多少责”的过程,就是 反向传播 。
在你的例子里只有一层矩阵 \(A\),所以“找谁负责”一眼就能看出来。但如果神经网络有 100 层:
当最后的结果错了,反向传播就像一个极其专业的审计员:
- 它先查第 100 层的责任。
- 再通过第 100 层推导出第 99 层的责任。
- 一路推回第 1 层。
- 如果没有反向传播,深层网络根本没法训练,因为你不知道该拧中间哪一层的旋钮。
在刚才的例子中:
- 计算 \(0.1 \times 650 = 65\)**** 是前向传播。
- 意识到“结果太大了,得减小 \(A\)” 这一瞬间的逻辑推导,就是 反向传播 。
- 把 \(0.1\) 减掉 \(0.02\) 变成 \(0.08\)**** 是优化更新。
更加具体的讲解,可以参考反向传播章节。
Span
我们继续用刚才的例子来说明Span(生成空间)。
假设我们有 3 个人,每个人的特征是“身高”和“体重”:
- 矩阵 \(A\)(数据矩阵): 每一行代表一个人,每一列代表一种特征。 $$ A = \begin{bmatrix} 180 & 75 \ 160 & 50 \ 175 & 80 \end{bmatrix} \begin{matrix} \leftarrow \text{张三} \ \leftarrow \text{李四} \ \leftarrow \text{王五} \end{matrix} $$
- 向量 \(\vec{x}\)(权重向量): 代表你对不同特征的“重视程度”。 $$ \vec{x} = \begin{bmatrix} 0.6 \ 0.4 \end{bmatrix} \begin{matrix} \leftarrow \text{身高的权重} \ \leftarrow \text{体重的权重} \end{matrix} $$
我们现在来看A的列
- 向量 \(v_1\) (身高列) :
[180, 160, 175](代表三位同学的身高分布) - 向量 \(v_2\) (体重列) :
[75, 50, 80](代表三位同学的体重分布)
这里的生成空间,就是当你随意变动身高权重 \(w_1\) 和体重权重 \(w_2\) 时,所能计算出来的 所有可能的“得分结果”向量 。
公式表达: 所有可能的得分向量 \(b = w_1 \cdot \text{身高向量} + w_2 \cdot \text{体重向量}\)
生成空间定义了模型的上限。由于你只有两个特征(身高、体重),你得到的“得分向量”永远只能在这个由两个向量张成的二维平面里跳动。
虽然你有 3 个同学(结果是三维向量),但因为你只有 2 个评价维度,你无法通过调整权重,让三个人得到任意你想要的组合。
- 比如,你可能想让张三得 100 分,李四得 0 分,王五得 50 分。
- 如果这个特定的分数组合
[100, 0, 50]不在身高和体重的“生成空间”里,那么你的模型永远无法通过调整权重来实现这个打分目标。
列空间
列空间 = 矩阵各列的 Span。在深度学习里,这意味着一个神经层(由矩阵 \(W\) 表示)能表达的所有特征,都被锁定在这个矩阵的列空间之内。如果这个空间太“扁”(维度低),模型能学到的东西就很少。
在你的矩阵 \(A = \begin{bmatrix} 180 & 75 \\ 160 & 50 \\ 175 & 80 \end{bmatrix}\) 中:
- 素材 :第一列(身高向量)和第二列(体重向量)。
- Span :是你用这两列向量作为“基础方向”,通过不断改变权重(线性组合)所能到达的所有点的集合。
- 列空间 :就是这个集合本身。它决定了你的模型 \(Ax\) 能输出什么样的结果。
特殊矩阵
逆矩阵
- 单位矩阵 \(I_n\)* :所有沿主对角线的元素都是 *\(1\),其余位置都是 \(0\)(式 2.20)。它的作用是保持向量不变:
- 逆矩阵 \(A^{-1}\)* :通过矩阵逆,我们可以解析地求解 *\(Ax = b\)。
- 从 \(Ax = b\) 开始。
- 两边左乘 \(A^{-1}\):\(A^{-1}Ax = A^{-1}b\)。
- 由于 \(A^{-1}A = I\),所以得到: \(x = A^{-1}b\) 。
这里要注意的是,逆矩阵虽然理论上可以求解,但是并不会在大多数软件或实际应用中被使用,这是因为计算机上只能表现出有限的精度。比如说,计算机无法存储\(\frac{1}{3}\),只能把无限的数字截断,比如变成 0.33333334。这个后果就是当你去计算一个几千行、几万行的巨大矩阵的逆时,这些微小的截断误差会不断 叠加、放大 。最后算出来的结果 \(x\) 可能会和正确答案差之毫厘,失之千里。
由于逆矩阵计算非常耗时,计算量非常大,因此我们并不在实际使用中使用。即便符号计算能够直接计算分数,其效率也非常低下,不如直接计算浮点数来得快。对于大多数现实任务(比如判断贷款、识别猫),精度达到小数点后 7 位或 15 位已经完全足够了。就像你量身高,精确到微米和精确到纳米,对买衣服没有任何区别。
事实上,在LLM开发中,人们更是在进行一场精度大倒退:从追求小数点后十几位,退步到只需要小数点后三四位,甚至更少。计算机存储浮点数(小数)有不同的“包装规格”,位数越少,占用的空间越小,算得越快:
- FP32,单精度,占用32bit,小数点后7位,以前训练DNN的标准
- FP16/BF16,占用16bit,小数点后3位,现在大语言模型如GPT-4就是用这个格式
- INT8/INT4,占用8/4bit,小数点后0位(整数),目标是让手机也能跑模型
甚至有些研究认为,精度低一点反而像一种“噪音”,能防止模型死记硬背数据(过拟合),让它的泛化能力更强。神经网络由数以亿计的参数组成。某个参数的一点点截断误差,会被其他参数的调整所抵消。这就像一万个人合力拉一辆车,其中一个人稍微偏了 1 厘米,不影响车的方向。
Rank(秩)
在线性代数中,Rank一般指秩。矩阵有多少列,决定了列空间最高可能是多少维;但这个矩阵的秩是多少,才决定了列空间实际上是多少维。
现在很多大模型压缩技术(比如 LoRA ),本质上就是发现模型权重的矩阵虽然很大(阶很高),但其实很多列都是线性相关的,其秩其实很小。所以我们只需要训练一个“低秩”的小矩阵,就能达到调整大模型的目的。
在大模型(如 GPT-4)中,权重矩阵 \(W\) 可能是一个 \(10000 \times 10000\) 的庞然大物。科学家发现,尽管这个矩阵很大(阶很高),但它里面的列向量高度 线性相关 。这意味着它的秩(Rank) 其实很小。既然真正“干活”的独立维度不多,我们就不需要用 \(10000 \times 10000\) 个参数来存储它。我们把它拆解为两个长条形的小矩阵相乘:\(A \times B\)。矩阵 \(A\) 是 \(10000 \times r\)。矩阵 \(B\) 是 \(r \times 10000\)。这里的 \(r\) 就是我们设定的 秩 (通常非常小,比如 \(r=8\) 或 \(r=64\))。原本需要存储 \(10000 \times 10000 = 1 亿\) 个参数。现在只需要 \(10000 \times 8 + 8 \times 10000 = 16 万\) 个参数。计算机计算两个瘦长矩阵的乘法,比计算一个巨大的方阵快得多,这直接提升了推理速度。
在深度学习中,如果一个层的权重矩阵发生了“秩亏” (Rank Deficient),意味着:模型原本有 512 个神经元,但因为秩太低,只有 10 个神经元在干不同的活,其他的都在划水(线性相关)。你的“列空间”塌陷了,模型无法分辨复杂的输入差异。这就是为什么在大模型微调(如 LoRA )里,我们会主动选择一个 很小的秩 \(r\)**** :既然大矩阵内部本来就有很多重复(实际秩很小),那我就干脆只训练一个秩只有 8 或 16 的小矩阵。这个小矩阵虽然“阶”小,但它每一列都有“实际意义”,计算效率极高。
方阵
方阵 (Square Matrix) :必须满足 \(m = n\)(行数 = 列数),即输入维度与输出维度相等。
线性无关 :方阵的所有列向量必须彼此独立,不能存在冗余。
奇异矩阵 (Singular) :如果方阵的列向量线性相关(即“秩”不足),则称为奇异矩阵。奇异矩阵在变换过程中会丢弃信息(发生维度塌陷),导致无法通过逆矩阵 \(A^{-1}\) 找回原始输入。
对角矩阵
对称矩阵
其他概念
正交
Ian教材2.6,如果涉及到再看看
特征分解
Ian教材2.7,如果涉及到再看看
奇异值分解
Ian教材2.8,如果涉及到再看看
附:Excersize
Ex.1 线性代数练习
在上面我们已经知道线性代数在机器学习中的作用了。简单来说就是当我们有一个输入vector后,如果我们能找到一个合适的矩阵A,那么我们就能得到一个结果vector。
练习1:Prove that \(A^{T}A\) is symmetric for any \(A \in\mathbb{R}^{m \times n}\)
\(A^T\)的意思是矩阵的转置(Transpose),操作就是把一个矩阵的行和列互换,比如:
$$ A = \begin{bmatrix}
1 & 2 & 3 \
4 & 5 & 6
\end{bmatrix} $$
transpose后:
$$ A^T = \begin{bmatrix}
1 & 4 \
2 & 5 \
3 & 6
\end{bmatrix} $$
然后\(A \in \mathbb{R}^{m \times n}\)的意思是矩阵A的归属是实数(Real Numbers),然后行数x列数为\(m*n\)。组合起来就是说A是一个m行n列的矩阵,并且矩阵中的所有元素都是实数。
对于两个矩阵的乘法,计算过程就是用第一个矩阵的第一行,先和第二个矩阵的每一列相乘,得到新的矩阵的第一行;然后用第一个矩阵的第二行,再依次和第二个矩阵的每一列相乘,得到新的矩阵的第二行。也就是说新的矩阵的行数,等于第一个矩阵的行数;新的矩阵的列数,等于第二个矩阵的列数。因此矩阵的乘法是不可交换的,A x B,和B x A,是两个不同的计算过程。
我们拿上述的A和A^T来试算一下:
$$ A^T A =
\begin{bmatrix}
1 & 4 \
2 & 5 \
3 & 6
\end{bmatrix}
\begin{bmatrix}
1 & 2 & 3 \
4 & 5 & 6
\end{bmatrix} $$
计算过程:
$$ \begin{aligned}
(A^T A)_{11} &= 1\cdot1 + 4\cdot4 = 1 + 16 = 17 \
(A^T A)_{12} &= 1\cdot2 + 4\cdot5 = 2 + 20 = 22 \
(A^T A)_{13} &= 1\cdot3 + 4\cdot6 = 3 + 24 = 27 \
(A^T A)_{21} &= 2\cdot1 + 5\cdot4 = 2 + 20 = 22 \
(A^T A)_{22} &= 2\cdot2 + 5\cdot5 = 4 + 25 = 29 \
(A^T A)_{23} &= 2\cdot3 + 5\cdot6 = 6 + 30 = 36 \
(A^T A)_{31} &= 3\cdot1 + 6\cdot4 = 3 + 24 = 27 \
(A^T A)_{32} &= 3\cdot2 + 6\cdot5 = 6 + 30 = 36 \
(A^T A)_{33} &= 3\cdot3 + 6\cdot6 = 9 + 36 = 45
\end{aligned} $$
得到结果:
$$ A^T A =
\begin{bmatrix}
17 & 22 & 27 \
22 & 29 & 36 \
27 & 36 & 45
\end{bmatrix} $$
请注意观察 :
- 元素(1,2) 和 元素(2,1) 都是 22。
- 元素(1,3) 和 元素(3,1) 都是 27。
- 元素(2,3) 和 元素(3,2) 都是 36。
这个矩阵沿着对角线是完美对称的,也就是题目中所问的symmetric。
我们现在反过来,算一下A * A^T:
$$ A A^T =
\begin{bmatrix}
1 & 2 & 3 \
4 & 5 & 6
\end{bmatrix}
\begin{bmatrix}
1 & 4 \
2 & 5 \
3 & 6
\end{bmatrix} $$
逐项计算:
$$ \begin{aligned}
(AA^T)_{11} &= 1\cdot1 + 2\cdot2 + 3\cdot3 = 1 + 4 + 9 = 14 \
(AA^T)_{12} &= 1\cdot4 + 2\cdot5 + 3\cdot6 = 4 + 10 + 18 = 32 \
(AA^T)_{21} &= 4\cdot1 + 5\cdot2 + 6\cdot3 = 4 + 10 + 18 = 32 \
(AA^T)_{22} &= 4\cdot4 + 5\cdot5 + 6\cdot6 = 16 + 25 + 36 = 77
\end{aligned} $$
最终结果:
$$ A A^T =
\begin{bmatrix}
14 & 32 \
32 & 77
\end{bmatrix} $$
这个结果也是对称的,但是结果却不同。
我们要关注两件事情:
1.结果是对称的
2.先后顺序在机器学习中的应用
首先,结果是对称的,说明两个矩阵的关系是相互的。即:
- 矩阵
S的元素S[i, j]代表了 “事物i” 与 “事物j” 的关系。 - 矩阵
S的元素S[j, i]代表了 “事物j” 与 “事物i” 的关系。
对称性 S[i, j] = S[j, i] 就意味着:
i对j的影响/关系,和j对i的影响/关系是完全一样的。
也就是说:
- 如果一个矩阵描述的是“城市间的飞行距离”,那它必然是对称的。纽约到波士顿的距离,等于波士顿到纽约的距离。
- 如果一个矩阵描述的是“特征间的相关性”,那它必然是对称的。“身高”与“体重”的相关性,和“体重”与“身高”的相关性是同一个数值。
这个特性是我们用来衡量两个特征之间相关性的标准方法。
其次,假如A矩阵代表的是数据集矩阵,其每一行代表一个数据样本,比如一个病人、一栋房子、一朵花,那m行就代表我们有m个样本。然后A的每一列代表一个特征,比如房子的面积、卧室的数量,那么我们就有了n个 特征。
对于\(m*n\)的矩阵A,\(A^TA\)的含义是feature correclation matrix特征相关性矩阵,其结果是一个\(n*n\)的新矩阵,这个新矩阵衡量的是n个特征两两之间的关系。这种用法常在Linear Regression线性回归和PCA主成分分析中使用。简单来说,就是告诉我们数据集的特征之间是如何相互关联的,这是分析数据结构的基础。
而对于\(AA^T\),我们将得到一个\(m*m\)的新矩阵。这个新矩阵衡量的是样本两两之间的关系,因此视角是以样本为中心的。别忘了,我们刚才说过,m行代表的是m个样本。那么利用这种结果,我们可以找到两个样本之间特征是否相似。这个在SVMs支持向量机、Kernel Methods核方法、Clustering聚类分析中使用的比较多。
好,那现在我们理解了对称性和矩阵乘法在机器学习中的作用后,我们再来证明一下该命题。利用乘积的转置法则和转置的转置法则,我们可以得到:
练习2:
考虑以下矩阵,请找出B的singular values(奇异值):
$$ B = \begin{bmatrix}
1 & 0 \
0 & 2 \
2 & 1
\end{bmatrix} $$
singular values是线性代数中极其重要的概念,这个值能快速提取出一个矩阵的重要核心信息。比如说,你喝了一杯很好喝的鸡尾酒,假设这个鸡尾酒就是上面这个B,那么你一定想要知道这个鸡尾酒的配方是什么。比如这个鸡尾酒有如下风味:
- 风味A:香甜
- 风味B:酸涩
- 风味C:清凉
然后你给这些风味打分:
- 香甜:10分
- 酸涩:7分
- 清凉:1分
这几个分数,就是奇异值!其中香甜是这杯鸡尾酒最大的特征,其次是酸涩和清凉。换句话说,奇异值就是一个复杂事务(如一个矩阵、一张图片、一杯鸡尾酒)中各个核心组成部分的重要性排名。
以上面的矩阵B为例,他的奇异值如下:
- \(\sigma_{1} = \sqrt{7}\)
- \(\sigma_{2} = \sqrt{3}\)
这两个抽象的sigma,揭示了B矩阵这个变换的核心本质。其意义包括:
- 几何上的意义:B将二维空间 的单位圆变换成三维空间的椭圆的时候的最大和最小的 拉伸比例
- 信息的重要性和降维:如果B是一个数据集,那么第一个奇异值将代表数据的主要变化和信息
- 用途:按\(\sigma_1\)进行数据压缩,可以保留B矩阵最核心的特征
具体的用途在之后遇到时我们再详细讲解。
奇异值计算步骤通常是:
- 计算 B 的转置矩阵 BT。
- 计算 BT 与 B 的乘积,得到一个新的方阵 (BTB)。
- 计算矩阵 BTB 的特征值 (eigenvalues)。
- 将这些特征值取正平方根,得到的结果就是矩阵 B 的奇异值。
那么对于矩阵B,其转置矩阵与B的乘积:
$$ B^T B =
\begin{bmatrix}
1 & 0 & 2 \
0 & 2 & 1
\end{bmatrix}
\begin{bmatrix}
1 & 0 \
0 & 2 \
2 & 1
\end{bmatrix} $$
计算得到:
$$ \begin{bmatrix}
1\cdot1 + 0\cdot0 + 2\cdot2 & 1\cdot0 + 0\cdot2 + 2\cdot1 \
0\cdot1 + 2\cdot0 + 1\cdot2 & 0\cdot0 + 2\cdot2 + 1\cdot1
\end{bmatrix}
=
\begin{bmatrix}
5 & 2 \
2 & 5
\end{bmatrix} $$
用这个结果代入矩阵的characteristic polynomial特征多项式:
这里的p是polynomial多项式的首字母缩写,一般代表多项式。lambda是eigenvalue特征值,在这里作为一个变量存在。
这里的det是Determinant的缩写,中文是行列式。行列式是作用于一个行数和列数相等的矩阵的函数,他会计算出一个标量。这个标量浓缩了关于这个矩阵变换的很多重要信息。正因如此,我们才在一开始需要通过计算B转置和B的乘积,来得到一个方阵。
对于一个2x2的矩阵,det就是主对角线(从左上角到右下角)上元素的乘积,减去副对角线上元素的乘积。3x3和更大的矩阵,则需要更多不同的技巧,这里就不赘述了。我们只要记住,我们可以用det操作得到一个方阵的特征多项式并找到这个方阵的奇异值就可以了。具体的计算我们可以依赖NumPy库来完成:
import numpy as np
M = np.array([
[4, 2, 1, 0],
[1, 3, 2, 1],
[0, 1, 5, 2],
[2, 3, 1, 1]
])
# 3. 调用 np.linalg.det() 函数计算行列式
# 无论矩阵是2x2, 4x4, 还是100x100,调用的函数都是同一个
determinant_value = np.linalg.det(M)
# 4. 打印出原始矩阵和计算结果
print("创建的4x4矩阵 M:")
print(M)
print("\n计算出的行列式 det(M):")
print(determinant_value)
其中\(I\)是单位矩阵,我们现在可以得到这个特征多项式了:
$$ \det !\left(
\begin{bmatrix}
5 & 2 \
2 & 5
\end{bmatrix}
- \lambda
\begin{bmatrix}
1 & 0 \
0 & 1
\end{bmatrix}
\right)
=
\det !\begin{bmatrix}
5 - \lambda & 2 \
2 & 5 - \lambda
\end{bmatrix} $$
得到该特征多项式后,我们可以把让该多项式等于0,即可得到特征多项式的特征值:
得到两个特征值后,我们就可以得到奇异值了。奇异值是两个特征值的平方根(严格来说,奇异值是\(A^TA\)的特征值开方,而对于对称正定矩阵,\(A^TA=A^2\),所以奇异值就是特征值的正平方根),因此:
$$ \sigma_1 = \sqrt{\lambda_1} = \sqrt{7},
\quad
\sigma_2 = \sqrt{\lambda_2} = \sqrt{3} $$
Ex.2 链式法则练习
练习1: Consider the function
where
$$ a, b \in\mathbb{R},
\quad
\sigma(t) = \frac{1}{1 + e^{-t}} \quad for
\quad t \in\mathbb{R}. $$
首先我们来看一下这个函数f(x, y) = σ(ax + by),这是一个接收x和y两个变量作为输入的函数。他的计算过程是两步:
- 先计算
ax + by。这在机器学习里叫做输入的 线性组合 (a和b可以看作是权重)。 - 然后将这个结果作为输入,传递给另一个函数
σ。σ在这里被称为 激活函数 (Activation Function) 。
然后再看一下 σ(t),这个函数有一个非常著名的名字,叫 Sigmoid 函数 ,也叫 Logistic 函数。它的作用是把任何一个实数 t(无论多大或多小)都压缩到 (0, 1) 这个区间内。因为这个特性,它经常在机器学习中被用来表示概率。
所以,整个函数 f(x,y) 的意思就是:接收输入 x 和 y,用权重 a 和 b 进行加权求和,然后用 Sigmoid 函数处理这个和,得到一个 0到1 之间的最终输出。
(a) Show that
解答:
$$ \frac{d}{dt}\sigma(t)
= \frac{d}{dt}\left(\frac{1}{1+e^{-t}}\right) $$
这个结论在机器学习中非常有名且非常常用,因为它让求导(也就是求梯度)变得非常方便。
(b) Using the result you showed in part(a) and the chain rule, compute \(\frac{\partial f}{\partial x}\) and \(\frac{\partial f}{\partial y}\).
我们来计算函数 \(f(x, y) = \sigma(ax + by)\) 对 \(x\) 和 \(y\) 的偏导数。
首先计算 \(\frac{\partial f}{\partial x}\)。这是一个复合函数,为了应用链式法则,我们视内层的线性部分 \(ax + by\) 为一个整体,并记作 \(z\)。这样函数就变成了 \(f = \sigma(z)\)。
根据链式法则,\(f\) 对 \(x\) 的导数等于外层函数对 \(z\) 的导数与内层函数对 \(x\) 的导数的乘积:
$$ \frac{\partial f}{\partial x}
= \frac{d\sigma}{dz} \cdot\frac{\partial z}{\partial x} $$
我们知道第一问的结论是 \(\frac{d\sigma}{dz} = \sigma(z)\big(1 - \sigma(z)\big)\),同时,内层函数对 \(x\) 的偏导数是 \(\frac{\partial z}{\partial x} = a\)。
将这两部分相乘,我们得到:
$$ \frac{\partial f}{\partial x}
= \sigma(z)\big(1 - \sigma(z)\big) \cdot a $$
最后,我们将 \(z = ax + by\) 代回,并整理成您提供的最终格式:
$$ \frac{\partial f}{\partial x}
= \boxed{a \, \sigma(ax + by)\big[1 - \sigma(ax + by)\big]} $$
计算对 \(y\) 的偏导数 \(\frac{\partial f}{\partial y}\) 的过程完全同理。链式法则的应用如下:
$$ \frac{\partial f}{\partial y}
= \frac{d\sigma}{dz} \cdot\frac{\partial z}{\partial y} $$
其中,外层函数的导数部分不变,我们只需计算内层函数对 \(y\) 的偏导数,即 \(\frac{\partial z}{\partial y} = b\)。
将它们相乘得到:
$$ \frac{\partial f}{\partial y}
= \sigma(z)\big(1 - \sigma(z)\big) \cdot b $$
同样地,将 \(z = ax + by\) 代回,我们得到关于 \(y\) 的最终偏导数:
$$ \frac{\partial f}{\partial y}
= \boxed{b \, \sigma(ax + by)\big[1 - \sigma(ax + by)\big]} $$
练习2:
For
$$ \mathbf{x} =
\begin{bmatrix}
x_{1} \
\vdots \
x_{n}
\end{bmatrix}
\in\mathbb{R}^n $$
define
Compute the partial derivative \(\frac{\partial r}{\partial x_i}\) for a generic coordinate \(i \in \{1, \ldots, n\}\)
解答:
这道题定义了一个向量x,该向量由n个分量组成。然后定义了一个函数r(x),其计算方式是将向量x的每一个分量都进行平方,然后将所有结果相加。数学表达式为:
$$ r(\mathbf{x}) = \sum_{j=1}^{n} x_j^2
= x_1^2 + x_2^2 + \cdots + x_n^2 $$
这个函数实际上计算的是向量 x 的欧几里得范数(即向量长度)的平方。
而题目要求我们来计算函数r相对于其任意一个分量\(x_i\)的偏导数(partial derivative)。
在计算偏导数\(\frac{\partial r}{\partial x_i}\)的时候,我们要将除了\(x_i\)之外的其他所有分量都当作常数来处理,因此对于上述展开的r(x),很显然,如果除了\(x_i\)之外的其他分量都被视为常数,那么这些常数在求导的过程中会变为0,也即:
$$ \frac{\partial}{\partial x_i}(x_j^2) = 0
\quad (\text{对于所有 } j \ne i) $$
那么根据幂函数的求导法则($\frac{d}{dx} x^k = k x^{k-1} $),我们可以得到
由于其他项都是0,因此:
练习3:
Let $\mathbf{w} \in\mathbb{R}^n $ be a constant vector and define the scalar function
$$ s(\mathbf{x}) = \mathbf{w}^\top\mathbf{x}
= \sum_{j=1}^{n} w_j x_j $$
Compute \(\frac{\partial s}{\partial x_i}\) for a generic coordinate \(i \in \{1, \ldots, n\}\)
解答:
这道题的意思就是给你一个固定的 n 维向量 w 和一个变量 n 维向量 x 。用这两个向量的点积定义了一个函数 s(x)。现在请你求出这个函数 s 相对于变量向量 x 的第 i 个分量 xi 的偏导数。
比如假设 n=3,那么:
*\(w=w1,w2,w3\)(三个固定的数)
- \(x=x1,x2,x3\) (三个变量)
- \(s(\mathbf{x}) = w_1 x_1 + w_2 x_2 + w_3 x_3\)
我们要求的就是用一个通用的表达式来代表\(\frac{\partial s}{\partial x_i}\)。
那么对于这种题,其实我们把函数s(x)展开来写就很清晰了:
现在对上面展开的式子求导:
利用导数的加法法则,我们可以对每一项分别求导:
$$ \frac{\partial s}{\partial x_i}
= \frac{\partial}{\partial x_i}(w_1 x_1)
- \frac{\partial}{\partial x_i}(w_2 x_2)
- \cdots
- \frac{\partial}{\partial x_i}(w_i x_i)
- \cdots
- \frac{\partial}{\partial x_i}(w_n x_n) $$
和练习2类似,当我们对wi求导的时候,非wi的项目在求导中都被视为常数,因此求导后是0.
而对于wi的目标项,可以得到:
$$ \frac{\partial}{\partial x_i}(w_i x_i)
= w_i \cdot\frac{\partial}{\partial x_i}(x_i)
= w_i \cdot1
= w_i $$
所以:
Ex.3 概率论练习
An incoming email is spam with prior \(p(S)=0.2\) and not spam with \(p(\bar{S}) = 0.8\).
Two independent filters flag spam:
annd \(F_1, F_2\) are inndependent given the class \((S or \bar{S})\).
(a) What is the probability that both filters flag an email as spam?
首先,我们把题目给出的所有信息翻译成通俗的语言:
p(S) = 0.2: "S" 代表 "Spam" (垃圾邮件)。这句话的意思是,在没有任何其他信息的情况下,一封随机收到的邮件是 垃圾邮件的概率为20% 。这是 先验概率* 。
p(S̄) = 0.8: "S̄" 代表 "Not Spam" (非垃圾邮件)。一封邮件 不是垃圾邮件的概率为80%* 。同样是先验概率。
接下来是关于两个垃圾邮件过滤器(Filter 1 和 Filter 2)的信息:
p(F₁=1 | S) = 0.9: F₁=1 表示“过滤器1将邮件标记为垃圾邮件”。这句话的意思是:如果一封邮件确实是*垃圾邮件,那么过滤器1有90%的概率能正确地把它标记出来(这是过滤器1的“召回率”或“真阳性率”)。
p(F₁=1 | S̄) = 0.1: 如果一封邮件不是*垃圾邮件,过滤器1仍然有10%的概率会错误地把它标记为垃圾邮件(这是过滤器1的“假阳性率”)。
p(F₂=1 | S) = 0.8: 如果一封邮件确实是*垃圾邮件,过滤器2有80%的概率能正确标记它。
p(F₂=1 | S̄) = 0.05: 如果一封邮件不是*垃圾邮件,过滤器2有5%的概率会错误标记它。
最后一句关键信息:
F₁, F₂ are independent given the class (S or S̄): 这叫做 条件独立 。意思是:一旦我们确定了一封邮件的真实类别(是垃圾邮件,或不是),那么两个过滤器的判断就 互不影响* 。
- 例如,对于一封已知的垃圾邮件,过滤器1是否标记它,和过滤器2是否标记它,是两个可以相乘的独立概率事件。
这一小问问的是:“ 两个过滤器同时把一封邮件标记为垃圾邮件的总概率是多少? ”
这里的关键点在于,这个问题并没有告诉你这封邮件 本身到底是不是垃圾邮件 。所以,要计算这个总概率,你必须考虑两种可能发生并导致这个结果的 互斥场景 :
场景一* :这封邮件 确实是垃圾邮件(S)** ,并且两个过滤器都正确地标记了它。
场景二* :这封邮件 其实不是垃圾邮件(S̄)** ,但两个过滤器都犯了错误,同时标记了它。
这道题最终想让你计算的,就是 场景一发生的概率 + 场景二发生的概率 。这背后运用的原理就是我们之前提过的 全概率公式 。
我们可以分别计算两个场景的概率,然后得到答案:
场景一:
邮件是垃圾邮件(S),并且两个filter都标记了它。我们计算这个特定场景发生的联合概率: \(P(A \cap S)\),根据条件概率的定义,我们知道:
由于\(P(S)\)是已知的先验概率,为0.2。\(P(A \mid S)\)指的是“在一封确认为垃圾邮件的邮件中,两个filter都标记它的概率”。因为题目已经说明两个filter条件独立,所以我们可以将他们相乘:
代入数值得到:
场景一的总概率便得到了:
同理,场景二的总概率\(P(A \cap \bar{S})\)也可以用同样的方法得到:
把两个互斥场景的概率相加,即得到总概率:
(b) Given that both filters flag an email, what is the probability of the email being spam? (You can leave your answer as an unsimplified fraction.)
在上一问,我们算出了被两个filter同时标记为垃圾邮件的概率。而这一问问的则是,对于那些已经被两个filter同时标记的邮件,其为真垃圾邮件的比例是多少。这是一个后验概率。
回忆一下贝叶斯公式:
在这道题中:
- Y = 邮件真的是垃圾邮件(S)
- X = 邮件被两个filters同时标记(我们之前称之为事件A)
所以代入到贝叶斯公式中,可以得到 :
翻译一下就是:
P(邮件是垃圾 | 被两个滤镜标记) = P(邮件是垃圾 并且 被两个滤镜标记) / P(被两个滤镜标记)
在第一问中,我们已经知道:
- \(P(A) = 0.148\)
- \(P(A \cap S)=0.144\)
代入可得:
.