Skip to content

第一阶段:数学与编程基础 ​

1.1 线性代数 — 神经网络的"语言" ​

如果你只想记住一句话:神经网络的前向传播 = 矩阵乘法链 + 非线性激活函数。

标量、向量、矩阵、张量 ​

概念数学表示PyTorch 表示示例
标量 (Scalar)x∈Rtorch.tensor(3.14)温度 25.3°C
向量 (Vector)x∈Rntorch.randn(100)100 维词向量
矩阵 (Matrix)X∈Rm×ntorch.randn(32, 100)32 个样本的特征
张量 (Tensor)X∈Rb×m×ntorch.randn(16, 32, 100)16 个 batch

核心运算 ​

1. 矩阵乘法 — 神经网络最基本的运算 ​

一个简单的全连接层:

y=Wx+b

其中:

  • x∈Rdin — 输入向量(d_in = 输入维度)
  • W∈Rdout×din — 权重矩阵
  • b∈Rdout — 偏置向量
  • y∈Rdout — 输出向量
python
import torch

# 一个简单的线性层
d_in, d_out = 784, 256
x = torch.randn(1, d_in)        # 输入: (1, 784)  — 例如一张 MNIST 图片
W = torch.randn(d_out, d_in)    # 权重: (256, 784)
b = torch.randn(d_out)           # 偏置: (256,)

# 前向传播:y = Wx + b
y = x @ W.T + b                 # (1, 784) @ (784, 256) + (256,) = (1, 256)
print(f"输入形状: {x.shape} → 输出形状: {y.shape}")

2. 点积 — 注意力机制的基础 ​

两个向量的点积衡量它们的"相似度":

a⋅b=∑i=1naibi=∥a∥∥b∥cos⁡θ

当两个向量同方向时点积最大,正交时为 0,反向时为负。Transformer 的自注意力本质上就是大规摸的点积计算。

3. Softmax — 把任意向量变成概率分布 ​

softmax(xi)=exi∑j=1nexj
python
def softmax(x):
    """将任意实数向量转换为概率分布(所有元素之和为1)"""
    exp_x = torch.exp(x - x.max())  # 减去最大值防止数值溢出
    return exp_x / exp_x.sum(dim=-1, keepdim=True)

logits = torch.tensor([2.0, 1.0, 0.1])
probs = softmax(logits)
print(f"输入: {logits}")
print(f"Softmax 后: {probs} (和={probs.sum():.1f})")
# 输出: tensor([0.6590, 0.2424, 0.0986]) (和=1.0)

Softmax 是 Transformer 的命脉,它把注意力分数转化为"每个位置应该关注多少"的概率分布。


1.2 微积分与优化基础 — 梯度下降为什么有效 ​

深度学习 = 大规模梯度下降。理解微积分,才能真正理解"模型是怎么学会的"。

导数与偏导数 ​

导数描述函数在某一点的变化率:

f′(x)=limh→0f(x+h)−f(x)h

偏导数:对于多元函数 f(x1,x2,...,xn),固定其他变量,对其中一个变量求导:

∂f∂xi=limh→0f(x1,...,xi+h,...,xn)−f(x1,...,xi,...,xn)h

梯度 — 最陡上升方向 ​

梯度是所有偏导数组成的向量,指向函数增长最快的方向:

∇f=[∂f∂x1,∂f∂x2,…,∂f∂xn]T

梯度下降:沿着梯度的反方向走一小步,函数值会下降:

θnew=θold−η⋅∇f(θold)
python
"""手工实现梯度下降:找到 y = x² 的最小值"""
import torch

x = torch.tensor([3.0], requires_grad=True)  # 初始值:x=3
lr = 0.1  # 学习率

for step in range(20):
    y = x ** 2               # 损失函数:y = x²,最小值在 x=0
    y.backward()             # dy/dx = 2x
    with torch.no_grad():
        x -= lr * x.grad     # x = x - lr * 2x
        x.grad.zero_()       # 清零梯度
    print(f"Step {step:2d}: x = {x.item():.6f}, y = {y.item():.6f}")

