跳转至

00 - 深度学习数学基础

重要性: ⭐⭐⭐⭐⭐ 实用度: ⭐⭐⭐⭐⭐ 学习时间: 15-20小时 必须掌握: 是


为什么需要学习数学?

深度学习不是魔法,而是建立在严谨的数学基础之上的工程技术。掌握数学能让你:

  • 真正理解算法为什么有效,而不是死记硬背
  • 调试问题时知道从哪里入手
  • 设计新模型时有理论指导
  • 阅读论文时能理解推导过程
  • 与他人交流时使用准确的语言

好消息:你不需要成为数学家,只需要掌握深度学习常用的数学工具。


学习路线图

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    深度学习数学基础学习路线图                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  第一阶段:线性代数(核心中的核心)                                     │
│  ├── 向量与向量空间        [2小时]                                    │
│  ├── 矩阵与矩阵运算        [2小时]                                    │
│  ├── 特征分解与SVD         [2小时]                                    │
│  └── 在深度学习中的应用     [1小时]                                    │
│                                                                     │
│  第二阶段:微积分(优化的基础)                                         │
│  ├── 导数与梯度            [2小时]                                    │
│  ├── 偏导数与方向导数       [2小时]                                    │
│  ├── 链式法则              [1小时]                                    │
│  └── 泰勒展开              [1小时]                                    │
│                                                                     │
│  第三阶段:概率论(不确定性的语言)                                      │
│  ├── 概率基础              [2小时]                                    │
│  ├── 常见分布              [1小时]                                    │
│  ├── 期望与方差            [1小时]                                    │
│  └── 信息论                [2小时]                                    │
│                                                                     │
│  第四阶段:优化理论(训练的本质)                                        │
│  ├── 凸优化基础            [1小时]                                    │
│  ├── 梯度下降理论          [2小时]                                    │
│  └── 约束优化              [1小时]                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

第一部分:线性代数

1. 向量与向量空间

1.1 什么是向量?

直观理解:向量是有方向的量,可以表示为空间中从一个点指向另一个点的箭头。

数学定义:向量是向量空间中的元素,满足加法和数乘的封闭性。

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    向量的表示                                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  几何表示:           代数表示:           物理意义:                   │
│                                                                     │
│       ↑y                                                            │
│       │    •(3,2)     v = [3]          位移、速度、力                 │
│       │   /          [2]                                            │
│       │  /           或 v = (3, 2)                                  │
│       │ /                                                             │
│       └────────→ x                                                  │
│                                                                     │
│  向量的维度:                                                         │
│  • 2维向量:平面上的点 [x, y]                                        │
│  • 3维向量:空间中的点 [x, y, z]                                     │
│  • n维向量:n维空间中的点 [x₁, x₂, ..., xₙ]                          │
│                                                                     │
│  在深度学习中:                                                       │
│  • 一张28×28的灰度图像 = 784维向量                                   │
│  • 一个词嵌入 = 通常128或256维向量                                    │
│  • 一个batch的64张图像 = 64×784矩阵                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.2 向量运算

向量点积的几何意义

Python
import numpy as np

# 向量定义
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])

# 1. 向量加法(对应元素相加)
# 几何意义:平行四边形法则
v_add = v1 + v2  # [5, 7, 9]

# 2. 数乘(每个元素乘以标量)
# 几何意义:长度的缩放
v_scale = 2 * v1  # [2, 4, 6]

# 3. 点积(内积)- 结果是一个标量
# 公式:v₁·v₂ = Σ(v₁[i] × v₂[i])
# 几何意义:v₁在v₂方向上的投影长度 × |v₂|
dot_product = np.dot(v1, v2)  # 1×4 + 2×5 + 3×6 = 32

# 4. 范数(长度)
# L2范数(欧几里得范数):||v|| = √(Σv[i]²)
norm = np.linalg.norm(v1)  # √(1+4+9) = √14 ≈ 3.74

# 5. 向量夹角
# cos(θ) = (v₁·v₂) / (||v₁|| × ||v₂||)
cos_theta = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))

print(f"v1 + v2 = {v_add}")
print(f"2 * v1 = {v_scale}")
print(f"v1 · v2 = {dot_product}")
print(f"||v1|| = {norm:.2f}")
print(f"cos(θ) = {cos_theta:.4f}")

1.3 向量空间与基

直观理解:向量空间是一个集合,其中的元素(向量)可以进行加法和数乘运算。

