第 2 章 前置知识:线性代数、微积分、概率统计与 Python 计算
2.1 学习目标
- 掌握神经网络中最常用的数学对象:向量、矩阵、张量、范数与广播。
- 理解导数、偏导数、梯度、雅可比矩阵与链式法则。
- 建立概率统计直觉,理解期望、方差、似然、交叉熵与 KL 散度。
- 能用 Python / Numpy 实现基础数值运算,为后续从零实现网络做准备。
- 为后面的反向传播、损失函数和优化算法打好理论底座。
能力矩阵:
| 能力域 | 入门 | 进阶 | 熟练 |
|---|---|---|---|
| 线性代数 | 会矩阵乘法 | 理解向量空间与投影 | 理解 SVD、特征值与低秩近似 |
| 微积分 | 会求单变量导数 | 理解偏导与链式法则 | 能推导矩阵求导 |
| 概率统计 | 会算均值方差 | 理解条件概率与分布 | 理解交叉熵、KL 和最大似然 |
| 编程实现 | 会用 Python | 会用 Numpy 向量化 | 能写数值稳定代码 |
2.2 为什么神经网络需要这些前置知识
神经网络训练的核心操作就是“对很多参数求梯度,然后做迭代更新”。这件事天然依赖数学基础:
- 线性代数负责描述数据与参数的批量运算;
- 微积分负责描述参数变化对损失的影响;
- 概率统计负责描述不确定性、噪声与泛化;
- 优化理论负责告诉我们如何更快更稳地下降损失。
如果缺少这些基础,常见症状是:
- 看得懂代码,但看不懂公式;
- 能跑通模型,但不知道为什么收敛;
- 能调参数,但不知道为什么过拟合;
- 知道准确率,却解释不了交叉熵和概率输出。
2.3 线性代数基础
2.3.1 标量、向量、矩阵、张量
| 对象 | 记法 | 示例 |
|---|---|---|
| 标量 | 3.14 | |
| 向量 | ||
| 矩阵 | 数组 | |
| 张量 | 多维数组 |
在神经网络中:
- 单个样本常表示为向量;
- 一个 batch 是矩阵;
- 图像、视频、序列常表示为更高阶张量。
2.3.2 矩阵乘法
若 ,,则:
元素级定义:
神经网络中的线性层本质就是矩阵乘法加偏置:
2.3.3 向量范数
常见范数:
- 范数:
- 范数:
- 范数:
范数常用于:
- 正则化
- 距离度量
- 梯度裁剪
- 参数约束
2.3.4 点积与几何意义
点积可以理解为:
- 衡量两个向量的相似程度;
- 投影长度的基础;
- 线性分类器的打分函数。
2.3.5 特征值与特征向量
若 ,则 是特征向量, 是特征值。
它们在神经网络中的作用包括:
- 理解 Hessian 的曲率;
- 分析优化难度;
- 理解 PCA 与降维;
- 理解矩阵分解和低秩近似。
2.3.6 SVD
奇异值分解:
用途:
- 压缩模型参数;
- 观察数据主方向;
- 做低秩近似;
- 解释 Embedding 和表示空间。
2.4 微积分基础
2.4.1 导数
导数描述函数在某一点的变化率:
如果函数增加很快,则导数较大;若函数不变,则导数接近 0。
2.4.2 偏导数
多变量函数 对某个变量求导:
神经网络中,损失函数依赖很多参数,因此几乎总是使用偏导。
2.4.3 梯度
梯度是所有偏导组成的向量:
梯度的方向是函数增长最快的方向,因此梯度下降要沿着负梯度方向走。
2.4.4 链式法则
链式法则是反向传播的数学核心。
若:
则:
在神经网络里,计算图往往很长,因此链式法则会被重复应用很多次。
2.4.5 泰勒展开
一阶泰勒近似:
它帮助我们理解:
- 梯度下降为什么能下降损失;
- 为什么学习率太大会发散;
- 为什么局部曲率会影响训练。
2.5 概率统计基础
2.5.1 概率与条件概率
条件概率在分类和生成模型中都非常重要。
2.5.2 随机变量与分布
常见分布:
- 伯努利分布:二分类
- 多项分布:多分类
- 正态分布:噪声建模与初始化
- 指数分布:等待时间
2.5.3 期望与方差
在训练中:
- 期望表示平均性能;
- 方差表示波动程度;
- 高方差常意味着模型不稳定或过拟合。
2.5.4 最大似然估计
给定样本数据 和参数 ,最大似然是找让数据最可能出现的参数:
训练分类模型时,交叉熵损失往往就是负对数似然。
2.5.5 交叉熵
若真实分布为 ,预测分布为 ,则交叉熵为:
在 one-hot 标签下,交叉熵等价于只关注正确类别的负对数概率。
2.5.6 KL 散度
关系:
这说明最小化交叉熵等价于让预测分布接近真实分布。
2.6 Python 与 Numpy 预备
2.6.1 向量化思维
神经网络训练需要大量矩阵运算,应该尽量避免 Python 级 for 循环。
import numpy as np
x = np.array([1.0, 2.0, 3.0])w = np.array([0.5, -1.0, 2.0])
score = x @ wprint(score)2.6.2 批量数据形状
X = np.random.randn(32, 784) # batch_size = 32, features = 784W = np.random.randn(784, 128)b = np.zeros((1, 128))Z = X @ W + b这里:
32表示 batch 大小;784可以表示 28x28 图片展平后的像素数;128是隐藏层宽度。
2.6.3 数值稳定性
直接计算 log(0)、exp(1000) 都会出问题,因此要注意:
- softmax 用减最大值稳定化;
- log 要加 epsilon;
- 归一化时避免除以零;
- 梯度可能爆炸或消失。
def stable_softmax(logits): shifted = logits - np.max(logits, axis=1, keepdims=True) exp_logits = np.exp(shifted) return exp_logits / np.sum(exp_logits, axis=1, keepdims=True)2.6.4 广播机制
Numpy 的广播允许不同形状的数组在一定规则下自动扩展。它对深度学习非常重要,因为:
- 偏置通常按 batch 广播;
- 标量学习率作用到参数矩阵;
- 一些归一化参数需要按通道广播。
2.7 从数学到神经网络
2.7.1 为什么线性变换不够
若只有线性组合:
多个线性层仍然等价于一个线性层,表达能力没有本质增强。
因此必须引入非线性激活函数:
2.7.2 为什么要用概率视角
分类任务的输出通常需要概率解释。Softmax + 交叉熵提供了:
- 可解释的概率输出;
- 易于优化的损失函数;
- 和最大似然一致的训练目标。
2.7.3 为什么要用链式法则
神经网络由很多模块串联,若要知道某个参数如何影响最终损失,必须把局部导数一层层传回去。这正是反向传播。
2.8 重点公式速查
| 主题 | 公式 |
|---|---|
| 向量点积 | |
| 线性层 | |
| 梯度 | |
| 链式法则 | |
| Softmax | |
| 交叉熵 | |
| KL 散度 |
2.9 常见误区
- 以为矩阵乘法只是在“套公式”。实际上它决定了特征如何组合。
- 以为梯度就是“一个分数”。实际上梯度是向量,表示每个参数的更新方向。
- 以为交叉熵只是分类里的一个损失名称。实际上它有严格的概率解释。
- 以为数值稳定性只是“工程细节”。实际上它直接影响训练能否继续。
- 以为广播只是语法糖。实际上它决定了张量操作是否高效。
2.10 本章小结
本章提供的不是孤立公式,而是神经网络训练所需的数学工具箱:
- 线性代数描述输入、参数与表示;
- 微积分描述误差如何传播;
- 概率统计描述输出的意义与训练目标;
- Python / Numpy 负责把这些理论变成可运行代码。
2.11 课后练习
- 写出 的维度要求,并说明每个维度代表什么。
- 用自己的话解释链式法则为什么是反向传播的基础。
- 说明为什么交叉熵常用于分类而不是均方误差。
- 解释 softmax 为什么要做数值稳定化。
- 用 Numpy 实现一个二维数组的标准化函数。
2.12 矩阵微积分:从元素导数到矩阵导数
在深度学习中,我们通常更关心以向量或矩阵为变量的导数,而不是逐元素展开的标量导数。矩阵微积分能让我们用紧凑的符号表达反向传播。下面给出一系列常用结论与证明要点。
2.12.1 标量对向量的导数
若 ,,则梯度定义为列向量:
例如:若 ,则 。
2.12.2 标量对矩阵的导数
若 ,对矩阵 的导数通常以与 同形的矩阵表示,元素为对应的偏导数。
例如:,则 。
证明技巧:把矩阵按元素展开,利用线性算子与迹的性质。
2.12.3 常用矩阵导数规则速查
- 。
- (需注意形状)。
- 若 , 为标量,则:。
这些规则可从元素级定义或迹运算推导而来。
2.13 Jacobian 与 Hessian:雅可比矩阵与二阶导数
2.13.1 Jacobian
对于向量值函数 ,Jacobian 定义为:
Jacobian 在反向传播中用于把上游的向量梯度映射回前一层:若上游有向量梯度 ,则
2.13.2 Hessian
Hessian 是二阶导数组成的矩阵,描述函数曲率:
在优化中,Hessian 的特征值决定了局部曲率:大特征值对应陡峭方向,小特征值对应平坦方向;负特征值意味着鞍点或局部最大值。
但 Hessian 计算和存储代价高(O(n^2) 或更多),所以深度学习通常使用一阶方法或近似二阶方法。
2.14 矩阵分解与 PCA 的数值实现
主成分分析(PCA)可以通过 SVD 高效实现。给定数据矩阵 (每行一个样本,已中心化),SVD 给出:
取前 列对应最大奇异值即可得到 维低秩近似。PCA 的解释变换矩阵为 ,投影后的表示为 。
NumPy 实现示例:
import numpy as np
def pca(X, k): # X: (N, D) Xc = X - X.mean(axis=0) U, S, Vt = np.linalg.svd(Xc, full_matrices=False) return Vt[:k].T, S[:k]
# 使用:# V_k, S_k = pca(X, k=10)# X_reduced = Xc.dot(V_k)注意:对大规模数据建议使用增量 SVD(sklearn.decomposition.IncrementalPCA)或随机 SVD(sklearn.utils.extmath.randomized_svd)。
2.15 最小二乘与正规方程
线性回归的闭式解(最小二乘):给定 ,,损失为 ,则最优解满足正规方程:
实现注意:如果 不可逆或条件数不好,使用正则化(岭回归)或数值稳定的 np.linalg.lstsq。
NumPy 示例:
w, *_ = np.linalg.lstsq(X, y, rcond=None)2.16 数值微分与稳定的梯度检验
前文提到有限差分用于梯度检验,这里给出更系统的实现以及注意点。
中心差分(central difference)比前向差分更精确:
实现要点:
- 只在小规模模型和少量参数上做;
- 使用 double 精度;
- 防止数值舍入误差(选择合适的 epsilon)。
def numerical_grad(f, theta, eps=1e-6): g = np.zeros_like(theta) it = np.nditer(theta, flags=['multi_index'], op_flags=['readwrite']) while not it.finished: idx = it.multi_index old = theta[idx].copy() theta[idx] = old + eps fx1 = f(theta) theta[idx] = old - eps fx2 = f(theta) g[idx] = (fx1 - fx2) / (2*eps) theta[idx] = old it.iternext() return g2.17 概率基础扩展:似然、对数似然与贝叶斯视角
最大似然估计(MLE)是参数估计的基石。对数似然更常用:
贝叶斯方法在 MLE 上引入先验 ,求后验:
MAP(最大后验)估计等价于在损失中加入正则项。
2.18 信息论引入:熵、交叉熵与互信息
熵衡量分布的不确定度:
互信息(Mutual Information)衡量两个变量的信息共享:
在表征学习与信息瓶颈等理论中,这些量有助于理解表征压缩与任务相关性。
2.19 经典分布与估计方法速查
- 伯努利 / 二项分布:参数 ,均值 ,方差 。
- 正态分布:rac{1}{\sqrt{2\pi\sigma^2}}e^{-(x-\mu)^2/(2\sigma^2)}。
- 指数分布、Gamma 分布在等待时间和贝叶斯先验中常见。
估计方法:MLE、MAP、贝叶斯推断、EM 算法(用于含隐变量的模型,如混合高斯)。
2.20 优化基础:凸性、收敛与学习率选择
若损失是凸的,全局最优易于找到;但神经网络通常非凸,优化变成启发式。
常见结论(仅作直觉):
- 学习率过大会发散;
- 学习率过小收敛慢;
- 动量能在局部鞍点处帮助离开平坦区域;
- 批量大小影响噪声水平:小 batch 更噪但具有正则效果。
实践建议:使用学习率搜索(learning rate finder),先做 warmup 再采用衰减策略。
2.21 激活函数的导数与数值特性
列出常用激活及其导数与工程注意事项:
- Sigmoid: , 。易饱和,导致梯度消失。
- Tanh: , 。中心化但仍易饱和。
- ReLU: ,导数为 1(正区间)或 0(负区间)。简单且效果好,但死神经元问题存在。
- Leaky ReLU: 着色 ReLU 以避免死神经元,负区间斜率小于 1。
- Softplus: 平滑版本的 ReLU,导数是 sigmoid。
选择激活时综合考虑梯度流和模型表达能力。
2.22 从零实现的练习:逻辑回归与交叉熵
实现逻辑回归训练的完整流程:数据生成、模型、损失、梯度、优化循环与评估。
import numpy as np
def sigmoid(x): return 1/(1+np.exp(-x))
def predict_proba(X, w, b): return sigmoid(X.dot(w) + b)
def binary_cross_entropy(y, p): eps = 1e-12 p = np.clip(p, eps, 1-eps) return -np.mean(y*np.log(p) + (1-y)*np.log(1-p))
def grad(X, y, w, b): p = predict_proba(X, w, b) N = X.shape[0] dw = X.T.dot(p - y) / N db = np.mean(p - y) return dw, db
def train(X, y, lr=0.1, epochs=1000): D = X.shape[1] w = np.zeros(D) b = 0.0 for epoch in range(epochs): dw, db = grad(X, y, w, b) w -= lr * dw b -= lr * db if epoch % 100 == 0: loss = binary_cross_entropy(y, predict_proba(X,w,b)) print(epoch, loss) return w, b练习:用合成线性可分和不可分数据分别训练并比较训练曲线。
2.23 数值稳定性实践清单
- softmax 用 shifted logits:减去每行最大值;
- log 与除法时加
eps; - 在梯度检验时使用双精度
dtype=np.float64; - 遇到梯度爆炸时启用梯度裁剪
clip_by_norm; - 训练时记录
loss,grad_norm,param_norm,lr等监控项; - 若出现 NaN,先用小数据集复现并检查输入尺度与初始化。
2.24 实战任务(章节级项目)
任务 1:用 Numpy 实现一个小型 MLP(1 层隐藏),在 MNIST 子集上训练并观察学习曲线与梯度范数。要求实现:前向、反向、SGD、数值梯度检验、训练日志。
任务 2:实现 PCA 压缩与重建,用 SVD 对 CIFAR-10 的小批量图像做低秩近似,比较不同奇异值数量下的重建误差和视觉质量。
任务 3:实现逻辑回归的 L2 正则版本并与无正则比较泛化性能。
这些练习会为后续从零实现神经网络提供大量调试与工程经验。
2.25 扩展练习(逐步评分)
- 实现
numerical_grad并用其验证你写的 MLP 反向传播(选取少量参数)。 - 在逻辑回归训练中加入
momentum优化器并比较收敛速度。 - 实现 mini-batch SGD,并实验不同 batch_size 对训练曲线的影响。
- 实现一个简单的 learning rate finder:在短训练中指数增加学习率并记录 loss,以找最佳 lr 区间。
- 编写脚本把训练过程的关键指标保存为 CSV,以便用 Matplotlib 可视化。
2.26 参考资料
- Strang, Gilbert. “Linear Algebra and Its Applications.”(线性代数教材)
- Bishop, Christopher M. “Pattern Recognition and Machine Learning.”(概率与机器学习)
- Goodfellow, Bengio, Courville. “Deep Learning.”(深度学习基础)
- Numerical Recipes(数值计算技巧)
2.12 延伸阅读
- 《线性代数及其应用》
- 《高等数学》中的多元微积分章节
- 《概率论与数理统计》中的条件概率、随机变量与最大似然
- Numpy 官方文档中的 broadcasting 说明
如果這篇文章對你有幫助,歡迎分享給更多人!
部分資訊可能已經過時





