# 输出:x 从 3.0 逐渐收敛到 0(y 的最小值点)

链式法则 — 反向传播的数学基础 ​

对于复合函数 f(g(x)):

dfdx=dfdg⋅dgdx

对于多层网络 f(g(h(x))):

dfdx=dfdg⋅dgdh⋅dhdx

这就是反向传播的数学本质:误差从输出层逐层传回输入层。

python
"""手工演示反向传播的链式法则"""
x = torch.tensor([2.0], requires_grad=True)

# 复合函数:y = (3x² + 2)³
# 分解:a = x², b = 3a + 2, y = b³
# 链式法则:dy/dx = dy/db · db/da · da/dx
#                  = 3b²   · 3     · 2x

y = (3 * x**2 + 2) ** 3
y.backward()

# 验证
a = x.item() ** 2
b = 3 * a + 2
expected = 3 * b**2 * 3 * 2 * x.item()
print(f"PyTorch 计算: {x.grad.item():.2f}")
print(f"手工链式法则: {expected:.2f}")

Jacobian 与 Hessian — 进阶优化 ​

概念定义作用何时关心
梯度 (Gradient)∇f:一阶偏导向量表明"往哪走最快下降"所有训练
JacobianJ:向量值函数的一阶导数矩阵层间误差传播理解 autograd 原理
HessianH:二阶偏导矩阵曲率信息,判断是鞍点还是最小值理解优化器选择(Adam vs SGD)
python
"""Hessian 的直观示例:为什么 Adam 比 SGD 好"""
# 鞍点问题:SGD 在鞍点处梯度 ≈ 0,会卡住不动
# Adam 利用了历史梯度信息(动量+自适应学习率),能冲过鞍点
# 但对程序员来说,只需记住:默认用 AdamW 就行了

1.3 线性代数进阶 — 理解 Embedding 空间 ​

特征值与特征向量 ​

对于方阵 A,若存在非零向量 v 和标量 λ 满足:

Av=λv

则 λ 是特征值,v 是特征向量。

直觉:特征向量是矩阵作用于其上"只放缩不转向"的方向。

在大模型中的意义 ​

python
"""特征值分解在 NLP 中的直观应用"""
# 词向量矩阵 W ∈ R^(vocab_size × embed_dim)
# PCA(主成分分析)= 对协方差矩阵做特征值分解

# 场景:把 768 维词向量降到 2 维可视化
import torch

# 模拟 1000 个词的 768 维词向量
embeddings = torch.randn(1000, 768)
embeddings = embeddings / embeddings.norm(dim=1, keepdim=True)

# 协方差矩阵
cov = embeddings.T @ embeddings / embeddings.size(0)  # (768, 768)

# 特征值分解
eigenvalues, eigenvectors = torch.linalg.eigh(cov)

# 特征值排序(降序)
sorted_idx = eigenvalues.argsort(descending=True)
top_eigenvectors = eigenvectors[:, sorted_idx[:2]]  # 取前 2 个主成分

# 降维到 2D
embeddings_2d = embeddings @ top_eigenvectors
print(f"词向量: {embeddings.shape} → 2D: {embeddings_2d.shape}")
# 前 2 个特征值的方差解释率
print(f"Top-2 特征值占比: {eigenvalues[sorted_idx[:2]].sum() / eigenvalues.sum():.1%}")

SVD (奇异值分解) — 任意矩阵的分解 ​

A=UΣVT
  • U:左奇异向量(行空间的正交基)
  • Σ:奇异值(降序排列)
  • VT:右奇异向量(列空间的正交基)

在 Attention 中的应用:低秩分解降低计算量(如 Linformer 用 SVD 将 O(n2) 降到 O(nk))。