基(Basis):向量空间中的一组特殊向量,空间中的任何向量都可以表示为这组基的线性组合。

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    基与坐标                                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  标准基:                                                            │
│  在2维空间中:e₁ = [1, 0], e₂ = [0, 1]                               │
│  任何向量 v = [3, 2] = 3×e₁ + 2×e₂                                  │
│                                                                     │
│  非标准基:                                                          │
│  b₁ = [1, 1], b₂ = [1, -1]                                          │
│  同样 v = [3, 2] 可以表示为:                                        │
│  v = 2.5×b₁ + 0.5×b₂                                                │
│                                                                     │
│  在深度学习中的应用:                                                 │
│  • 主成分分析(PCA):找到数据最重要的基(主成分)                     │
│  • 嵌入空间:词嵌入就是学习到的语义基                                 │
│  • 特征提取:CNN学习的是图像的特征基                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2. 矩阵与矩阵运算

2.1 什么是矩阵?

直观理解:矩阵是向量的集合,可以看作是一个二维表格或线性变换。

数学定义:m×n矩阵是由m行n列数排列成的矩形阵列。

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    矩阵的直观理解                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  矩阵作为数据表格:                                                   │
│  ┌─────────────────────────────────────┐                           │
│  │  身高  体重  年龄  |  样本1          │                           │
│  │  170   65    25   |  样本2          │                           │
│  │  160   55    30   |  样本3          │                           │
│  └─────────────────────────────────────┘                           │
│                                                                     │
│  矩阵作为线性变换:                                                   │
│                                                                     │
│  输入向量 x ──────→ 矩阵 A ──────→ 输出向量 y = Ax                  │
│                                                                     │
│  几何意义:                                                           │
│  • 旋转:A = [[cosθ, -sinθ], [sinθ, cosθ]]                          │
│  • 缩放:A = [[2, 0], [0, 3]]  (x方向2倍,y方向3倍)                  │
│  • 投影:A = [[1, 0], [0, 0]]  (投影到x轴)                           │
│                                                                     │
│  在深度学习中:                                                       │
│  • 权重矩阵:W 将输入特征映射到输出特征                               │
│  • 批量数据:X 是batch_size × feature_dim 的矩阵                     │
│  • 图像数据:28×28图像是784维向量,batch是矩阵                        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

2.2 矩阵运算

矩阵乘法可视化

Python
import numpy as np

# 矩阵定义
A = np.array([[1, 2], [3, 4], [5, 6]])  # 3×2矩阵
B = np.array([[7, 8], [9, 10]])          # 2×2矩阵

print(f"A的形状: {A.shape}")  # (3, 2)
print(f"B的形状: {B.shape}")  # (2, 2)

# 1. 矩阵加法(对应元素相加,形状必须相同)
C = np.array([[1, 2], [3, 4]])
D = np.array([[5, 6], [7, 8]])
print(f"C + D = \n{C + D}")

# 2. 数乘
print(f"2 * A = \n{2 * A}")

# 3. 矩阵乘法(最重要的运算!)
# 规则:A(m×n) @ B(n×p) = C(m×p)
# A的列数必须等于B的行数
E = A @ B  # 3×2 @ 2×2 = 3×2
print(f"A @ B = \n{E}")

# 矩阵乘法的元素计算:
# C[i,j] = Σ(A[i,k] × B[k,j])
# 即:A的第i行与B的第j列的点积

# 4. 转置(行列互换)
print(f"A的转置: \n{A.T}")  # 2×3

# 5. 单位矩阵(对角线为1,其余为0)
I = np.eye(3)
print(f"3×3单位矩阵: \n{I}")

# 性质:A @ I = I @ A = A

# 6. 逆矩阵(只对方阵存在,且行列式不为0)
F = np.array([[4, 7], [2, 6]])
F_inv = np.linalg.inv(F)
print(f"F的逆矩阵: \n{F_inv}")
print(f"F @ F_inv = \n{F @ F_inv}")  # 接近单位矩阵

2.3 矩阵在深度学习中的应用

Python
import numpy as np

# 场景1:全连接层的前向传播
# y = x @ W + b

batch_size = 64
input_dim = 784
output_dim = 256

# 随机初始化
X = np.random.randn(batch_size, input_dim)  # 输入:64张784维的图像
W = np.random.randn(input_dim, output_dim) * 0.01  # 权重
b = np.zeros(output_dim)  # 偏置

# 前向传播
Y = X @ W + b  # 输出:64×256
print(f"输入形状: {X.shape}")
print(f"权重形状: {W.shape}")
print(f"输出形状: {Y.shape}")

# 场景2:批量处理多个样本
# 矩阵乘法天然支持批量运算

# 场景3:注意力机制中的矩阵运算
# Attention(Q, K, V) = softmax(Q @ K.T / √d) @ V

seq_len = 10
d_k = 64

Q = np.random.randn(seq_len, d_k)
K = np.random.randn(seq_len, d_k)
V = np.random.randn(seq_len, d_k)

