AI/ML 数学完全指南
要真正理解机器学习和深度学习,就必须掌握其背后的数学。很多开发者在使用框架时,其实并不清楚"这个公式为什么会这样起作用"。这篇文章正是为了填补这个空白而写的。
它并不只是罗列公式,而是重点讲解每个概念为什么重要、又在深度学习的哪个环节如何被使用。文中配有可运行的 Python/NumPy 代码,方便你亲自验证这些公式。
1. 线性代数(Linear Algebra)
线性代数是深度学习最基础的语言。神经网络的前向传播(Forward Pass)本质上是一连串矩阵乘法,而嵌入(embedding)则是高维向量空间中的一个点。
1.1 向量(Vector)
向量的定义与几何意义
向量是同时具有大小(magnitude)与方向(direction)的量。数学上它是一列有序的数,几何上则可以看作指向 维空间中某一点的箭头。
在深度学习中,向量无处不在——输入数据、隐藏层的激活值、嵌入表示,全部都是向量。
向量加法与标量乘法
两个向量相加是按分量(element-wise)进行的。
标量 与向量相乘,是把每个分量都乘以 。
内积(Dot Product)
内积是衡量两个向量"相似度"的运算。
从几何上看,内积也可以表示为两个向量的模长与它们夹角 的余弦之积。
内积为正时,两个向量大致指向同一方向;为负时指向相反方向;为零时两者正交(垂直)。
余弦相似度(Cosine Similarity)
如果只想衡量两个向量的方向相似性(与大小无关),可以用它们各自的模长做归一化。
其取值范围是 ,1 表示方向完全相同,-1 表示方向完全相反。自然语言处理中衡量词嵌入相似度时经常用到它。
向量范数(Vector Norm)
范数是衡量向量"大小(长度)"的函数。
- 范数(曼哈顿距离):
- 范数(欧几里得距离):
- 范数(最大值范数):
在正则化(Regularization)中, 会诱导稀疏性(sparsity), 则会让权重整体上更小。
import numpy as np
a = np.array([3.0, 4.0])
b = np.array([1.0, 2.0])
# 内积
dot_product = np.dot(a, b) # 3*1 + 4*2 = 11
print(f"内积: {dot_product}")
# 范数
l2_norm_a = np.linalg.norm(a) # sqrt(9+16) = 5
print(f"L2 范数: {l2_norm_a}")
# 余弦相似度
cosine_sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(f"余弦相似度: {cosine_sim:.4f}")
# 各种范数
v = np.array([3.0, -4.0, 1.0])
print(f"L1 范数: {np.linalg.norm(v, ord=1)}") # 8.0
print(f"L2 范数: {np.linalg.norm(v, ord=2)}") # 5.099...
print(f"Linf 范数: {np.linalg.norm(v, ord=np.inf)}") # 4.0
1.2 矩阵(Matrix)
矩阵表示法
矩阵是把数排列成矩形的结构。 矩阵有 行(row)和 列(column)。
在深度学习中,权重矩阵 表示层与层之间的线性变换。
矩阵乘法(Matrix Multiplication)
当 是 矩阵、 是 矩阵时,乘积 是一个 矩阵:
关键规则是前一个矩阵的列数必须等于后一个矩阵的行数。结果矩阵的 shape 是 。
矩阵乘法不满足交换律:(一般情况下)。
转置矩阵(Transpose)
把行和列互换得到的矩阵。
性质:
逆矩阵(Inverse Matrix)
方阵 的逆矩阵 满足 。逆矩阵存在的前提是行列式不为零。
行列式(Determinant)
矩阵的行列式:
行列式表示该矩阵所代表的线性变换把空间"拉伸或压缩"了多少。 意味着维度被压缩,逆矩阵不存在。
秩(Rank)
矩阵的秩是线性无关的行(或列)的最大数量。秩越低,该矩阵所代表的线性变换的输出空间维度就越低。低秩近似(Low-rank approximation)是 LoRA 等模型压缩技术的核心概念。
import numpy as np
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
B = np.array([[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])
# 矩阵乘法
C = np.dot(A, B)
print("矩阵乘法结果:\n", C)
# 转置矩阵
print("A 的转置矩阵:\n", A.T)
# 行列式
A2 = np.array([[3.0, 1.0],
[2.0, 4.0]])
print(f"行列式: {np.linalg.det(A2):.2f}") # 3*4 - 1*2 = 10
# 逆矩阵
A_inv = np.linalg.inv(A2)
print("逆矩阵:\n", A_inv)
print("A * A_inv (应为单位矩阵):\n", np.round(A2 @ A_inv))
# 秩
print(f"A 的秩: {np.linalg.matrix_rank(A)}") # 2 (存在线性相关的行)
1.3 特征值与特征向量(Eigenvalues & Eigenvectors)
定义
对于方阵 ,满足下列方程的非零向量 称为特征向量(eigenvector),标量 称为特征值(eigenvalue)。
这个式子的含义非常强大:当矩阵 变换向量 时,方向不变,只有大小按 倍缩放。
特征值分解(Eigendecomposition)
如果 是对称矩阵,就可以用相互正交的特征向量将其分解。
其中 是以特征向量为列的正交矩阵, 是以特征值为对角元的对角矩阵。
与 PCA(主成分分析)的关系
数据矩阵 的协方差矩阵 的特征向量就是主成分(Principal Components)。最大特征值所对应的特征向量,就是数据方差最大的方向,也就是最重要的特征方向。
SVD(奇异值分解, Singular Value Decomposition)
特征值分解只适用于方阵,但 SVD 适用于任意矩阵。
- : 正交矩阵(左奇异向量)
- : 对角矩阵(奇异值,均不小于 0)
- : 正交矩阵(右奇异向量)
SVD 是矩阵近似、去噪、推荐系统、自然语言处理中 LSA 等技术的核心。LoRA(Low-Rank Adaptation)也利用了 SVD 的低秩近似思想。
import numpy as np
# 特征值与特征向量
A = np.array([[4.0, 2.0],
[1.0, 3.0]])
eigenvalues, eigenvectors = np.linalg.eig(A)
print("特征值:", eigenvalues)
print("特征向量 (列向量):\n", eigenvectors)
# 验证: A*v = lambda*v
v0 = eigenvectors[:, 0]
lam0 = eigenvalues[0]
print("A*v:", A @ v0)
print("lambda*v:", lam0 * v0)
# SVD
M = np.array([[1, 2, 3],
[4, 5, 6]])
U, S, Vt = np.linalg.svd(M, full_matrices=False)
print(f"U shape: {U.shape}")
print(f"S (奇异值): {S}")
print(f"Vt shape: {Vt.shape}")
# 低秩近似 (rank-1 近似)
rank1_approx = np.outer(S[0] * U[:, 0], Vt[0, :])
print("原始矩阵:\n", M)
print("rank-1 近似:\n", rank1_approx)
# PCA 示例
from numpy.linalg import eig
# 生成数据
np.random.seed(42)
data = np.random.randn(100, 2)
data[:, 1] = data[:, 0] * 0.8 + data[:, 1] * 0.2 # 添加相关性
# 协方差矩阵
cov = np.cov(data.T)
eigenvals, eigenvecs = eig(cov)
# 第一主成分
idx = np.argsort(eigenvals)[::-1]
principal_component = eigenvecs[:, idx[0]]
print("第一主成分:", principal_component)
print("解释方差比例:", eigenvals[idx[0]] / eigenvals.sum())
1.4 深度学习与线性代数
作为线性变换的层
神经网络的全连接层(Fully Connected Layer)本质上是一个线性变换。
其中:
- :输入向量
- :权重矩阵
- :偏置向量
- :输出向量
多个层的堆叠,本质上是连续的线性变换。如果没有激活函数,堆叠再多层也等价于单一的线性变换,因此非线性激活函数(ReLU、Sigmoid 等)是必不可少的。
批处理与矩阵乘法
同时处理 个样本时:
其中 ,。GPU 正是针对这种大规模矩阵乘法的并行计算做了优化。
2. 微积分(Calculus)
微积分负责回答深度学习中"如何学习"这个问题。用来最小化损失函数的梯度下降法,完全依赖于微分。
2.1 微分(Differentiation)
极限与导数的定义
函数 在 处的导数,用极限来定义。
它表示函数在 处的瞬时变化率,也就是该点切线的斜率。
基本求导法则
- 幂法则:
- 和法则:
- 积法则:
- 商法则:
- 链式法则(Chain Rule):
深度学习中常用函数的导数:
- (Sigmoid)
偏导数(Partial Derivative)
对多元函数中的某一个变量求导,其余变量都当作常数处理。
例如, 时:
梯度(Gradient)
把所有偏导数收集在一起构成的向量。
梯度指向函数值增长最快的方向。因此要最小化损失函数,就要沿着梯度的反方向移动(梯度下降法)。
雅可比(Jacobian)矩阵
向量函数 的所有一阶偏导数构成的矩阵。
海森(Hessian)矩阵
标量函数二阶偏导数构成的方阵。
海森矩阵的特征值反映了函数的曲率。全部为正表示极小值,全部为负表示极大值,正负混合则表示鞍点(Saddle Point)。
import numpy as np
# 数值微分 (用于验证梯度)
def numerical_gradient(f, x, h=1e-5):
grad = np.zeros_like(x)
for i in range(len(x)):
x_plus = x.copy()
x_plus[i] += h
x_minus = x.copy()
x_minus[i] -= h
grad[i] = (f(x_plus) - f(x_minus)) / (2 * h)
return grad
# 示例函数: f(x, y) = x^2 + 2y^2
def f(x):
return x[0]**2 + 2 * x[1]**2
x0 = np.array([3.0, 4.0])
grad = numerical_gradient(f, x0)
print(f"数值梯度: {grad}") # [6.0, 16.0]
print(f"解析梯度: [{2*x0[0]}, {4*x0[1]}]")
# 使用 PyTorch 的自动微分
try:
import torch
x = torch.tensor([3.0, 4.0], requires_grad=True)
y = x[0]**2 + 2 * x[1]**2
y.backward()
print(f"PyTorch 梯度: {x.grad}")
except ImportError:
print("未安装 PyTorch")
2.2 链式法则与反向传播(Backpropagation)
链式法则(Chain Rule)
用来计算复合函数导数的法则。
推广到多元变量:
反向传播算法
在神经网络训练中,需要把损失函数 对每一个权重 求导。由于网络是多层复合函数,所以要反复应用链式法则。
以一个 2 层神经网络为例:
要求 ,需要:
反向传播就是从输出方向朝输入方向,高效地计算这条链。
import numpy as np
# 简单神经网络的反向传播示例
class SimpleNet:
def __init__(self):
self.W1 = np.random.randn(4, 3) * 0.1
self.b1 = np.zeros(4)
self.W2 = np.random.randn(2, 4) * 0.1
self.b2 = np.zeros(2)
def relu(self, x):
return np.maximum(0, x)
def relu_grad(self, x):
return (x > 0).astype(float)
def forward(self, x):
self.x = x
self.z1 = self.W1 @ x + self.b1
self.h = self.relu(self.z1)
self.z2 = self.W2 @ self.h + self.b2
return self.z2
def backward(self, dL_dz2):
# 第 2 层梯度
dL_dW2 = np.outer(dL_dz2, self.h)
dL_db2 = dL_dz2
dL_dh = self.W2.T @ dL_dz2
# ReLU 梯度
dL_dz1 = dL_dh * self.relu_grad(self.z1)
# 第 1 层梯度
dL_dW1 = np.outer(dL_dz1, self.x)
dL_db1 = dL_dz1
return dL_dW1, dL_db1, dL_dW2, dL_db2
net = SimpleNet()
x = np.array([1.0, 2.0, 3.0])
output = net.forward(x)
dL_dout = np.array([1.0, -1.0]) # 损失的梯度
grads = net.backward(dL_dout)
print(f"W1 梯度 shape: {grads[0].shape}")
print(f"W2 梯度 shape: {grads[2].shape}")
2.3 优化理论
极值条件
- 一阶条件(必要条件):在极值点处
- 二阶条件(充分条件):由海森矩阵 的符号判断极小/极大
凸函数(Convex Function)
如果函数 是凸的,那么函数值总是小于等于两点连线的值。
凸函数的极小值必然是全局最小值。深度学习的损失函数一般都不是凸的,因此无法保证全局最小值。
梯度下降法(Gradient Descent)
其中 是学习率(learning rate)。学习率过大会发散,过小则收敛缓慢。
常见变体:
- 随机梯度下降法(SGD):每一步使用一个随机样本(或一个小批量)
- 动量(Momentum):累积此前的梯度方向以加速收敛
- Adam:自适应学习率,目前深度学习中使用最广泛的方法
import numpy as np
import matplotlib.pyplot as plt
# 梯度下降法实现
def gradient_descent(grad_f, init_x, learning_rate=0.1, steps=100):
x = init_x.copy()
history = [x.copy()]
for _ in range(steps):
grad = grad_f(x)
x -= learning_rate * grad
history.append(x.copy())
return x, np.array(history)
# 示例: f(x, y) = x^2 + 4y^2 求最小值
def f(x):
return x[0]**2 + 4 * x[1]**2
def grad_f(x):
return np.array([2*x[0], 8*x[1]])
init_x = np.array([3.0, 3.0])
final_x, history = gradient_descent(grad_f, init_x, learning_rate=0.1, steps=50)
print(f"起始点: {init_x}")
print(f"收敛点: {final_x}")
print(f"最小值: {f(final_x):.6f}")
# Adam 优化器实现
def adam(grad_f, init_x, alpha=0.01, beta1=0.9, beta2=0.999, eps=1e-8, steps=100):
x = init_x.copy()
m = np.zeros_like(x)
v = np.zeros_like(x)
for t in range(1, steps + 1):
g = grad_f(x)
m = beta1 * m + (1 - beta1) * g
v = beta2 * v + (1 - beta2) * g**2
m_hat = m / (1 - beta1**t)
v_hat = v / (1 - beta2**t)
x -= alpha * m_hat / (np.sqrt(v_hat) + eps)
return x
final_adam = adam(grad_f, init_x)
print(f"Adam 收敛点: {final_adam}")
3. 概率与统计(Probability & Statistics)
概率与统计是处理深度学习中不确定性的语言。损失函数的设计、正则化、模型评估,全都建立在概率思维之上。
3.1 概率基础
概率公理(Kolmogorov Axioms)
- (非负性)
- (全概率为 1)
- 对于互斥事件, (可加性)
条件概率
在事件 已经发生的条件下,事件 发生的概率:
贝叶斯定理(Bayes' Theorem)
贝叶斯定理描述的是"基于证据更新信念"的原理。
- :先验概率(Prior)——见到证据之前的信念
- :似然(Likelihood)——在假设 A 成立的前提下,证据 B 出现的概率
- :后验概率(Posterior)——看到证据之后被更新的信念
它被广泛用于分类模型评估、朴素贝叶斯分类器、贝叶斯神经网络等场景。
全概率公式
3.2 概率分布
离散概率分布
伯努利分布(Bernoulli Distribution)
结果只有 0 或 1 的单次试验:
,
二项分布(Binomial Distribution)
次伯努利试验中成功的次数:
泊松分布(Poisson Distribution)
单位时间/空间内事件发生的次数:
连续概率分布
均匀分布(Uniform Distribution)
在区间 上,所有值的概率密度都相同:
正态分布(Normal/Gaussian Distribution)
用均值 和标准差 来刻画。根据中心极限定理(Central Limit Theorem),许多自然现象都近似服从正态分布。深度学习中的权重初始化、噪声建模等都经常用到它。
多元正态分布(Multivariate Normal Distribution)
其中 是均值向量, 是协方差矩阵。它是 VAE(Variational Autoencoder)对潜在空间建模的核心工具。
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
# 正态分布
mu, sigma = 0, 1
x = np.linspace(-4, 4, 100)
pdf = stats.norm.pdf(x, mu, sigma)
print(f"P(-1 < X < 1) = {stats.norm.cdf(1) - stats.norm.cdf(-1):.4f}") # 68.27%
print(f"P(-2 < X < 2) = {stats.norm.cdf(2) - stats.norm.cdf(-2):.4f}") # 95.45%
print(f"P(-3 < X < 3) = {stats.norm.cdf(3) - stats.norm.cdf(-3):.4f}") # 99.73%
# 多元正态分布采样
mean = np.array([0, 0])
cov = np.array([[1, 0.7],
[0.7, 1]])
samples = np.random.multivariate_normal(mean, cov, size=1000)
print(f"样本形状: {samples.shape}")
print(f"样本均值: {samples.mean(axis=0)}")
print(f"样本协方差:\n{np.cov(samples.T)}")
# 二项分布
n, p = 10, 0.5
k = np.arange(0, n+1)
pmf = stats.binom.pmf(k, n, p)
print(f"\n二项分布 B(10, 0.5):")
print(f"P(X=5) = {stats.binom.pmf(5, n, p):.4f}")
3.3 期望值与方差
期望值(Expected Value)
期望值的线性性质:
方差(Variance)
标准差:
协方差(Covariance)
衡量两个随机变量之间的线性关系。
相关系数(Correlation)
其取值范围是 ,只衡量线性关系的强度,与量纲无关。
协方差矩阵(Covariance Matrix)
维随机向量中所有两两组合的协方差:
它是 PCA 的核心输入,承载着数据的方差结构。
3.4 最大似然估计(Maximum Likelihood Estimation, MLE)
似然函数(Likelihood Function)
给定参数 ,观测到数据 的概率:
MLE 要找的是使这个似然最大化的 。
对数似然(Log-Likelihood)
把乘法转换成加法,让计算更简单。
由于对数是单调递增函数,使对数似然最大化的 与使似然最大化的 是同一个。
MLE 推导示例:正态分布
假设数据 服从 :
对 求导并令其为 0: (样本均值)
对 求导: (样本方差)
深度学习中的 Cross-Entropy 与 MLE
在分类问题中,最小化 Cross-Entropy 损失等价于 MLE。
这等价于在真实数据分布下最大化模型的对数似然。
import numpy as np
from scipy.optimize import minimize_scalar
# MLE 示例: 伯努利分布
data = np.array([1, 0, 1, 1, 0, 1, 1, 1, 0, 1]) # 抛硬币
n = len(data)
k = data.sum()
# 解析 MLE: p_hat = k/n
p_mle = k / n
print(f"MLE 估计值: p = {p_mle:.2f}") # 0.7
# 对数似然函数
def neg_log_likelihood(p):
if p <= 0 or p >= 1:
return np.inf
return -(k * np.log(p) + (n - k) * np.log(1 - p))
result = minimize_scalar(neg_log_likelihood, bounds=(0.01, 0.99), method='bounded')
print(f"数值优化 MLE: p = {result.x:.4f}")
# Cross-Entropy 损失实现
def cross_entropy(y_true, y_pred, eps=1e-15):
y_pred = np.clip(y_pred, eps, 1 - eps)
return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))
# 二分类示例
y_true = np.array([1, 0, 1, 1, 0])
y_pred = np.array([0.9, 0.1, 0.8, 0.7, 0.2])
loss = cross_entropy(y_true, y_pred)
print(f"\nCross-Entropy 损失: {loss:.4f}")
3.5 信息论(Information Theory)
熵(Entropy)
概率分布 的不确定性或信息量:
在均匀分布下熵最大,只有一种结果可能时熵为 0。
KL 散度(KL Divergence)
两个分布 与 之间的"距离"(注意,非对称):
,且仅当 时为 0。用于 VAE 的损失函数、策略优化(PPO 等)。
交叉熵(Cross-Entropy)
真实分布 与模型分布 之间的交叉熵:
由于 是常数,最小化 Cross-Entropy 等价于最小化 KL 散度。
互信息(Mutual Information)
两个随机变量共享的信息量:
它是特征选择、表示学习的理论基础。
import numpy as np
def entropy(p):
"""计算离散分布的熵"""
p = np.array(p)
p = p[p > 0] # 去掉 0 (0*log(0) 按 0 处理)
return -np.sum(p * np.log2(p))
def kl_divergence(p, q, eps=1e-15):
"""计算 KL 散度 D_KL(P||Q)"""
p = np.array(p) + eps
q = np.array(q) + eps
p = p / p.sum()
q = q / q.sum()
return np.sum(p * np.log(p / q))
def cross_entropy_distributions(p, q, eps=1e-15):
"""计算分布间的 Cross-Entropy"""
p = np.array(p)
q = np.array(q) + eps
return -np.sum(p * np.log(q))
# 均匀分布 (最大熵)
uniform = [0.25, 0.25, 0.25, 0.25]
print(f"均匀分布的熵: {entropy(uniform):.4f} bits") # 2.0 bits
# 集中分布 (低熵)
concentrated = [0.97, 0.01, 0.01, 0.01]
print(f"集中分布的熵: {entropy(concentrated):.4f} bits")
# KL 散度
true_dist = [0.4, 0.3, 0.2, 0.1]
model_dist = [0.35, 0.35, 0.15, 0.15]
kl = kl_divergence(true_dist, model_dist)
print(f"\nKL 散度: {kl:.4f}")
# Cross-Entropy = H(P) + KL(P||Q)
ce = cross_entropy_distributions(true_dist, model_dist)
h_p = entropy(true_dist) * np.log(2) # 转换为 nats
print(f"Cross-Entropy: {ce:.4f}")
print(f"H(P) + KL: {h_p + kl:.4f}")
4. 数值方法(Numerical Methods)
在深度学习的实现中,理解数学理论与实际计算机运算之间的差距非常重要。
4.1 浮点数表示
计算机中的实数用浮点数表示。
FP32 (单精度)
- 32 位:符号位 1 位、指数位 8 位、尾数位 23 位
- 精度:约 7 位十进制有效数字
- 范围:约
FP16 (半精度)
- 16 位:符号位 1 位、指数位 5 位、尾数位 10 位
- 精度:约 3 位十进制有效数字
- 节省 GPU 内存、提升速度 (Mixed Precision Training)
- 缺点:存在上溢/下溢的风险
BF16 (Brain Float 16)
- 16 位:符号位 1 位、指数位 8 位、尾数位 7 位
- 与 FP32 相同的指数范围 (上溢风险较低)
- 由 Google TPU 引入,目前在 AI 训练中广泛使用
import numpy as np
# 浮点数精度问题
a = np.float32(0.1)
b = np.float32(0.2)
print(f"0.1 + 0.2 = {a + b}") # 可能不精确等于 0.3
# 数值上溢
x_large = np.float16(65000)
print(f"FP16 大数值: {x_large}")
overflow = np.float16(70000)
print(f"FP16 上溢: {overflow}") # inf
# numpy dtype 比较
for dtype in [np.float16, np.float32, np.float64]:
info = np.finfo(dtype)
print(f"{dtype.__name__}: max={info.max:.3e}, min_pos={info.tiny:.3e}")
4.2 数值稳定性
Softmax 的数值不稳定性及其解决方案
Softmax 函数:
如果输入的值很大, 会导致上溢。
数值稳定的 Softmax 实现:
数学上二者等价,但数值上要稳定得多。
import numpy as np
def naive_softmax(x):
"""不稳定的 Softmax"""
return np.exp(x) / np.sum(np.exp(x))
def stable_softmax(x):
"""数值稳定的 Softmax"""
x_shifted = x - np.max(x) # 减去最大值以保证稳定
return np.exp(x_shifted) / np.sum(np.exp(x_shifted))
# 常规情况
x_normal = np.array([1.0, 2.0, 3.0])
print("常规输入:")
print(f" Naive: {naive_softmax(x_normal)}")
print(f" Stable: {stable_softmax(x_normal)}")
# 大数值情况
x_large = np.array([1000.0, 2000.0, 3000.0])
print("\n大数值输入:")
try:
result = naive_softmax(x_large)
print(f" Naive: {result}")
except RuntimeWarning as e:
print(f" Naive: 出现上溢警告!")
print(f" Stable: {stable_softmax(x_large)}")
# Log-Softmax (与 Cross-Entropy 搭配使用)
def log_softmax(x):
x_shifted = x - np.max(x)
return x_shifted - np.log(np.sum(np.exp(x_shifted)))
logits = np.array([2.0, 1.0, 0.1])
print(f"\nLog-Softmax: {log_softmax(logits)}")
5. 线性回归的数学分析
线性回归是深度学习最基本的构成模块。彻底从数学上理解它,是理解更复杂模型的基础。
5.1 最小二乘法(Ordinary Least Squares)
针对数据 ,训练一个线性模型 。
损失函数(Mean Squared Error):
正规方程(Normal Equation)
以矩阵形式对损失函数求导并令其为 0:
这就是最小二乘解。矩阵 必须是可逆(invertible)的,这在各特征线性无关时成立。
5.2 Ridge 回归与 Lasso 回归
Ridge 回归(L2 正则化)
正规方程:
加上 后, 总是可逆的。权重会被保持在接近于零的水平,从而防止过拟合。
Lasso 回归(L1 正则化)
L1 正则化会诱导出稀疏解(sparse solution),让部分权重精确地变为 0,从而具有自动特征选择(feature selection)的效果。
import numpy as np
from sklearn.linear_model import LinearRegression, Ridge, Lasso
# 生成数据
np.random.seed(42)
n, d = 100, 10
X = np.random.randn(n, d)
true_w = np.array([1.0, -2.0, 3.0, 0.0, 0.0, 0.0, 0.5, -0.5, 0.0, 0.0])
y = X @ true_w + np.random.randn(n) * 0.5
# OLS (正规方程)
X_b = np.column_stack([np.ones(n), X]) # 添加偏置项
w_ols = np.linalg.lstsq(X_b, y, rcond=None)[0]
print("OLS 系数 (不含偏置):", w_ols[1:].round(2))
# Ridge
ridge = Ridge(alpha=1.0)
ridge.fit(X, y)
print("Ridge 系数:", ridge.coef_.round(2))
# Lasso (稀疏解)
lasso = Lasso(alpha=0.1)
lasso.fit(X, y)
print("Lasso 系数:", lasso.coef_.round(2))
print("变为 0 的系数数量:", (np.abs(lasso.coef_) < 0.01).sum())
# 直接实现正规方程
def ridge_normal_equation(X, y, lam=1.0):
n, d = X.shape
A = X.T @ X + lam * np.eye(d)
b = X.T @ y
return np.linalg.solve(A, b)
w_ridge = ridge_normal_equation(X, y, lam=1.0)
print("\n正规方程 Ridge:", w_ridge.round(2))
5.3 梯度的几何意义
等高线与梯度的关系
梯度 总是与等高线垂直(正交)。在梯度下降法中,沿这个方向的反方向移动,可以最快地减小函数值。
正则化的几何解释
Ridge 回归等价于在 这个球形约束内最小化 MSE。由于约束条件是圆形的,所以不会产生稀疏解。
Lasso 则是在 这个菱形约束内最小化 MSE。解经常出现在菱形的顶点上,因此会出现稀疏解。
6. 综合:深度学习数学的整合
6.1 神经网络的数学视角
层的全连接神经网络:
前向传播:线性代数(矩阵乘法) + 激活函数
损失计算:信息论(Cross-Entropy) 或 统计学(MSE)
反向传播:微积分(链式法则) → 计算梯度
参数更新:优化理论(梯度下降法、Adam)
6.2 Attention 机制与矩阵运算
Transformer 的 Attention:
- :查询、键、值矩阵(线性代数)
- 缩放:数值稳定性(数值方法)
- Softmax:转换为概率分布(概率论)
- 内积 :相似度衡量(向量内积)
import numpy as np
def attention(Q, K, V, mask=None):
"""
Scaled Dot-Product Attention
Q, K, V: (seq_len, d_k) 或 (batch, heads, seq_len, d_k)
"""
d_k = Q.shape[-1]
# 缩放后的内积相似度
scores = Q @ K.T / np.sqrt(d_k) # (seq_len, seq_len)
# 掩码 (可选)
if mask is not None:
scores = np.where(mask, scores, -1e9)
# Softmax 转换为概率分布
attention_weights = stable_softmax_2d(scores)
# 加权求和
output = attention_weights @ V
return output, attention_weights
def stable_softmax_2d(x):
x_max = x.max(axis=-1, keepdims=True)
x_shifted = x - x_max
exp_x = np.exp(x_shifted)
return exp_x / exp_x.sum(axis=-1, keepdims=True)
# 示例: 3 个 token, d_k=4
seq_len, d_k = 3, 4
Q = np.random.randn(seq_len, d_k)
K = np.random.randn(seq_len, d_k)
V = np.random.randn(seq_len, d_k)
output, weights = attention(Q, K, V)
print(f"Attention 输出 shape: {output.shape}")
print(f"Attention 权重 (每行之和 = 1):\n{weights.round(3)}")
print(f"每行之和: {weights.sum(axis=-1)}")
结语:接下来的学习方向
这篇指南梳理了 AI/ML 的核心数学基础。总结一下:
- 线性代数:表示与变换数据、模型参数的语言
- 微积分:解释模型"如何学习"的工具
- 概率与统计:处理不确定性,为损失函数提供理论依据
- 数值方法:让理论在真实计算机上稳定实现的知识
推荐接下来的学习步骤:
- Gilbert Strang 的线性代数课程:MIT OCW 免费提供
- Pattern Recognition and Machine Learning (Bishop):从概率论视角讲解 ML
- Deep Learning (Goodfellow et al.):深度学习理论的圣经
- 动手实践:用 NumPy 从零实现一个神经网络
数学是理解的工具。不必背下每一个公式,但如果能理解每个概念为什么存在、又在深度学习的哪个环节如何起作用,就能获得远比死记硬背更强大的实战能力。
参考资料
- Gilbert Strang, Introduction to Linear Algebra, 6th Edition
- Ian Goodfellow et al., Deep Learning, MIT Press (2016)
- Christopher Bishop, Pattern Recognition and Machine Learning, Springer (2006)
- 3Blue1Brown YouTube - Essence of Linear Algebra, Essence of Calculus
- fast.ai - Practical Deep Learning for Coders (数学直观讲解)
현재 단락 (1/595)
要真正理解机器学习和深度学习,就必须掌握其背后的数学。很多开发者在使用框架时,其实并不清楚"这个公式为什么会这样起作用"。这篇文章正是为了填补这个空白而写的。