Embedding 空间的几何直觉 ​

python
# 经典的词向量类比
# king - man + woman ≈ queen
# 说明:词向量的方向编码了语义关系
# 在向量空间中:
#   king_vec + (woman_vec - man_vec) ≈ queen_vec
# 即:国王 + 性别方向 = 女王

# 余弦相似度衡量语义相关性
def cosine_sim(a, b):
    """两个向量的余弦相似度"""
    return (a @ b) / (a.norm() * b.norm())

# 高相似方向 → 词义相近
# 正交方向 → 词义无关
# 相反方向 → 词义对立

1.4 概率论与统计学习基础 ​

为什么深度学习需要概率? ​

现实世界充满不确定性。概率论给深度学习提供了:

  • 损失函数的理论基础(交叉熵为什么有效?)
  • 不确定性量化(模型有多确定?)
  • 生成模型的理论框架(GAN/VAE/Diffusion)

熵 (Entropy) — 信息量的度量 ​

熵衡量一个随机变量的不确定性:

H(P)=−∑iP(xi)log⁡P(xi)
  • 均匀分布:熵最大(最不确定)
  • 确定性分布(某个事件概率为 1):熵 = 0(完全确定)

交叉熵 (Cross-Entropy) — 实际 vs 预测的差异 ​

交叉熵衡量用预测分布 Q 来编码真实分布 P 的"代价":

H(P,Q)=−∑iP(xi)log⁡Q(xi)
python
import torch.nn.functional as F

# 真实标签:类别 2(one-hot: [0, 0, 1, 0, 0])
# 模型预测:logits 转换为概率
logits = torch.tensor([[0.1, 0.2, 3.0, 0.4, 0.1]])  # 第三个最高
labels = torch.tensor([2])  # 真实类别

# 交叉熵损失 = -log(预测概率[真实类别])
loss = F.cross_entropy(logits, labels)
print(f"交叉熵损失: {loss.item():.4f}")
# 损失越小 → 模型对正确类别的置信度越高

核心直觉:训练就是在最小化交叉熵——让模型对正确答案越来越"确定"。

KL 散度 (KL Divergence) ​

DKL(P∥Q)=∑iP(xi)log⁡P(xi)Q(xi)=H(P,Q)−H(P)

KL 散度衡量两个分布之间的"距离"。训练时最小化 KL 散度等价于最小化交叉熵(因为 H(P) 是常数)。

最大似然估计 (MLE) — 训练的本质 ​

深度学习训练的本质就是最大似然估计。给定数据 D={x1,...,xn} 和模型参数 θ,最大化观测到数据的概率:

θMLE=arg⁡maxθP(D|θ)=arg⁡maxθ∏i=1nP(xi|θ)

取对数后等价于最小化负对数似然(Negative Log-Likelihood, NLL):

θMLE=arg⁡minθ−∑i=1nlog⁡P(xi|θ)

关键联系:当模型输出高斯分布时,NLL = MSE;当模型输出分类分布时,NLL = 交叉熵。所以你在 PyTorch 里写的 nn.CrossEntropyLoss() 本质上就是在做最大似然估计。

最大后验估计 (MAP) — 引入先验知识 ​

MAP 在 MLE 基础上加入了参数的先验分布 P(θ):

θMAP=arg⁡maxθP(θ|D)=arg⁡maxθP(D|θ)⋅P(θ)

取对数:

θMAP=arg⁡maxθ[log⁡P(D|θ)+log⁡P(θ)]

关键联系:当 P(θ) 是高斯先验时,log⁡P(θ) 等价于 L2 正则化项(Weight Decay)。所以 AdamW 的 weight_decay 本质上就是贝叶斯先验。

python
# MLE vs MAP 的代码等价性
# MLE(不加正则化):
loss_mle = F.cross_entropy(outputs, targets)