# 计算注意力分数
scores = Q @ K.T / np.sqrt(d_k)  # (10, 10)
print(f"\n注意力分数形状: {scores.shape}")

# softmax(简化版)
def softmax(x):
    exp_x = np.exp(x - np.max(x, axis=-1, keepdims=True))
    return exp_x / np.sum(exp_x, axis=-1, keepdims=True)

attention_weights = softmax(scores)
output = attention_weights @ V
print(f"注意力输出形状: {output.shape}")

3. 特征分解与奇异值分解

特征向量的几何意义

3.1 特征值与特征向量

核心问题:矩阵A作用在向量v上,什么时候v只是被拉伸,而不改变方向?

答案:当v是A的特征向量时!

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    特征值与特征向量                                    │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  定义:如果 Av = λv,则:                                             │
│  • v 是A的特征向量(非零)                                            │
│  • λ 是对应的特征值(标量)                                            │
│                                                                     │
│  几何意义:                                                           │
│                                                                     │
│     变换前        矩阵A        变换后                                  │
│       ↘                      ↗                                      │
│        v ─────────────────→ λv                                      │
│       ↗                      ↘                                      │
│     方向不变,只是长度变为λ倍                                          │
│                                                                     │
│  计算方法:                                                           │
│  Av = λv  ⟹  Av - λv = 0  ⟹  (A - λI)v = 0                          │
│  要有非零解,需要 det(A - λI) = 0(特征方程)                          │
│                                                                     │
│  在深度学习中的应用:                                                  │
│  • PCA降维:用最大的k个特征值对应的特征向量作为新基                    │
│  • 谱归一化:用特征值控制Lipschitz常数                                 │
│  • PageRank:特征向量表示网页重要性                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
Python
import numpy as np

# 定义矩阵
A = np.array([[4, 2], [1, 3]])

# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)

print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)

# 验证:Av = λv
for i in range(len(eigenvalues)):
    v = eigenvectors[:, i]
    lambda_v = eigenvalues[i]

    Av = A @ v
    lambda_v_v = lambda_v * v

    print(f"\n特征向量 {i+1}: {v}")
    print(f"Av = {Av}")
    print(f"λv = {lambda_v_v}")
    print(f"是否相等: {np.allclose(Av, lambda_v_v)}")

# 特征分解:A = V @ diag(λ) @ V^(-1)
V = eigenvectors
Lambda = np.diag(eigenvalues)
V_inv = np.linalg.inv(V)

A_reconstructed = V @ Lambda @ V_inv
print(f"\n重构的A:\n{A_reconstructed}")
print(f"与原A相等: {np.allclose(A, A_reconstructed)}")

3.2 奇异值分解(SVD)

SVD分解可视化

重要性:SVD是线性代数中最强大的工具之一,任何矩阵都可以做SVD!

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    奇异值分解(SVD)                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  定理:任何m×n矩阵A都可以分解为:                                       │
│                                                                     │
│  A = U @ Σ @ V^T                                                    │
│                                                                     │
│  其中:                                                              │
│  • U:m×m正交矩阵(左奇异向量)                                        │
│  • Σ:m×n对角矩阵(奇异值,非负,从大到小排列)                         │
│  • V^T:n×n正交矩阵的转置(右奇异向量)                                 │
│                                                                     │
│  几何意义:                                                           │
│                                                                     │
│  输入x ──→ V^T ──→ Σ ──→ U ──→ 输出Ax                               │
│        旋转   缩放   旋转                                             │
│                                                                     │
│  任何线性变换都可以分解为:旋转→缩放→旋转                               │
│                                                                     │
│  在深度学习中的应用:                                                  │
│  • 降维:取前k个奇异值,实现最优低秩近似                                │
│  • 压缩:存储U_k, Σ_k, V_k代替原矩阵                                   │
│  • 去噪:小奇异值通常对应噪声                                          │
│  • 推荐系统:矩阵补全                                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
Python
import numpy as np

# 创建矩阵
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])  # 4×3
print(f"原矩阵形状: {A.shape}")

# SVD分解
U, s, Vt = np.linalg.svd(A, full_matrices=False)

print(f"U形状: {U.shape}")      # (4, 3)
print(f"奇异值: {s}")           # (3,)
print(f"Vt形状: {Vt.shape}")    # (3, 3)

# 重构Sigma矩阵
Sigma = np.diag(s)

# 重构原矩阵
A_reconstructed = U @ Sigma @ Vt
print(f"\n重构误差: {np.linalg.norm(A - A_reconstructed):.10f}")

# 应用:降维(取前2个奇异值)
k = 2
U_k = U[:, :k]
Sigma_k = np.diag(s[:k])
Vt_k = Vt[:k, :]

A_approx = U_k @ Sigma_k @ Vt_k
print(f"\n{k}个奇异值近似,误差: {np.linalg.norm(A - A_approx):.4f}")

# 压缩率计算
original_size = A.size
compressed_size = U_k.size + s[:k].size + Vt_k.size
print(f"原矩阵大小: {original_size}")
print(f"压缩后大小: {compressed_size}")
print(f"压缩率: {compressed_size/original_size:.2%}")

第二部分:微积分

梯度的几何意义

4. 导数与梯度

4.1 导数的本质

直观理解:导数是变化率,描述函数在某一点的"陡峭程度"。

数学定义:f'(x) = lim(h→0) [f(x+h) - f(x)] / h

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    导数的几何意义                                      │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│       y                                                             │
│       │    ╱                                                        │
│       │   ╱  f(x) = x²                                              │
│       │  ╱                                                          │
│       │ ╱    在x=1处,切线斜率=2                                     │
│       │╱──────┐                                                     │
│       │    ╱  │ 切线                                                │
│       │   ╱   │                                                     │
│       └──┼────┼────────────────→ x                                  │
│          0    1                                                     │
│                                                                     │
│  导数告诉我们:                                                       │
│  • 函数在某点的瞬时变化率                                             │
│  • 函数图像在该点的切线斜率                                           │
│  • 函数在该点的局部线性近似                                           │
│                                                                     │
│  在深度学习中:                                                       │
│  • 损失函数对参数的导数 = 梯度                                        │
│  • 梯度告诉我们如何调整参数以减少损失                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

4.2 常见函数的导数

Python
import numpy as np
import matplotlib.pyplot as plt

# 常见函数及其导数
def f_and_df():
    """
    函数          导数
    ─────────────────────────
    c (常数)      0
    x             1
    x²            2x
    xⁿ            n·x^(n-1)
    e^x           e^x
    ln(x)         1/x
    sin(x)        cos(x)
    cos(x)        -sin(x)
    sigmoid(x)    sigmoid(x)·(1-sigmoid(x))
    """
    pass

# 数值导数(用于验证)
def numerical_derivative(f, x, h=1e-5):
    """
    计算函数f在点x处的数值导数

    参数:
        f: 函数
        x: 标量或数组,求导点
        h: 步长

    返回:
        数值导数
    """
    if np.isscalar(x):
        return (f(x + h) - f(x - h)) / (2 * h)
    else:
        # 处理数组输入
        x = np.asarray(x)
        grad = np.zeros_like(x)
        for i in range(x.size):
            x_plus = x.copy()
            x_minus = x.copy()
            x_plus.flat[i] += h
            x_minus.flat[i] -= h
            grad.flat[i] = (f(x_plus) - f(x_minus)) / (2 * h)
        return grad

# 测试:f(x) = x² 的导数
def f(x):
    return x**2

def df_analytical(x):
    return 2*x

x = 3.0
df_numerical = numerical_derivative(f, x)
df_exact = df_analytical(x)

print(f"f(x) = x² 在 x={x} 处:")
print(f"数值导数: {df_numerical}")
print(f"解析导数: {df_exact}")
print(f"误差: {abs(df_numerical - df_exact):.10f}")

# 可视化函数和导数
x = np.linspace(-3, 3, 100)
y = x**2
dy = 2*x

plt.figure(figsize=(10, 4))

plt.subplot(1, 2, 1)
plt.plot(x, y, 'b-', label='f(x) = x²')
plt.plot(x, dy, 'r--', label="f'(x) = 2x")
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title('Function and Derivative')

plt.subplot(1, 2, 2)
# 绘制某点的切线
x0 = 1.5
y0 = x0**2
slope = 2*x0
x_tangent = np.linspace(x0-1, x0+1, 10)
y_tangent = slope * (x_tangent - x0) + y0

plt.plot(x, y, 'b-', label='f(x) = x²')
plt.plot(x_tangent, y_tangent, 'r-', label=f'Tangent at x={x0}')
plt.plot(x0, y0, 'ro', markersize=8)
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True, alpha=0.3)
plt.title('Tangent Line')

plt.tight_layout()
plt.savefig('derivative_visualization.png', dpi=150)
plt.show()

4.3 梯度(多元函数的导数)