# MAP with L2 prior(等价于 Weight Decay):
loss_map = F.cross_entropy(outputs, targets) + weight_decay * sum(p.pow(2).sum() for p in model.parameters())
# 实际上 AdamW 的 weight_decay 在 optimizer 里自动处理了

偏差-方差权衡 — 理解过拟合与欠拟合 ​

概念定义表现对应
偏差 (Bias)模型预测的期望与真实值之间的差距欠拟合:训练集和测试集表现都差模型太简单
方差 (Variance)模型对不同训练集的敏感程度过拟合:训练集很好,测试集很差模型太复杂
不可约误差数据本身的噪声无论多好的模型都无法避免数据质量问题
期望误差=Bias2+Variance+不可约噪声
mermaid
graph LR
    UNDER["🔵 高偏差 (欠拟合)<br/>- 训练 loss 高<br/>- 验证 loss 也高<br/>- 原因:模型太简单"] --> BALANCED["🟢 平衡点<br/>- 训练 loss 低<br/>- 验证 loss 低<br/>- 原因:模型恰好"]
    BALANCED --> OVER["🔴 高方差 (过拟合)<br/>- 训练 loss 很低<br/>- 验证 loss 很高<br/>- 原因:模型太复杂"]

    style UNDER fill:#3498db,color:#fff
    style BALANCED fill:#2ecc71,color:#fff
    style OVER fill:#e74c3c,color:#fff

如何判断:训练 loss 低但验证 loss 高 → 过拟合 → 加正则化/更多数据/减少参数。训练 loss 和验证 loss 都高 → 欠拟合 → 加大模型/减少正则化/更多 epoch。

泛化误差 — 模型真正的"考试成绩" ​

  • 训练误差:在训练数据上的错误率(平时作业成绩)
  • 泛化误差:在未见过的数据上的错误率(高考成绩)
  • 泛化间隙:两者之差(越大说明过拟合越严重)
python
"""监控泛化间隙的代码框架"""
def check_generalization_gap(model, train_loader, val_loader):
    model.eval()
    with torch.no_grad():
        train_loss = evaluate(model, train_loader)
        val_loss = evaluate(model, val_loader)
    gap = val_loss - train_loss
    if gap > 0.1:  # 间隙过大
        print(f"⚠️  泛化间隙 {gap:.4f} 过大,可能过拟合")
        print(f"   建议:加 Dropout / Weight Decay / 更多数据")
    else:
        print(f"✅ 泛化间隙 {gap:.4f} 正常")

1.5 Python 与 PyTorch 速成 ​

PyTorch 的核心三要素 ​

概念说明关键代码
Tensor多维数组,可在 GPU 上运算torch.tensor([1,2,3])
Autograd自动微分,自动计算梯度x.requires_grad_()
nn.Module神经网络层的基类class MyNet(nn.Module)
python
import torch
import torch.nn as nn

# === 自动微分示例 ===
x = torch.tensor([2.0], requires_grad=True)  # 需要计算梯度
y = x ** 3 + 2 * x ** 2 + 1                   # y = x³ + 2x² + 1
y.backward()                                    # 自动计算 dy/dx
print(f"x=2 时, dy/dx = {x.grad.item()}")      # 理论上 3*4+4*2 = 20

# === 构建一个简单的网络 ===
class TinyNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(10, 5)   # 10 → 5
        self.fc2 = nn.Linear(5, 1)    # 5 → 1

    def forward(self, x):
        x = torch.relu(self.fc1(x))   # 激活函数
        return self.fc2(x)

model = TinyNet()
print(f"模型参数总数: {sum(p.numel() for p in model.parameters())}")
# 输出: 10*5 + 5(偏置) + 5*1 + 1(偏置) = 61

🧭 学习导航 ​

← 上一阶段:math-foundations | 返回总览 | 下一阶段:classic-neural-networks →

批注模式

💬 文章评论

暂无评论,来说点什么吧 👇

编程学习笔记