梯度几何意义详细可视化

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    梯度:多元函数的变化率                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  定义:对于函数 f(x₁, x₂, ..., xₙ),其梯度为:                        │
│                                                                     │
│  ∇f = [∂f/∂x₁, ∂f/∂x₂, ..., ∂f/∂xₙ]ᵀ                               │
│                                                                     │
│  几何意义:                                                          │
│  • 梯度是一个向量,指向函数增长最快的方向                              │
│  • 梯度的模长表示增长的速度                                           │
│  • 负梯度指向函数下降最快的方向(这就是为什么梯度下降有效)              │
│                                                                     │
│  示例:f(x, y) = x² + y²                                             │
│  ∇f = [2x, 2y]ᵀ                                                    │
│                                                                     │
│  在点(1, 1):∇f = [2, 2]ᵀ                                           │
│  在点(1, 1)沿梯度方向移动,函数增长最快                                │
│                                                                     │
│  在深度学习中的应用:                                                  │
│  • 损失函数 L(θ) 对参数 θ 的梯度告诉我们如何更新参数                   │
│  • θ_new = θ_old - η·∇L(θ)                                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
Python
import numpy as np

# 多元函数示例:f(x, y) = x² + 2y²
def f(x, y):
    return x**2 + 2*y**2

def gradient_f(x, y):
    """计算梯度 [∂f/∂x, ∂f/∂y]"""
    df_dx = 2*x  # x的偏导数
    df_dy = 4*y  # y的偏导数
    return np.array([df_dx, df_dy])

# 在点(1, 2)处
point = np.array([1.0, 2.0])
grad = gradient_f(point[0], point[1])

print(f"在点 {point}:")
print(f"函数值: {f(point[0], point[1])}")
print(f"梯度: {grad}")
print(f"梯度方向(单位向量): {grad / np.linalg.norm(grad)}")

# 验证:沿梯度方向移动,函数值增加
step = 0.1
direction = grad / np.linalg.norm(grad)  # 单位方向
new_point = point + step * direction

print(f"\n沿梯度方向移动 {step}:")
print(f"新位置: {new_point}")
print(f"原函数值: {f(point[0], point[1]):.4f}")
print(f"新函数值: {f(new_point[0], new_point[1]):.4f}")
print(f"变化: {f(new_point[0], new_point[1]) - f(point[0], point[1]):.4f}")

# 梯度下降演示
print("\n" + "="*50)
print("梯度下降优化演示")
print("="*50)

current_point = np.array([3.0, 3.0])
learning_rate = 0.1

for i in range(10):
    grad = gradient_f(current_point[0], current_point[1])
    loss = f(current_point[0], current_point[1])

    print(f"Step {i}: 位置={current_point}, 损失={loss:.4f}, 梯度={grad}")

    # 梯度下降更新
    current_point = current_point - learning_rate * grad

5. 链式法则

反向传播与链式法则

5.1 链式法则的本质

核心思想:复合函数的导数 = 外层函数导数 × 内层函数导数

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    链式法则:复合函数的求导                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  单变量链式法则:                                                     │
│  如果 y = f(g(x)),则 dy/dx = f'(g(x)) · g'(x)                      │
│                                                                     │
│  直观理解:                                                          │
│  x的变化 → 引起g的变化 → 引起f的变化                                 │
│  总变化 = 第一步变化 × 第二步变化                                    │
│                                                                     │
│  示例:y = (x + 1)²                                                 │
│  令 u = x + 1,则 y = u²                                            │
│  dy/dx = dy/du · du/dx = 2u · 1 = 2(x + 1)                          │
│                                                                     │
│  ─────────────────────────────────────────────────────────────────  │
│                                                                     │
│  多变量链式法则(深度学习核心):                                      │
│                                                                     │
│  如果 z = f(x, y),x = g(t),y = h(t)                                │
│  则 dz/dt = ∂z/∂x · dx/dt + ∂z/∂y · dy/dt                           │
│                                                                     │
│  向量形式(更常用):                                                  │
│  如果 y = f(g(x)),则 ∂y/∂x = ∂y/∂g · ∂g/∂x                        │
│                                                                     │
│  在神经网络中的应用:                                                  │
│  损失L → 输出层 → 隐藏层 → 输入                                      │
│  ∂L/∂W₁ = ∂L/∂h₂ · ∂h₂/∂h₁ · ∂h₁/∂W₁                              │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

5.2 链式法则在反向传播中的应用

Python
import numpy as np

# 链式法则验证示例
# 函数: y = sigmoid(w·x + b)
# 我们想计算 ∂y/∂w, ∂y/∂b, ∂y/∂x

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def sigmoid_derivative(z):
    s = sigmoid(z)
    return s * (1 - s)

# 前向传播
x = 2.0
w = 3.0
b = 1.0

z = w * x + b      # 线性变换
y = sigmoid(z)     # 激活函数

print(f"前向传播:")
print(f"z = w·x + b = {w}·{x} + {b} = {z}")
print(f"y = sigmoid({z}) = {y}")

# 反向传播(假设损失对y的梯度为1)
dy = 1.0

# 链式法则: ∂L/∂z = ∂L/∂y · ∂y/∂z
dz = dy * sigmoid_derivative(z)
print(f"\n反向传播:")
print(f"∂y/∂z = sigmoid'(z) = {sigmoid_derivative(z):.4f}")
print(f"∂L/∂z = {dz:.4f}")

# 继续传播
dw = dz * x        # ∂L/∂w = ∂L/∂z · ∂z/∂w = ∂L/∂z · x
db = dz * 1        # ∂L/∂b = ∂L/∂z · ∂z/∂b = ∂L/∂z · 1
dx = dz * w        # ∂L/∂x = ∂L/∂z · ∂z/∂x = ∂L/∂z · w

print(f"\n各参数的梯度:")
print(f"∂L/∂w = {dw:.4f}")
print(f"∂L/∂b = {db:.4f}")
print(f"∂L/∂x = {dx:.4f}")

# 数值验证
epsilon = 1e-5

def compute_loss(w, b, x):
    z = w * x + b
    return sigmoid(z)

dw_numerical = (compute_loss(w+epsilon, b, x) - compute_loss(w-epsilon, b, x)) / (2*epsilon)
db_numerical = (compute_loss(w, b+epsilon, x) - compute_loss(w, b-epsilon, x)) / (2*epsilon)

print(f"\n数值验证:")
print(f"∂L/∂w 解析: {dw:.6f}, 数值: {dw_numerical:.6f}")
print(f"∂L/∂b 解析: {db:.6f}, 数值: {db_numerical:.6f}")

第三部分:概率论与信息论

6. 概率基础

6.1 概率与随机变量

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    概率基础概念                                        │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  概率的定义:                                                         │
│  P(A) 表示事件A发生的可能性,取值在[0, 1]之间                          │
│                                                                     │
│  随机变量:将随机事件映射为数值                                        │
│  • 离散随机变量:取值为有限或可数无限个(如掷骰子的点数)                │
│  • 连续随机变量:取值为连续区间(如身高、体重)                         │
│                                                                     │
│  概率分布:                                                           │
│  • 离散:概率质量函数(PMF)P(X=x)                                    │
│  • 连续:概率密度函数(PDF)f(x),P(a≤X≤b) = ∫f(x)dx                  │
│                                                                     │
│  在深度学习中的应用:                                                  │
│  • 数据增强的随机性                                                    │
│  • Dropout的随机失活                                                   │
│  • 生成模型学习数据分布                                                │
│  • 贝叶斯神经网络                                                      │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

6.2 常见概率分布

Python
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# 1. 均匀分布 Uniform(a, b)
# 在[a, b]区间内概率密度相同
x = np.linspace(0, 1, 100)
y_uniform = stats.uniform.pdf(x, 0, 1)

# 2. 正态分布(高斯分布)Normal(μ, σ²)
# 钟形曲线,自然界最常见
# 概率密度:f(x) = (1/√(2πσ²)) · exp(-(x-μ)²/(2σ²))
x = np.linspace(-5, 5, 100)
y_normal = stats.norm.pdf(x, 0, 1)

# 3. 伯努利分布 Bernoulli(p)
# 二值随机变量,取1的概率为p,取0的概率为1-p
# 应用:二分类问题的标签

# 4. 二项分布 Binomial(n, p)
# n次独立伯努利试验中成功的次数

# 5. 多项分布 Multinomial(n, p)
# 多分类问题的推广

# 6. 分类分布 Categorical(p)
# 一次试验的多项分布,用于多分类

# 可视化
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

# 均匀分布
axes[0, 0].plot(x, stats.uniform.pdf(x, -2, 4), 'b-', linewidth=2)
axes[0, 0].set_title('Uniform Distribution')
axes[0, 0].set_xlabel('x')
axes[0, 0].set_ylabel('PDF')
axes[0, 0].grid(True, alpha=0.3)

# 正态分布
axes[0, 1].plot(x, stats.norm.pdf(x, 0, 1), 'r-', linewidth=2, label='μ=0, σ=1')
axes[0, 1].plot(x, stats.norm.pdf(x, 0, 2), 'g--', linewidth=2, label='μ=0, σ=2')
axes[0, 1].plot(x, stats.norm.pdf(x, 2, 1), 'b:', linewidth=2, label='μ=2, σ=1')
axes[0, 1].set_title('Normal Distribution')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)

# 二项分布
n, p = 10, 0.5
x_binom = np.arange(0, n+1)
y_binom = stats.binom.pmf(x_binom, n, p)
axes[1, 0].bar(x_binom, y_binom, alpha=0.7)
axes[1, 0].set_title(f'Binomial Distribution (n={n}, p={p})')
axes[1, 0].set_xlabel('k')
axes[1, 0].set_ylabel('PMF')
axes[1, 0].grid(True, alpha=0.3)

# 指数分布
x_exp = np.linspace(0, 5, 100)
y_exp = stats.expon.pdf(x_exp, scale=1)
axes[1, 1].plot(x_exp, y_exp, 'm-', linewidth=2)
axes[1, 1].set_title('Exponential Distribution')
axes[1, 1].set_xlabel('x')
axes[1, 1].set_ylabel('PDF')
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('probability_distributions.png', dpi=150)
plt.show()

print("概率分布可视化完成!")

6.3 期望、方差与协方差

Python
import numpy as np

# 期望(均值):E[X] = Σx·P(X=x) 或 ∫x·f(x)dx
# 表示随机变量的平均值

# 方差:Var(X) = E[(X - E[X])²] = E[X²] - E[X]²
# 表示随机变量的离散程度

# 标准差:σ = √Var(X)

# 协方差:Cov(X, Y) = E[(X - E[X])(Y - E[Y])]
# 表示两个随机变量的线性相关性

# 相关系数:ρ = Cov(X, Y) / (σ_X · σ_Y)
# 标准化后的协方差,取值[-1, 1]

# 示例:计算数据集的统计量
data = np.random.randn(1000, 3)  # 1000个样本,3个特征

# 均值
mean = np.mean(data, axis=0)
print(f"均值: {mean}")

# 方差
variance = np.var(data, axis=0)
print(f"方差: {variance}")

# 标准差
std = np.std(data, axis=0)
print(f"标准差: {std}")

# 协方差矩阵
cov_matrix = np.cov(data.T)
print(f"\n协方差矩阵:\n{cov_matrix}")

# 相关系数矩阵
corr_matrix = np.corrcoef(data.T)
print(f"\n相关系数矩阵:\n{corr_matrix}")

# 在深度学习中的应用:
# 1. Batch Normalization使用均值和方差
# 2. 权重初始化考虑方差:
#    - Xavier初始化:适用于Sigmoid/Tanh激活,W ~ N(0, 2/(n_in+n_out))
#    - He初始化:适用于ReLU激活,W ~ N(0, 2/n_in)
# 3. 梯度裁剪使用标准差
# 4. 特征相关性分析

7. 信息论基础

7.1 熵(Entropy)

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    熵:不确定性的度量                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  定义:H(X) = -Σ P(x) · log(P(x))                                   │
│                                                                     │
│  直观理解:                                                          │
│  • 熵越大,不确定性越大,信息量越大                                    │
│  • 熵越小,不确定性越小,信息量越小                                    │
│                                                                     │
│  示例:                                                              │
│  硬币A:P(正面)=0.5, P(反面)=0.5                                     │
│  H(A) = -(0.5·log(0.5) + 0.5·log(0.5)) = 1 bit                      │
│                                                                     │
│  硬币B:P(正面)=0.9, P(反面)=0.1                                     │
│  H(B) = -(0.9·log(0.9) + 0.1·log(0.1)) ≈ 0.47 bit                   │
│                                                                     │
│  结论:硬币A的不确定性更大(熵更大)                                   │
│                                                                     │
│  在深度学习中的应用:                                                  │
│  • 交叉熵损失函数                                                      │
│  • 决策树的划分准则                                                    │
│  • 模型压缩(信息瓶颈)                                                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

7.2 KL散度与交叉熵

Python
import numpy as np

# KL散度(Kullback-Leibler Divergence)
# 衡量两个概率分布的差异
# D_KL(P||Q) = Σ P(x) · log(P(x)/Q(x))
# 性质:非负,不对称

def kl_divergence(p, q):
    """计算KL散度 D_KL(p||q)"""
    # 避免log(0)
    p = np.clip(p, 1e-10, 1)
    q = np.clip(q, 1e-10, 1)
    return np.sum(p * np.log(p / q))

# 交叉熵 H(P, Q) = -Σ P(x) · log(Q(x))
# 与KL散度的关系:H(P, Q) = H(P) + D_KL(P||Q)

def cross_entropy(p, q):
    """计算交叉熵"""
    q = np.clip(q, 1e-10, 1)
    return -np.sum(p * np.log(q))

# 示例
p = np.array([0.1, 0.2, 0.7])  # 真实分布
q1 = np.array([0.1, 0.2, 0.7])  # 与p相同
q2 = np.array([0.3, 0.3, 0.4])  # 与p不同

print("真实分布 P:", p)
print("预测分布 Q1:", q1)
print("预测分布 Q2:", q2)
print()

print(f"H(P, Q1) = {cross_entropy(p, q1):.4f}")
print(f"H(P, Q2) = {cross_entropy(p, q2):.4f}")
print(f"D_KL(P||Q2) = {kl_divergence(p, q2):.4f}")

# 在分类问题中的应用
# 真实标签(one-hot): y = [0, 0, 1, 0]
# 预测概率: ŷ = [0.1, 0.2, 0.6, 0.1]
# 损失 = -Σ y[i] · log(ŷ[i]) = -log(0.6)

y_true = np.array([0, 0, 1, 0])
y_pred = np.array([0.1, 0.2, 0.6, 0.1])

loss = -np.sum(y_true * np.log(y_pred + 1e-10))
print(f"\n分类损失: {loss:.4f}")

第四部分:优化理论

8. 梯度下降理论

梯度下降优化过程

损失函数曲面

8.1 优化问题定义

Text Only
┌─────────────────────────────────────────────────────────────────────┐
│                    优化问题:最小化损失函数                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  目标:找到参数 θ*,使得 L(θ*) 最小                                   │
│                                                                     │
│  θ* = argmin L(θ)                                                   │
│                                                                     │
│  梯度下降算法:                                                       │
│  θ_{t+1} = θ_t - η · ∇L(θ_t)                                        │
│                                                                     │
│  其中:                                                              │
│  • η:学习率(步长)                                                  │
│  • ∇L(θ_t):损失函数在θ_t处的梯度                                     │
│                                                                     │
│  为什么梯度下降有效?                                                  │
│  • 梯度指向函数增长最快的方向                                          │
│  • 负梯度指向函数下降最快的方向                                        │
│  • 沿负梯度移动,函数值减小                                            │
│                                                                     │
│  学习率的选择:                                                        │
│  • 太大:震荡,甚至发散                                                │
│  • 太小:收敛慢                                                        │
│  • 合适:稳定快速收敛                                                  │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

8.2 凸优化简介

Python
import numpy as np
import matplotlib.pyplot as plt

# 凸函数:任意两点连线在函数上方
# 性质:局部最小值就是全局最小值

# 凸函数示例:f(x) = x²
def convex_function(x):
    return x**2

# 非凸函数示例:f(x) = x·sin(x)
def non_convex_function(x):
    return x * np.sin(x)

x = np.linspace(-5, 5, 1000)

plt.figure(figsize=(12, 4))

plt.subplot(1, 2, 1)
plt.plot(x, convex_function(x), 'b-', linewidth=2)
plt.title('Convex Function: f(x) = x²')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True, alpha=0.3)
# 标注全局最小值
plt.plot(0, 0, 'ro', markersize=10, label='Global Minimum')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(x, non_convex_function(x), 'r-', linewidth=2)
plt.title('Non-Convex Function: f(x) = x·sin(x)')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True, alpha=0.3)
# 标注多个局部最小值
local_mins = [-2.3, 2.3]
for xm in local_mins:
    plt.plot(xm, non_convex_function(xm), 'bo', markersize=8)
plt.plot(0, 0, 'ro', markersize=10, label='Global Minimum')
plt.legend()

plt.tight_layout()
plt.savefig('convex_vs_nonconvex.png', dpi=150)
plt.show()

print("凸函数 vs 非凸函数可视化完成!")

# 深度学习的挑战:
# 神经网络的损失函数通常是非凸的
# 但实践中SGD通常能找到好的局部最小值
# 原因:高维空间中,鞍点比局部最小值更常见

总结与下一步

数学基础速查表

概念 公式 深度学习应用
向量点积 a·b = Σaᵢbᵢ 注意力机制
矩阵乘法 C = AB 全连接层、注意力
特征分解 A = VΛV⁻¹ PCA、谱分析
SVD A = UΣVᵀ 降维、压缩
导数 f'(x) = df/dx 梯度计算
梯度 ∇f = [∂f/∂x₁, ...] 参数更新
链式法则 ∂z/∂x = ∂z/∂y · ∂y/∂x 反向传播
期望 E[X] = Σx·P(x) 损失函数
方差 Var(X) = E[(X-μ)²] 初始化、BatchNorm
H(X) = -ΣP(x)logP(x) 交叉熵损失
KL散度 D_KL(P||Q) = ΣP·log(P/Q) 变分推断

学习建议

  1. 不要死记硬背:理解概念的本质和几何意义
  2. 动手计算:用笔和纸推导公式
  3. 代码验证:用Python验证数学结论
  4. 联系应用:思考每个概念在深度学习中的具体应用
  5. 循序渐进:先掌握核心概念,再深入细节

下一步

完成数学基础后,你可以: 1. 回到 01-深度学习概述 继续学习 2. 在学习理论章节时,随时回来查阅数学基础 3. 尝试用数学语言重新理解已学过的概念

记住:数学是工具,不是目的。掌握这些数学基础,是为了更深入地理解深度学习算法。祝学习愉快!🎉