深度学习数学基础入门

前言

为了学习,也为了看懂深度学习中的定律、函数、方程等,所以狠心的整理回顾了一下涉及到深度学习中的一些数学基础知识。

知识列表:

I. 预备知识:基础数学概念回顾

  1. 集合
    • 集合的定义与表示 (列举法、描述法)
    • 集合的基本关系 (子集、真子集、空集、全集)
    • 集合的基本运算 (并集、交集、补集、差集)
    • 韦恩图 (Venn Diagram) 的理解与应用
  1. 函数

    • 函数的定义 (映射、定义域、值域、对应法则)
    • 函数的表示 (解析式、图像法、列表法)
    • 函数的性质 (单调性、奇偶性、周期性)
    • 基本初等函数
      • 线性函数 (一次函数)
      • 二次函数
      • 幂函数
      • 指数函数
      • 对数函数
      • 三角函数 (正弦、余弦、正切)
      • 反三角函数 (反正弦、反余弦、反正切)
  2. 方程与不等式

    • 一元一次方程及其解法
    • 一元二次方程及其解法 (公式法、因式分解法、配方法)
    • 根与系数的关系 (韦达定理)
    • 不等式的性质
    • 一元一次不等式(组)及其解法
    • 一元二次不等式及其解法
    • 绝对值不等式
    • 分式不等式
  3. 数列

    • 数列的定义
    • 等差数列
      • 定义与通项公式
      • 前 n 项和公式
    • 等比数列
      • 定义与通项公式
      • 前 n 项和公式

II. 线性代数基础

  1. 向量

    • 向量的定义 (几何向量、代数向量)
    • 向量的表示 (坐标表示、列向量、行向量)
    • 向量的运算
      • 向量加法 (平行四边形法则、三角形法则)
      • 向量数乘
      • 向量点积 (内积)
      • 向量叉积 (外积) (仅限三维向量)
    • 向量的范数
      • L1 范数
      • L2 范数 (欧几里得范数)
      • Lp 范数
    • 线性相关与线性无关
    • 向量空间、子空间
    • 基、维数、坐标
  2. 矩阵

    • 矩阵的定义
    • 矩阵的表示
    • 特殊矩阵
      • 零矩阵
      • 方阵
      • 单位矩阵
      • 对角矩阵
      • 上三角矩阵
      • 下三角矩阵
      • 对称矩阵
      • 反对称矩阵
    • 矩阵的运算
      • 矩阵加法
      • 矩阵数乘
      • 矩阵乘法 (矩阵与向量的乘法、矩阵与矩阵的乘法)
      • 矩阵的转置
    • 矩阵的行列式
      • 二阶行列式
      • 三阶行列式
      • n 阶行列式
      • 行列式的性质
    • 矩阵的逆
      • 逆矩阵的定义
      • 逆矩阵的性质
      • 逆矩阵的求法 (伴随矩阵法、初等变换法)
    • 矩阵的秩
  3. 线性方程组

    • 线性方程组的表示 (系数矩阵、增广矩阵)
    • 线性方程组的解
      • 唯一解
      • 无穷多解
      • 无解
    • 高斯消元法 (初等行变换)
    • 克拉默法则 (Cramer’s Rule)
  4. 特征值与特征向量

    • 特征值与特征向量的定义
    • 特征值与特征向量的计算
    • 特征多项式
    • 特征空间
    • 特征值分解 (谱分解)
    • 特征值与特征向量的几何意义
  5. 奇异值分解 (SVD)

    • SVD 的定义
    • SVD的计算(进阶)
    • SVD 的应用 (数据压缩、降维、推荐系统)

III. 微积分基础

  1. 导数

    • 导数的定义 (极限形式)
    • 导数的几何意义 (切线斜率、瞬时变化率)
    • 常见函数的导数
      • 常数函数
      • 幂函数
      • 指数函数
      • 对数函数
      • 三角函数
      • 反三角函数
    • 导数法则
      • 加法法则
      • 减法法则
      • 乘法法则
      • 除法法则
      • 链式法则 (复合函数求导)
    • 高阶导数
  2. 偏导数

    • 偏导数的定义
    • 多元函数的偏导数
    • 梯度向量
    • 方向导数
    • 全微分
  3. 梯度下降法

    • 梯度下降法的原理
    • 梯度下降法的步骤
    • 学习率 (步长) 的作用
    • 局部最小值、全局最小值
    • 鞍点
  4. 泰勒展开

    • 泰勒公式 (Taylor’s Formula)
    • 麦克劳林公式 (Maclaurin’s Formula)
    • 一阶泰勒展开 (线性近似)
    • 二阶泰勒展开 (二次近似)
  5. 凸优化(选学)
    * 凸集
    * 凸函数
    * 凸优化问题
    * 凸优化的性质(局部最优解即全局最优解)

IV. 概率论与数理统计基础

  1. 随机事件与概率
    * 随机试验
    * 样本空间
    * 随机事件
    * 事件的关系与运算 (包含、相等、并、交、差、互斥、对立)
    * 概率的定义 (古典概型、几何概型、频率定义、公理化定义)
    * 概率的性质 (非负性、规范性、可加性)
    * 条件概率
    * 事件的独立性
    * 全概率公式
    * 贝叶斯公式 (Bayes’ Theorem)

  2. 随机变量
    * 随机变量的定义
    * 离散型随机变量

    • 概率分布列
    • 伯努利分布 (0-1 分布)
    • 二项分布
    • 泊松分布
      * 连续型随机变量
    • 概率密度函数 (PDF)
    • 均匀分布
    • 指数分布
    • 正态分布 (高斯分布)
      * 随机变量的数字特征
    • 期望 (均值)
    • 方差
    • 标准差
    • 协方差
    • 相关系数
  3. 最大似然估计 (MLE)
    * 似然函数
    * 最大似然估计的原理
    * 最大似然估计的步骤
    * 最大似然估计的应用

  4. 信息熵与交叉熵

    • 信息熵定义与公式
    • 交叉熵定义与公式
    • 相对熵(KL散度)
    • 信息熵,交叉熵,相对熵在深度学习中的应用

1. 集合

1.1 什么是集合?

  • 通俗定义: 把一些东西放在一起,就形成了一个集合。这些“东西”可以是任何事物,比如数字、字母、人、物体,甚至是其他集合。
  • 数学定义: 具有某种特定性质的、确定的、互不相同的事物的总体,称为集合 (Set)。 集合中的每个事物称为元素 (Element)。

举例:

  • 所有的英文字母可以组成一个集合:{a, b, c, …, z}
  • 所有小于10的正整数可以组成一个集合:{1, 2, 3, 4, 5, 6, 7, 8, 9}
  • 你今天穿的所有衣物可以组成一个集合:{衬衫, 裤子, 袜子, 鞋子}
  • 一个班级里所有的学生可以组成一个集合。

要点:

  • 确定性: 一个元素是否属于某个集合,必须是明确的,不能模棱两可。例如,“好人”不能组成一个集合,因为“好”的标准不确定。
  • 互异性: 集合中的元素必须是互不相同的。例如,{1, 2, 2, 3} 不是一个集合,应该写成 {1, 2, 3}。
  • 无序性: 集合中的元素没有先后顺序。{1, 2, 3} 和 {3, 1, 2} 是同一个集合。

1.2 集合的表示

  • 列举法: 把集合中的所有元素一一列举出来,写在大括号 {} 内。
    • 例如:{1, 2, 3, 4, 5}
  • 描述法: 用集合中元素的共同特征来描述集合。
    • 例如:{x | x 是小于 10 的正整数} (读作“x 属于实数集,且 x 是小于 10 的正整数”)。竖线 “|” 前面表示元素的形式,后面表示元素的特征。
    • 更复杂的例子:{ (x, y) | x² + y² = 1 } (表示单位圆上的所有点)
  • 特殊符号:
    • N: 自然数集 (非负整数集) {0, 1, 2, 3, …}
    • N+ 或 N*: 正整数集 {1, 2, 3, …}
    • Z: 整数集 {…, -2, -1, 0, 1, 2, …}
    • Q: 有理数集 (可以表示成两个整数之比的数)
    • R: 实数集 (包括有理数和无理数)
    • C: 复数集
    • ∅: 空集, 不包含任何元素的集合

1.3 集合的基本关系

  • 子集 (Subset): 如果集合 A 的所有元素都属于集合 B,那么 A 是 B 的子集,记作 A ⊆ B (或 B ⊇ A)。
    • 例如:{1, 2} ⊆ {1, 2, 3}
    • 任何集合都是它本身的子集:A ⊆ A
    • 空集是任何集合的子集:∅ ⊆ A
  • 真子集 (Proper Subset): 如果 A 是 B 的子集,且 A ≠ B (A 中至少有一个元素不属于 B),那么 A 是 B 的真子集,记作 A ⊂ B (或 B ⊃ A)。
    • 例如:{1, 2} ⊂ {1, 2, 3}
  • 空集 (Empty Set): 不包含任何元素的集合,记作 ∅。
    • 空集是任何集合的子集。
    • 空集是唯一的。
  • 全集 (Universal Set): 在某个特定问题中,所有研究的对象都属于一个最大的集合,这个集合称为全集,通常记作 U。
    • 例如,在研究整数时,全集可以是整数集 Z。

1.4 集合的基本运算

  • 并集 (Union): 由所有属于集合 A 或属于集合 B 的元素组成的集合,记作 A ∪ B。
    • A ∪ B = {x | x ∈ A 或 x ∈ B}
    • 例如:{1, 2, 3} ∪ {3, 4, 5} = {1, 2, 3, 4, 5}
  • 交集 (Intersection): 由所有既属于集合 A 又属于集合 B 的元素组成的集合,记作 A ∩ B。
    • A ∩ B = {x | x ∈ A 且 x ∈ B}
    • 例如:{1, 2, 3} ∩ {3, 4, 5} = {3}
  • 补集 (Complement): 如果 A 是全集 U 的一个子集,由所有不属于 A 的元素组成的集合,称为 A 在 U 中的补集 (或余集),记作 ∁UA 或 A’。
    • ∁UA = {x | x ∈ U 且 x ∉ A}
    • 例如:如果 U = {1, 2, 3, 4, 5},A = {1, 2, 3},那么 ∁UA = {4, 5}
  • 差集(Difference): 所有属于A且不属于B的元素组成的集合, 记作A\B
    • A\B = {x | x∈A 且 x∉B}
    • 例如:{1,2,3} \ {3,4} = {1,2}

1.5 韦恩图 (Venn Diagram)

  • 韦恩图是用平面上的圆形 (或其他封闭曲线) 来表示集合的一种图形。
  • 可以直观地表示集合之间的关系 (子集、真子集) 和运算 (并集、交集、补集)。
  • 在表示集合运算时非常有用。

以下是使用Mermaid代码绘制韦恩图的示例:

graph LR
    subgraph U
    A((A))
    B((B))
    end
    A --> |A ∪ B| C{并集}
    A --> |A ∩ B| D{交集}
    A --> |∁UA| E{补集}

集合是数学中最基本的概念之一,也是学习深度学习数学基础的起点。理解集合的概念、表示方法、关系和运算,对于后续理解概率论等概念至关重要。


2. 函数

函数。 函数是现代数学、乃至整个科学的基石。在深度学习中,从数据到预测结果的映射,本质上就是一个复杂的函数。

2.1 什么是函数?

  • 通俗定义: 函数就像一个“黑盒子”,你给它一个输入(称为自变量),它会根据某种规则进行处理,然后给你一个输出(称为因变量)。

  • 数学定义: 设 A 和 B 是两个非空集合,如果按照某种确定的对应关系 f,对于集合 A 中的任意一个元素 x,在集合 B 中都有唯一确定的元素 y 与之对应,那么就把这种对应关系 f 叫做定义在集合 A 上的一个函数 (Function),记作 y = f(x)。

    • x 称为自变量 (Independent Variable)。
    • y 称为因变量 (Dependent Variable)。
    • A 称为函数的定义域 (Domain),即所有可能的输入 x 的集合。
    • 所有可能的输出 y 的集合称为函数的值域 (Range)。
    • f 是对应法则,它规定了输入 x 如何映射到输出 y。

举例:

  • 自动售货机: 你投入硬币 (输入),售货机根据你的选择给你相应的商品 (输出)。
  • 计算器: 你输入一个数字和一个运算符号 (如 +2),计算器会计算出结果 (输出)。
  • 身高预测: 根据父母的身高 (输入),可以预测子女的身高 (输出) —— 当然,这只是一个粗略的估计。
  • y=2x+1。这是一个常见的数学函数。例如输入2,输出5。

要点:

  • 一一对应: 函数要求对于每一个输入 x,都必须有唯一的输出 y 与之对应。一个 x 不能对应多个 y(但多个 x 可以对应同一个 y)。
  • 定义域和值域: 定义域是所有可能的输入的集合,值域是所有可能的输出的集合。

2.2 函数的表示

  • 解析式 (公式法): 用数学表达式来表示函数。

    • 例如:y = 2x + 1, f(x) = x², g(t) = sin(t)
  • 图像法: 用图形来表示函数。在平面直角坐标系中,以自变量 x 为横坐标,因变量 y 为纵坐标,画出函数的图像。

    • 例如,y = 2x + 1 的图像是一条直线。
    • 例如,y = x² 的图像是抛物线。

    下面是使用Matplotlib绘制这两个函数的示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import matplotlib.pyplot as plt
    import numpy as np

    # 生成 x 值
    x = np.linspace(-5, 5, 100) # 从 -5 到 5 生成 100 个点

    # 计算 y 值
    y1 = 2 * x + 1
    y2 = x**2

    # 绘制图形
    plt.figure(figsize=(8, 6)) # 设置图形大小

    plt.subplot(2, 1, 1) # 创建子图,2 行 1 列,当前为第 1 个子图
    plt.plot(x, y1)
    plt.title('y = 2x + 1')
    plt.xlabel('x')
    plt.ylabel('y')

    plt.subplot(2, 1, 2) # 创建子图,2 行 1 列,当前为第 2 个子图
    plt.plot(x, y2)
    plt.title('y = x²')
    plt.xlabel('x')
    plt.ylabel('y')

    plt.tight_layout() # 自动调整子图布局
    plt.show()
  • 列表法: 用表格来表示函数。表格中列出一些自变量的值和对应的因变量的值。

    • 例如:
      x y = 2x + 1
      -1 -1
      0 1
      1 3
      2 5

2.3 函数的性质

  • 单调性 (Monotonicity): 描述函数值随自变量变化而变化的情况。
    • 单调递增: 在定义域内,如果 x₁ < x₂,则 f(x₁) < f(x₂),那么函数是单调递增的。
    • 单调递减: 在定义域内,如果 x₁ < x₂,则 f(x₁) > f(x₂),那么函数是单调递减的。
  • 奇偶性 (Parity): 描述函数关于 y 轴或原点对称的情况。
    • 偶函数: 对于定义域内的任意 x,都有 f(-x) = f(x),那么函数是偶函数 (图像关于 y 轴对称)。
      • 例如:f(x) = x²
    • 奇函数: 对于定义域内的任意 x,都有 f(-x) = -f(x),那么函数是奇函数 (图像关于原点对称)。
      • 例如:f(x) = x³
  • 周期性 (Periodicity): 描述函数值周期性重复出现的情况。
    • 对于定义域内的任意 x,如果存在一个常数 T ≠ 0,使得 f(x + T) = f(x),那么函数是周期函数,T 称为函数的周期。
    • 例如:f(x) = sin(x) 是周期函数,周期为 2π。

2.4 基本初等函数

在深度学习中经常遇到的一些基本函数:

  • 线性函数 (一次函数): y = kx + b (k 和 b 是常数,k ≠ 0)。图像是一条直线。
  • 二次函数: y = ax² + bx + c (a, b, c 是常数, a ≠ 0)。图像是抛物线。
  • 幂函数: y = xᵃ (a 是常数)。
  • 指数函数: y = aˣ (a 是常数, a > 0 且 a ≠ 1)。
    • 当 a > 1 时,指数函数单调递增。
    • 当 0 < a < 1 时,指数函数单调递减。
    • 一个非常重要的指数函数:自然指数函数 y = eˣ,其中 e ≈ 2.71828… 是一个无理数 (自然对数的底)。
  • 对数函数: y = logₐx (a 是常数, a > 0 且 a ≠ 1)。对数函数是指数函数的反函数。
    • 当 a > 1 时,对数函数单调递增。
    • 当 0 < a < 1 时,对数函数单调递减。
    • 自然对数函数 y = ln x,是以 e 为底的对数函数 (logₑx)。
  • 三角函数: 正弦函数 y = sin(x), 余弦函数 y = cos(x), 正切函数 y = tan(x)。
  • **反三角函数:**反正弦函数,反余弦函数,反正切函数

函数是描述输入和输出之间关系的数学工具,对函数的理解,是构建深度学习模型的基础。


3. 方程与不等式

方程与不等式。 方程与不等式是处理数量关系的重要工具,在深度学习中,它们被用于模型参数的求解、优化问题的约束条件等方面。

3.1 方程

  • 什么是方程? 含有未知数的等式叫做方程 (Equation)。

    • 未知数: 通常用字母 x, y, z 等表示。
    • 等式: 用等号 “=” 连接的式子。
    • 方程的解: 使方程左右两边相等的未知数的值。
    • 解方程: 求出方程的解的过程。
  • 一元一次方程: 只含有一个未知数,并且未知数的次数是 1 的方程。

    • 一般形式:ax + b = 0 (a, b 是常数, a ≠ 0)
    • 解法:移项、合并同类项、系数化为 1。
    • 例如:2x + 3 = 7 => 2x = 4 => x = 2
  • 一元二次方程: 只含有一个未知数,并且未知数的最高次数是 2 的方程。

    • 一般形式:ax² + bx + c = 0 (a, b, c 是常数, a ≠ 0)
    • 解法:
      • 公式法: 求根公式 x = (-b ± √(b² - 4ac)) / 2a
        • 判别式 Δ = b² - 4ac
          • Δ > 0:方程有两个不相等的实数根。
          • Δ = 0:方程有两个相等的实数根 (重根)。
          • Δ < 0:方程没有实数根 (有两个共轭复数根)。
      • 因式分解法: 将方程左边分解成两个一次因式的乘积。
        • 例如:x² - 5x + 6 = 0 => (x - 2)(x - 3) = 0 => x = 2 或 x = 3
      • 配方法: 将方程左边配成一个完全平方的形式。
  • 根与系数的关系 (韦达定理): 对于一元二次方程 ax² + bx + c = 0 (a ≠ 0),如果方程有两个根 x₁ 和 x₂,那么:

    • x₁ + x₂ = -b/a
    • x₁ * x₂ = c/a

3.2 不等式

  • 什么是不等式? 用不等号 (>, <, ≥, ≤, ≠) 连接的式子叫做不等式 (Inequality)。
  • 不等式的性质:
    • 不等式的两边同时加上或减去同一个数,不等号的方向不变。
    • 不等式的两边同时乘以或除以同一个正数,不等号的方向不变。
    • 不等式的两边同时乘以或除以同一个负数,不等号的方向改变。
  • 一元一次不等式: 只含有一个未知数,并且未知数的次数是 1 的不等式。
    • 一般形式:ax + b > 0, ax + b < 0, ax + b ≥ 0, ax + b ≤ 0 (a, b 是常数, a ≠ 0)
    • 解法:与解一元一次方程类似,但要注意乘以或除以负数时,不等号的方向要改变。
  • 一元二次不等式: 只含有一个未知数,并且未知数的最高次数是 2 的不等式。
    • 一般形式:ax² + bx + c > 0, ax² + bx + c < 0, ax² + bx + c ≥ 0, ax² + bx + c ≤ 0 (a, b, c 是常数, a ≠ 0)
    • 解法:通常先求出对应的一元二次方程的根,然后根据二次函数的图像 (抛物线) 来确定不等式的解集。
    • 也可通过因式分解,转换成一元一次不等式组求解。
  • 绝对值不等式: 含有绝对值符号的不等式。
    • |x| < a (a > 0) <=> -a < x < a
    • |x| > a (a > 0) <=> x < -a 或 x > a
  • 分式不等式: 分母中含有未知数的不等式。
    • 解法:通常先将分式不等式转化为整式不等式,然后求解。要注意分母不能为 0。

方程和不等式是解决各种数学问题的基本工具。了解其定义、类型和解法,对于理解深度学习中的优化过程非常重要。许多深度学习问题最终会转化为求解方程或不等式,或者在满足一定约束条件(不等式)下进行优化。


4. 数列

数列。数列在深度学习中也有一定的应用,比如在处理时间序列数据、循环神经网络 (RNN) 中,就会涉及到数列的概念。

4.1 什么是数列?

  • 定义: 按照一定次序排列的一列数叫做数列 (Sequence)。
    • 数列中的每一个数叫做数列的 (Term)。
    • 第一项通常称为首项,记作 a₁。
    • 第 n 项称为数列的通项,记作 aₙ。
    • 数列可以表示为 a₁, a₂, a₃, …, aₙ, …
    • 数列可以是有穷的 (有限项),也可以是无穷的 (无限项)。

举例:

  • 1, 2, 3, 4, 5, … (正整数数列)
  • 2, 4, 6, 8, 10, … (偶数数列)
  • 1, 1/2, 1/3, 1/4, 1/5, … (倒数数列)
  • 1, -1, 1, -1, 1, … (摆动数列)

4.2 等差数列

  • 定义: 如果一个数列从第 2 项起,每一项与它的前一项的差都等于同一个常数,那么这个数列叫做等差数列 (Arithmetic Sequence 或 Arithmetic Progression)。
    • 这个常数叫做等差数列的公差 (Common Difference),通常用 d 表示。
    • 通项公式:aₙ = a₁ + (n - 1)d
  • 等差数列求和:
    • 前 n 项和公式:Sₙ = (a₁ + aₙ)n / 2 = na₁ + n(n - 1)d / 2
    • 推导:可以利用“倒序相加”的方法推导。

举例:

  • 1, 3, 5, 7, 9, … (公差 d = 2)
  • 10, 7, 4, 1, -2, … (公差 d = -3)

4.3 等比数列

  • 定义: 如果一个数列从第 2 项起,每一项与它的前一项的比都等于同一个常数,那么这个数列叫做等比数列 (Geometric Sequence 或 Geometric Progression)。
    • 这个常数叫做等比数列的公比 (Common Ratio),通常用 q 表示 (q ≠ 0)。
    • 通项公式:aₙ = a₁ * qⁿ⁻¹
  • 等比数列求和:
    • 前 n 项和公式:
      • 当 q ≠ 1 时,Sₙ = a₁(1 - qⁿ) / (1 - q)
      • 当 q = 1 时,Sₙ = na₁
    • 推导:可以利用“错位相减”的方法推导。

举例:

  • 2, 4, 8, 16, 32, … (公比 q = 2)
  • 1, 1/2, 1/4, 1/8, 1/16, … (公比 q = 1/2)

数列是按照一定规律排列的数的集合。等差数列和等比数列是两种最基本的数列,它们在数学和实际应用中都有广泛的应用。理解数列的概念、通项公式和求和公式,对于后续学习会有帮助。


II. 线性代数基础

线性代数是深度学习的数学基础中非常重要的一个部分。深度学习中的数据通常表示为向量和矩阵,神经网络的运算也 মূলত是基于线性代数的运算。

我们从第一个小知识点开始:1. 向量

1.1 什么是向量?

  • 几何定义: 向量 (Vector) 是既有大小又有方向的量。可以用带箭头的线段来表示,箭头表示向量的方向,线段的长度表示向量的大小。
    • 在物理学中,力、速度、位移等都是向量。
  • 代数定义: 向量是有序的一组数。
    • 例如:[1, 2, 3] 是一个三维向量。
    • [4, 5] 是一个二维向量。
    • [6] 是一个一维向量。
  • 更广义的定义: 向量是向量空间中的元素。 (这个定义比较抽象,我们暂时可以不深究。)

向量的表示:

  • 几何表示: 在平面直角坐标系或空间直角坐标系中,用带箭头的线段表示。
    • 起点通常是原点 (0, 0) 或 (0, 0, 0)。
    • 终点的坐标就是向量的坐标。
  • 坐标表示:
    • 二维向量:v = [x, y] 或 v = (x, y)
    • 三维向量:v = [x, y, z] 或 v = (x, y, z)
    • n 维向量:v = [v₁, v₂, …, vₙ] 或 v = (v₁, v₂, …, vₙ)
  • 列向量和行向量:
    • 列向量: 将向量的元素竖着排列。
      1
      2
      3
      [1]
      [2]
      [3]
    • 行向量: 将向量的元素横着排列。
      1
      [1, 2, 3]
    • 在深度学习中,通常使用列向量。

1.2 向量的运算

  • 向量加法: 对应元素相加。
    • 几何意义:平行四边形法则或三角形法则。
    • 代数表示:如果 u = [u₁, u₂, …, uₙ],v = [v₁, v₂, …, vₙ],那么 u + v = [u₁ + v₁, u₂ + v₂, …, uₙ + vₙ]。
  • 向量数乘: 向量的每个元素都乘以一个标量 (实数)。
    • 几何意义:向量的伸缩。如果标量大于 0,则向量方向不变;如果标量小于 0,则向量方向相反。
    • 代数表示:如果 v = [v₁, v₂, …, vₙ],k 是一个标量,那么 kv = [kv₁, kv₂, …, kvₙ]。
  • 向量点积 (内积): 两个向量对应元素相乘,然后求和。
    • 几何意义:一个向量在另一个向量上的投影长度乘以另一个向量的长度。点积的结果是一个标量。
      • 如果两个向量的点积为 0,则这两个向量正交 (垂直)。
    • 代数表示:如果 u = [u₁, u₂, …, uₙ],v = [v₁, v₂, …, vₙ],那么 uv = u₁v₁ + u₂v₂ + … + uₙvₙ。
  • 向量叉积 (外积): 仅适用于三维向量。
    • 几何意义:叉积的结果是一个向量,其方向垂直于两个原始向量所在的平面,其大小等于两个原始向量构成的平行四边形的面积。
    • 代数表示:如果 u = [u₁, u₂, u₃],v = [v₁, v₂, v₃],那么 u × v = [u₂v₃ - u₃v₂, u₃v₁ - u₁v₃, u₁v₂ - u₂v₁]。

1.3 向量的范数

  • 范数 (Norm): 衡量向量“大小”的度量。范数是一个函数,它将向量映射为一个非负实数。
  • Lp 范数:
    • L1 范数:向量各个元素的绝对值之和。||v||₁ = |v₁| + |v₂| + … + |vₙ|
    • L2 范数 (欧几里得范数):向量各个元素的平方和的平方根。||v||₂ = √(v₁² + v₂² + … + vₙ²)
    • Lp 范数:||v||ₚ = (|v₁|ᵖ + |v₂|ᵖ + … + |vₙ|ᵖ)¹/ᵖ (p ≥ 1)

代码示例 (Python - NumPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np

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

# 向量加法
print("向量加法:", v1 + v2) # 输出:[5 7 9]

# 向量数乘
print("向量数乘:", 2 * v1) # 输出:[2 4 6]

# 向量点积
print("向量点积:", np.dot(v1, v2)) # 输出:32 (1*4 + 2*5 + 3*6 = 32)

# 向量叉积 (仅限三维向量)
v3 = np.array([1, 2, 3])
v4 = np.array([4, 5, 6])
print("向量叉积:", np.cross(v3, v4)) # 输出:[-3 6 -3]

# L1 范数
print("L1 范数:", np.linalg.norm(v1, ord=1)) # 输出:6.0

# L2 范数
print("L2 范数:", np.linalg.norm(v1, ord=2)) # 输出:3.7416573867739413

# Lp范数
print("L4 范数", np.linalg.norm(v1, ord=4))

向量是线性代数的基本元素,也是深度学习中表示数据的基本单位。理解向量的几何意义、代数表示、运算和范数,对于后续学习矩阵、线性变换等概念至关重要。


2. 矩阵

2.1 什么是矩阵?

  • 定义: 矩阵 (Matrix) 是一个由 m 行 n 列元素排列成的矩形阵列。
    • 矩阵中的元素可以是数字、符号或数学表达式。
    • m 行 n 列的矩阵称为 m × n 矩阵。
    • 如果 m = n,则称矩阵为方阵 (Square Matrix)。

矩阵的表示:

1
2
3
4
A = [ a₁₁ a₁₂ ... a₁ₙ ]   
[ a₂₁ a₂₂ ... a₂ₙ ]
[ . . ... . ]
[ aₘ₁ aₘ₂ ... aₘₙ ]
  • 通常用大写字母表示矩阵,如 A, B, C。
  • aᵢⱼ 表示矩阵 A 中第 i 行第 j 列的元素。

举例:

  • [ 1  2 ]
    [ 3  4 ]
    
    1
    2
    3
    4
        是一个 2 × 2 矩阵 (方阵)。
    * ```
    [ 1 2 3 ]
    [ 4 5 6 ]
    是一个 2 × 3 矩阵。
  • [ 1 ]
    [ 2 ]
    [ 3 ]
    
    1
    2
    3
        是一个 3 × 1 矩阵 (列向量)。
    * ```
    [ 1 2 3 ]
    是一个 1 × 3 矩阵 (行向量)。

2.2 特殊矩阵

  • 零矩阵 (Zero Matrix): 所有元素都为 0 的矩阵。
  • 方阵 (Square Matrix): 行数和列数相等的矩阵。
  • 单位矩阵 (Identity Matrix): 对角线上的元素都为 1,其余元素都为 0 的方阵。通常用 I 或 E 表示。
    1
    2
    3
    [ 1  0  0 ]
    [ 0 1 0 ]
    [ 0 0 1 ]
  • 对角矩阵 (Diagonal Matrix): 除了对角线上的元素外,其余元素都为 0 的方阵。
    1
    2
    3
    [ 2  0  0 ]
    [ 0 5 0 ]
    [ 0 0 -1 ]
  • 上三角矩阵 (Upper Triangular Matrix): 对角线以下的元素都为 0 的方阵。
    1
    2
    3
    [1 2 3]
    [0 4 5]
    [0 0 6]
  • 下三角矩阵 (Lower Triangular Matrix): 对角线以上的元素都为 0 的方阵。
    1
    2
    3
    [ 1  0  0 ]
    [ 2 3 0 ]
    [ 4 5 6 ]
  • 对称矩阵 (Symmetric Matrix): 元素关于对角线对称的方阵 (aᵢⱼ = aⱼᵢ)。
    1
    2
    3
    [ 1  2  3 ]
    [ 2 4 5 ]
    [ 3 5 6 ]
  • 反对称矩阵 (Skew-symmetric Matrix): 元素关于对角线反对称的方阵 (aᵢⱼ = -aⱼᵢ,且对角线元素都为 0)。

2.3 矩阵的运算

  • 矩阵加法: 对应元素相加 (只有相同大小的矩阵才能相加)。
  • 矩阵数乘: 矩阵的每个元素都乘以一个标量。
  • 矩阵乘法 (Matrix Multiplication):
    • 要求:第一个矩阵的列数必须等于第二个矩阵的行数。
    • 结果:一个 m × n 矩阵乘以一个 n × p 矩阵,得到一个 m × p 矩阵。
    • 计算:结果矩阵的第 i 行第 j 列的元素等于第一个矩阵的第 i 行与第二个矩阵的第 j 列的点积。
    • 不满足交换律: 通常 AB ≠ BA。
    • 满足结合律: (AB)C = A(BC)。
    • 满足分配律: A(B + C) = AB + AC, (A + B)C = AC + BC。
    • 与单位矩阵相乘: AI = IA = A (A 是方阵)。
  • 矩阵的转置(Transpose):
    • 将矩阵的行和列互换。
      • 如果 A 是 m × n 矩阵,那么 A 的转置 (记作 Aᵀ 或 A’) 是一个 n × m 矩阵。
      • (Aᵀ)ᵢⱼ = Aⱼᵢ

代码示例 (Python - NumPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np

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

# 矩阵加法
print("矩阵加法:\n", A + B)

# 矩阵数乘
print("矩阵数乘:\n", 2 * A)

# 矩阵乘法
print("矩阵乘法:\n", np.dot(A, B))

# 矩阵转置
print("矩阵转置:\n", A.T)

# 单位矩阵
I = np.eye(3) # 3x3 单位矩阵
print("单位矩阵:\n", I)

矩阵是线性代数中的另一个核心概念。它们用于表示线性变换、存储数据等。理解矩阵的类型、运算(特别是矩阵乘法)对于深度学习至关重要,因为神经网络的每一层都可以看作是一个矩阵运算。


3. 线性方程组

3.1 什么是线性方程组?

  • 定义: 线性方程组 (System of Linear Equations) 是一组包含多个未知数、且每个方程都是线性的方程组。
    • 线性方程:未知数的次数都是 1 的方程。

线性方程组的表示:

  • 一般形式:

    1
    2
    3
    4
    a₁₁x₁ + a₁₂x₂ + ... + a₁ₙxₙ = b₁
    a₂₁x₁ + a₂₂x₂ + ... + a₂ₙxₙ = b₂
    ...
    aₘ₁x₁ + aₘ₂x₂ + ... + aₘₙxₙ = bₘ

    其中:
    * x₁, x₂, …, xₙ 是未知数。
    * aᵢⱼ 是系数 (已知常数)。
    * bᵢ 是常数项 (已知常数)。

  • 矩阵形式:

    1
    Ax = b

    其中:
    * A 是 m × n 的系数矩阵 (由 aᵢⱼ 组成)。
    * x 是 n × 1 的未知数向量 (由 xᵢ 组成)。
    * b 是 m × 1 的常数项向量 (由 bᵢ 组成)。

举例:

1
2
2x + 3y = 7
x - y = 1

这是一个包含两个未知数 (x, y) 和两个方程的线性方程组。

用矩阵形式表示:

1
2
[ 2  3 ] [ x ] = [ 7 ]
[ 1 -1 ] [ y ] = [ 1 ]

3.2 线性方程组的解

  • 解: 满足线性方程组中所有方程的一组未知数的值。
  • 解的情况:
    • 唯一解: 方程组有且仅有一组解。
    • 无穷多解: 方程组有无限多组解。
    • 无解: 方程组没有解。

3.3 高斯消元法 (Gaussian Elimination)

  • 高斯消元法: 一种求解线性方程组的常用方法。通过一系列的初等行变换,将增广矩阵化为行阶梯形矩阵或行最简形矩阵,从而求出方程组的解。
  • 增广矩阵: 将系数矩阵 A 和常数项向量 b 合并成一个矩阵 [A | b]。
  • 初等行变换:
    1. 交换两行的位置。
    2. 将某一行乘以一个非零常数。
    3. 将某一行的倍数加到另一行上。
  • 行阶梯形矩阵 (Row Echelon Form):
    1. 每一行的第一个非零元素 (称为主元) 必须是 1。
    2. 主元所在列的下方元素必须都为 0。
    3. 非零行必须在零行上方。
  • 行最简形矩阵 (Reduced Row Echelon Form):
    1. 满足行阶梯形矩阵的所有条件。
    2. 主元所在列的上方元素也必须都为 0。

高斯消元法的步骤:

  1. 写出线性方程组的增广矩阵。
  2. 通过初等行变换,将增广矩阵化为行阶梯形矩阵。
  3. 如果行阶梯形矩阵中出现 [0 0 … 0 | b] (b ≠ 0) 的形式,则方程组无解。
  4. 否则,将行阶梯形矩阵化为行最简形矩阵。
  5. 从行最简形矩阵中读出方程组的解 (唯一解或无穷多解)。

代码示例 (Python - NumPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import numpy as np

# 线性方程组的增广矩阵
A = np.array([[2, 3, 7], [1, -1, 1]])

# 使用 NumPy 求解线性方程组 (如果 A 是方阵且可逆)
# x = np.linalg.solve(A[:, :-1], A[:, -1])
# print("解:", x)

# 手动实现高斯消元法 (简化版,仅适用于有唯一解的情况)
def gaussian_elimination(matrix):
rows, cols = matrix.shape
for i in range(rows):
# 将主元变为 1
pivot = matrix[i, i]
matrix[i, :] = matrix[i, :] / pivot

# 将主元所在列的下方元素变为 0
for j in range(i + 1, rows):
factor = matrix[j, i]
matrix[j, :] = matrix[j, :] - factor * matrix[i, :]
return matrix

# 求解
reduced_matrix = gaussian_elimination(A.astype(float)) #转为float类型
print("行阶梯形矩阵:\n", reduced_matrix)

# 回代求解
x = np.zeros(reduced_matrix.shape[0])
for i in range(reduced_matrix.shape[0] -1, -1, -1):
x[i] = reduced_matrix[i, -1]
for j in range(i+1, reduced_matrix.shape[0]):
x[i] -= reduced_matrix[i,j] * x[j]

print("解: ", x)

3.4 克拉默法则 (Cramer’s Rule)(选学)

  • 克莱姆法则/克拉默法则是一种利用行列式来求解线性方程组的方法。

    对于一个有 n 个方程和 n 个未知数的线性方程组,如果系数矩阵 A 的行列式不为零(|A| ≠ 0),那么方程组有唯一解,解可以通过以下公式给出:

    xi = |Ai| / |A|

    其中:
    xi 是第 i 个未知数。
    |A| 是系数矩阵 A 的行列式。
    |Ai| 是将系数矩阵 A 中第 i 列替换为常数项向量 b 后得到的矩阵的行列式。

线性方程组是线性代数中的一个重要概念,也是解决实际问题时经常遇到的问题。高斯消元法是一种通用的求解线性方程组的方法。


4. 特征值与特征向量

4.1 什么是特征值与特征向量?

  • 定义: 对于一个给定的方阵 A,如果存在一个非零向量 v 和一个标量 λ,使得:

    Av = λv

    那么:

    • λ 称为 A 的特征值 (Eigenvalue)。
    • v 称为 A 的对应于特征值 λ 的特征向量 (Eigenvector)。
  • 理解:

    • 特征向量是指经过矩阵 A 变换后,方向不变或只是反向(仍然在同一条直线上)的非零向量。
    • 特征值表示特征向量在变换中被缩放的比例。
      • 如果 λ > 0,则特征向量被拉伸。
      • 如果 λ < 0,则特征向量被拉伸并反向。
      • 如果 λ = 0,则特征向量被压缩到原点(但特征向量必须是非零向量,所以这通常意味着矩阵 A 不可逆)。
      • 如果 λ = 1, 则特征向量不被拉伸或者压缩

4.2 特征值与特征向量的计算

  1. 特征方程:

    • 从 Av = λv 出发,可以推导出:
    • Av - λv = 0
    • (A - λI)v = 0 (其中 I 是单位矩阵)
    • 为了使方程有非零解,矩阵 (A - λI) 必须是奇异的 (不可逆的),即它的行列式为 0:
    • det(A - λI) = 0
    • 这个方程称为 A 的特征方程 (Characteristic Equation)。
  2. 求解特征值:

    • 解特征方程 det(A - λI) = 0,得到 A 的所有特征值 λ。
  3. 求解特征向量:

    • 对于每个特征值 λ,将 λ 代入方程 (A - λI)v = 0,求解出对应的特征向量 v
    • 注意:特征向量不是唯一的,对于一个特征值,可以有无穷多个特征向量 (它们都在同一条直线上)。

举例:

求矩阵 A = [[2, 1], [1, 2]] 的特征值和特征向量。

  1. 特征方程:

    1
    det(A - λI) = det([[2-λ, 1], [1, 2-λ]]) = (2-λ)² - 1 = λ² - 4λ + 3 = 0
  2. 求解特征值:

    1
    2
    (λ - 1)(λ - 3) = 0
    λ₁ = 1, λ₂ = 3
  3. 求解特征向量:

    • 对于 λ₁ = 1:
      1
      (A - λ₁I)v = [[1, 1], [1, 1]] [x, y] = [0, 0]
      解得 x + y = 0,所以特征向量可以表示为 k₁[-1, 1] (k₁ ≠ 0)。
    • 对于 λ₂ = 3:
      1
      (A - λ₂I)v = [[-1, 1], [1, -1]] [x, y] = [0, 0]
      解得 x - y = 0,所以特征向量可以表示为 k₂[1, 1] (k₂ ≠ 0)。

4.3 特征值分解 (谱分解)

  • 如果一个矩阵有n个线性无关的特征向量,则可以将矩阵进行分解

代码示例 (Python - NumPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np

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

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

print("特征值:", eigenvalues) # 输出:[3. 1.]
print("特征向量:\n", eigenvectors)
# 输出:
# [[ 0.70710678 -0.70710678]
# [ 0.70710678 0.70710678]]
# 注意:NumPy 返回的特征向量是单位向量 (长度为 1)。

4.4. 特征值与特征向量的几何意义

  • 特征向量: 在线性变换中,特征向量是指那些方向保持不变(或只是反向)的向量。它们定义了变换的主要方向。

  • 特征值: 特征值表示了特征向量在变换中被拉伸或压缩的比例。

特征值和特征向量是线性代数中非常重要的概念,它们揭示了矩阵的内在性质。在深度学习中,特征值和特征向量被用于主成分分析 (PCA)、奇异值分解 (SVD) 等算法中。


5. 奇异值分解 (SVD)

5.1 什么是奇异值分解?

  • 定义: 奇异值分解 (Singular Value Decomposition, SVD) 是一种重要的矩阵分解方法,可以将任意一个 m × n 的矩阵 A 分解为三个矩阵的乘积:

    A = UΣVᵀ

    其中:

    • U 是一个 m × m 的正交矩阵 (UᵀU = I)。
    • Σ 是一个 m × n 的矩形对角矩阵,其对角线上的元素称为奇异值 (Singular Values),通常按从大到小的顺序排列 (σ₁ ≥ σ₂ ≥ … ≥ σᵣ > 0,其中 r 是矩阵 A 的秩)。
    • V 是一个 n × n 的正交矩阵 (VᵀV = I)。
    • Vᵀ 表示 V的转置矩阵
  • 与特征值分解的区别:

    • 特征值分解只适用于方阵。
    • SVD 适用于任意形状的矩阵。

理解 SVD:

  • SVD 可以看作是将一个线性变换分解为三个简单的变换:
    1. 旋转 (Vᵀ): 将原始空间中的向量旋转到一个新的坐标系中。
    2. 缩放 (Σ): 在新的坐标系中,沿着坐标轴进行缩放 (奇异值的大小表示缩放的程度)。
    3. 旋转 (U): 将缩放后的向量旋转到目标空间中。

5.2 SVD 的计算 (作为进阶,这里只简要介绍步骤,不深入推导)

  1. 计算 AᵀA 和 AAᵀ。
  2. 求 AᵀA 的特征值和特征向量:
    • AᵀA 的特征值就是奇异值的平方 (σᵢ²)。
    • AᵀA 的特征向量构成 V 的列向量。
  3. 求 AAᵀ 的特征值和特征向量:
    • AAᵀ 的特征值也是奇异值的平方 (σᵢ²)。
    • AAᵀ 的特征向量构成 U 的列向量。
  4. 求奇异值:
    • 奇异值 σᵢ = √(λᵢ),其中 λᵢ 是 AᵀA (或 AAᵀ) 的特征值。
  5. 构造 Σ:
    • 将奇异值按照从大到小的顺序排列在 Σ 的对角线上。

代码示例 (Python - NumPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np

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

# 奇异值分解
U, S, V = np.linalg.svd(A)

print("U:\n", U)
print("S:\n", S) # NumPy 返回的是奇异值的一维数组
print("V:\n", V) # V 已经是转置后的矩阵

# 重构 A
Sigma = np.zeros(A.shape)
Sigma[:A.shape[0], :A.shape[0]] = np.diag(S) #如果A是MxN的矩阵,且M<N, 则用M
print("重构 A:\n", U @ Sigma @ V)

5.3 SVD 的应用

  • 数据压缩: 可以只保留较大的奇异值,从而实现数据的压缩。
  • 降维: 可以将高维数据投影到低维空间中 (主成分分析 PCA 的一种实现方式)。
  • 推荐系统: 可以用于发现用户和物品之间的潜在关系。
  • 图像处理: 可以用于图像去噪、图像压缩等。
  • 自然语言处理: 可以用于文本主题分析 (潜在语义分析 LSA)。

奇异值分解 (SVD) 是一种强大的矩阵分解方法,它在深度学习和许多其他领域都有广泛的应用。理解SVD的原理和应用,对于深入理解深度学习算法非常有帮助。


III. 微积分基础

微积分是深度学习的另一个重要数学支柱。深度学习模型的训练过程,本质上就是一个优化问题,而微积分是解决优化问题的有力工具。

我们从第一个小知识点开始:1. 导数

1.1 什么是导数?

  • 直观理解: 导数 (Derivative) 描述了一个函数在某一点上的瞬时变化率。

    • 想象一下你正在开车,你的速度表显示的就是你行驶距离关于时间的瞬时变化率 (导数)。
    • 如果函数图像是一条曲线,那么导数就是曲线在某一点上的切线的斜率。
  • 数学定义:
    设函数 y = f(x) 在点 x₀ 的某个邻域内有定义,如果极限

    1
    lim (Δx→0) [f(x₀ + Δx) - f(x₀)] / Δx

    存在,则称函数 f(x) 在点 x₀ 处可导,并称这个极限值为 f(x) 在点 x₀ 处的导数,记作 f’(x₀) 或 dy/dx |ₓ=ₓ₀。

    • Δx 表示 x 的变化量 (x₀ + Δx - x₀)。
    • Δy = f(x₀ + Δx) - f(x₀) 表示 y 的变化量。
    • Δy/Δx 表示平均变化率 (割线的斜率)。
    • 当 Δx 趋近于 0 时,平均变化率的极限就是瞬时变化率 (切线的斜率)。

1.2 导数的几何意义

  • 函数 y = f(x) 在点 x₀ 处的导数 f’(x₀) 就是曲线 y = f(x) 在点 (x₀, f(x₀)) 处的切线的斜率。

1.3 常见函数的导数

函数 (y = f(x)) 导数 (y’ = f’(x))
C (常数) 0
xⁿ (n ≠ 0) nxⁿ⁻¹
x 1
2x
3x²
1/x -1/x²
√x 1/(2√x)
aˣ ln(a)
logₐx 1 / (x ln(a))
ln x 1 / x
sin x cos x
cos x -sin x
tan x sec²x = 1 / cos²x

1.4 导数法则

  • 加法法则: (u(x) + v(x))’ = u’(x) + v’(x)
  • 减法法则: (u(x) - v(x))’ = u’(x) - v’(x)
  • 乘法法则: (u(x)v(x))’ = u’(x)v(x) + u(x)v’(x)
  • 除法法则: (u(x)/v(x))’ = [u’(x)v(x) - u(x)v’(x)] / v²(x) (v(x) ≠ 0)
  • 链式法则 (复合函数求导): 如果 y = f(u) 且 u = g(x),那么 dy/dx = dy/du * du/dx。
    • 例如:y = sin(x²),求 dy/dx。
      • 令 u = x²,则 y = sin(u)。
      • dy/du = cos(u),du/dx = 2x。
      • dy/dx = cos(u) * 2x = 2x cos(x²)。

代码示例 (Python - NumPy/SymPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import sympy as sp

# 使用 NumPy 计算数值导数 (近似)
def f(x):
return x**2

x = 2
h = 0.0001
numerical_derivative = (f(x + h) - f(x)) / h
print("数值导数:", numerical_derivative) # 输出:4.0001 (近似于 4)

# 使用 SymPy 计算符号导数
x_sym = sp.Symbol('x') # 定义符号变量
f_sym = x_sym**2 # 定义符号表达式
derivative = sp.diff(f_sym, x_sym) # 求导
print("符号导数:", derivative) # 输出:2*x
print("符号导数在 x=2 处的值:", derivative.subs(x_sym, 2)) # 输出:4

导数是微积分的核心概念之一,它描述了函数的变化率。理解导数的定义、几何意义、常见函数的导数以及导数法则,对于后续学习偏导数、梯度下降等概念至关重要。


2. 偏导数

2.1 什么是偏导数?

  • 背景: 在多元函数中 (例如 z = f(x, y),有两个或多个自变量),我们需要研究函数关于其中一个自变量的变化率,同时保持其他自变量不变。

  • 定义: 设函数 z = f(x, y) 在点 (x₀, y₀) 的某个邻域内有定义,如果极限

    1
    lim (Δx→0) [f(x₀ + Δx, y₀) - f(x₀, y₀)] / Δx

    存在,则称此极限值为函数 f(x, y) 在点 (x₀, y₀) 处关于 x 的偏导数 (Partial Derivative),记作 ∂z/∂x |(x₀, y₀) 或 ∂f/∂x |(x₀, y₀) 或 fₓ(x₀, y₀)。

    类似地,函数 f(x, y) 在点 (x₀, y₀) 处关于 y 的偏导数定义为:

    1
    lim (Δy→0) [f(x₀, y₀ + Δy) - f(x₀, y₀)] / Δy

    记作 ∂z/∂y |(x₀, y₀) 或 ∂f/∂y |(x₀, y₀) 或 fᵧ(x₀, y₀)。

  • 理解:

    • 偏导数就是在多元函数中,固定其他所有自变量,只考虑一个自变量变化时,函数的变化率。
    • ∂z/∂x 表示函数沿着 x 轴方向的变化率。
    • ∂z/∂y 表示函数沿着 y 轴方向的变化率。

2.2 偏导数的计算

  • 计算方法: 求偏导数时,只需将其他自变量视为常数,然后对目标自变量求导即可。

举例:

  1. 求函数 z = x² + 3xy + y² 关于 x 和 y 的偏导数。

    • ∂z/∂x = 2x + 3y (将 y 视为常数)
    • ∂z/∂y = 3x + 2y (将 x 视为常数)
  2. 求函数 f(x, y, z) = x²y + y²z + z²x 关于 x, y, z 的偏导数。

    • ∂f/∂x = 2xy + z²
    • ∂f/∂y = x² + 2yz
    • ∂f/∂z = y² + 2zx

2.3 梯度向量

  • 定义: 对于多元函数 f(x₁, x₂, …, xₙ),其所有偏导数组成的向量称为梯度向量 (Gradient Vector),记作 ∇f 或 grad f。

    ∇f = [∂f/∂x₁, ∂f/∂x₂, …, ∂f/∂xₙ]

  • 理解:

    • 梯度向量指向函数值增长最快的方向。
    • 梯度向量的模 (长度) 表示函数值增长的速率。

代码示例 (Python - SymPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import sympy as sp

# 定义符号变量
x, y = sp.symbols('x y')

# 定义函数
f = x**2 + 3*x*y + y**2

# 计算偏导数
df_dx = sp.diff(f, x)
df_dy = sp.diff(f, y)

print("∂f/∂x:", df_dx) # 输出:2*x + 3*y
print("∂f/∂y:", df_dy) # 输出:3*x + 2*y

# 计算梯度向量
gradient = [df_dx, df_dy]
print("梯度向量:", gradient) # 输出:[2*x + 3*y, 3*x + 2*y]

# 计算在某一点处的梯度
point = {x: 1, y: 2}
gradient_at_point = [g.subs(point) for g in gradient]
print("在点 (1, 2) 处的梯度:", gradient_at_point) # 输出:[8, 7]

2.4 方向导数

  • 定义: 方向导数表示函数沿着某个特定方向的变化率。
  • 理解: 偏导数是沿着坐标轴方向的特殊方向导数

2.5 全微分

  • 定义: 函数的所有自变量都发生微小变化时,函数值的总变化量。
  • 公式 对于二元函数z = f(x,y)
    dz = (∂f/∂x)dx + (∂f/∂y)dy

偏导数是多元函数中关于单个自变量的变化率。梯度向量由所有偏导数组成,指向函数值增长最快的方向。理解偏导数和梯度向量,对于后续学习梯度下降法等优化算法至关重要。


3. 梯度下降法

3.1 什么是梯度下降法?

  • 背景: 在深度学习中,我们经常需要找到一个函数的最小值 (例如损失函数)。梯度下降法 (Gradient Descent) 是一种常用的迭代优化算法,用于求解函数的局部最小值。

  • 原理:

    • 梯度向量指向函数值增长最快的方向,那么负梯度方向就是函数值下降最快的方向。
    • 梯度下降法沿着负梯度方向逐步迭代,不断逼近函数的局部最小值。
  • 形象比喻:

    • 想象你站在一座山上,想要下到山谷的最低点。
    • 你环顾四周,找到最陡峭的下坡方向 (负梯度方向)。
    • 你沿着这个方向迈出一小步。
    • 重复这个过程,直到你到达一个平坦的地方 (局部最小值)。

3.2 梯度下降法的步骤

  1. 初始化: 选择一个初始点 x₀ (可以随机选择)。
  2. 迭代: 重复以下步骤,直到满足停止条件:
    • 计算函数 f(x) 在当前点 xᵢ 的梯度 ∇f(xᵢ)。
    • 更新 xᵢ:xᵢ₊₁ = xᵢ - α∇f(xᵢ),其中 α 是学习率 (步长)。
  3. 停止条件:
    • 达到最大迭代次数。
    • 梯度向量的模 (长度) 小于某个阈值。
    • 函数值的变化小于某个阈值。

3.3 学习率 (步长)

  • 学习率 α: 一个小的正数,控制每次迭代的步长。
    • 学习率过大:可能导致震荡,无法收敛到最小值。
    • 学习率过小:收敛速度太慢,需要更多迭代次数。

3.4 局部最小值、全局最小值和鞍点

  • 局部最小值 (Local Minimum): 在某个邻域内,函数值最小的点。
  • 全局最小值 (Global Minimum): 在整个定义域内,函数值最小的点。
  • 鞍点 (Saddle Point): 梯度为零,但既不是局部最小值也不是局部最大值的点 (形状像马鞍)。
    • 梯度下降法可能会陷入局部最小值或鞍点。

代码示例 (Python - NumPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np
import matplotlib.pyplot as plt

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

# 计算梯度 (示例:f'(x) = 2x)
def gradient(x):
return 2 * x

# 梯度下降法
def gradient_descent(initial_x, learning_rate, num_iterations):
x = initial_x
x_history = [x] # 记录 x 的历史值
for i in range(num_iterations):
grad = gradient(x)
x = x - learning_rate * grad
x_history.append(x)
return x, x_history

# 设置参数
initial_x = 4 # 初始点
learning_rate = 0.1 # 学习率
num_iterations = 20 # 迭代次数

# 执行梯度下降
min_x, x_history = gradient_descent(initial_x, learning_rate, num_iterations)

print("最小值点:", min_x) # 输出:接近 0

# 可视化
x_values = np.linspace(-5, 5, 100)
y_values = f(x_values)

plt.plot(x_values, y_values)
plt.scatter(x_history, [f(x) for x in x_history], color='red')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Gradient Descent')
plt.show()

梯度下降法是一种常用的优化算法,用于求解函数的最小值。它沿着负梯度方向逐步迭代,不断逼近最小值。学习率的选择很重要,过大或过小都可能导致算法无法收敛或收敛速度过慢。梯度下降法可能会陷入局部最小值。

范例 1:一元函数的梯度下降

我们以一个简单的一元函数为例:f(x) = x² - 4x + 5

  1. 目标: 找到函数 f(x) 的最小值。

  2. 导数: f’(x) = 2x - 4

  3. 梯度下降:

    • 初始化:选择一个初始点 x₀,例如 x₀ = 5。
    • 学习率:设置学习率 α,例如 α = 0.1。
    • 迭代:
      • 计算梯度:f’(xᵢ) = 2xᵢ - 4
      • 更新 x:xᵢ₊₁ = xᵢ - αf’(xᵢ) = xᵢ - 0.1(2xᵢ - 4)
  4. Python 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    import numpy as np
    import matplotlib.pyplot as plt

    # 定义函数
    def f(x):
    return x**2 - 4*x + 5

    # 定义导数
    def gradient(x):
    return 2*x - 4

    # 梯度下降法
    def gradient_descent(initial_x, learning_rate, num_iterations):
    x = initial_x
    x_history = [x]
    for i in range(num_iterations):
    grad = gradient(x)
    x = x - learning_rate * grad
    x_history.append(x)
    return x, x_history

    # 设置参数
    initial_x = 5
    learning_rate = 0.1
    num_iterations = 20

    # 执行梯度下降
    min_x, x_history = gradient_descent(initial_x, learning_rate, num_iterations)

    print("最小值点:", min_x)

    # 可视化
    x_values = np.linspace(0, 6, 100)
    y_values = f(x_values)

    plt.plot(x_values, y_values)
    plt.scatter(x_history, [f(x) for x in x_history], color='red')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.title('Gradient Descent for f(x) = x² - 4x + 5')
    plt.show()

    运行这段代码,你会看到一个抛物线图形,红色的点表示梯度下降的迭代过程,最终红点会逐渐靠近抛物线的最低点 (x = 2)。

范例 2:二元函数的梯度下降

我们以一个二元函数为例:f(x, y) = x² + 2y²

  1. 目标: 找到函数 f(x, y) 的最小值。

  2. 偏导数:

    • ∂f/∂x = 2x
    • ∂f/∂y = 4y
  3. 梯度: ∇f(x, y) = [2x, 4y]

  4. 梯度下降:

    • 初始化:选择一个初始点 (x₀, y₀),例如 (x₀, y₀) = (2, 3)。
    • 学习率:设置学习率 α,例如 α = 0.1。
    • 迭代:
      • 计算梯度:∇f(xᵢ, yᵢ) = [2xᵢ, 4yᵢ]
      • 更新 x 和 y:
        • xᵢ₊₁ = xᵢ - α * 2xᵢ
        • yᵢ₊₁ = yᵢ - α * 4yᵢ
  5. Python 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D

    # 定义函数
    def f(x, y):
    return x**2 + 2*y**2

    # 定义梯度
    def gradient(x, y):
    return np.array([2*x, 4*y])

    # 梯度下降法
    def gradient_descent(initial_point, learning_rate, num_iterations):
    point = np.array(initial_point)
    point_history = [point]
    for i in range(num_iterations):
    grad = gradient(point[0], point[1])
    point = point - learning_rate * grad
    point_history.append(point)
    return point, np.array(point_history)

    # 设置参数
    initial_point = [2, 3]
    learning_rate = 0.1
    num_iterations = 30

    # 执行梯度下降
    min_point, point_history = gradient_descent(initial_point, learning_rate, num_iterations)

    print("最小值点:", min_point)

    # 可视化 (3D 图)
    x_values = np.linspace(-3, 3, 100)
    y_values = np.linspace(-3, 3, 100)
    X, Y = np.meshgrid(x_values, y_values)
    Z = f(X, Y)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
    ax.scatter(point_history[:, 0], point_history[:, 1], f(point_history[:, 0], point_history[:, 1]), color='red')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('f(x, y)')
    ax.set_title('Gradient Descent for f(x, y) = x² + 2y²')
    plt.show()

    运行这段代码,你会看到一个三维的碗状图形,红色的点表示梯度下降的迭代过程,最终红点会逐渐靠近碗底 (最小值点 (0, 0))。

范例 3:学习率的影响

我们修改范例 1 的代码,尝试不同的学习率,观察梯度下降的效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np
import matplotlib.pyplot as plt

# ... (函数 f(x) 和导数 gradient(x) 的定义与范例 1 相同) ...

# 梯度下降法 (添加学习率参数)
def gradient_descent(initial_x, learning_rate, num_iterations):
x = initial_x
x_history = [x]
for i in range(num_iterations):
grad = gradient(x)
x = x - learning_rate * grad
x_history.append(x)
return x, x_history

# 设置参数
initial_x = 5
num_iterations = 20

# 不同的学习率
learning_rates = [0.01, 0.1, 0.5, 1.1]

# 可视化
x_values = np.linspace(0, 6, 100)
y_values = f(x_values)

plt.figure(figsize=(10, 6))
plt.plot(x_values, y_values)

for lr in learning_rates:
min_x, x_history = gradient_descent(initial_x, lr, num_iterations)
plt.plot(x_history, [f(x) for x in x_history], marker='o', label=f'LR={lr}')

plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Effect of Learning Rate on Gradient Descent')
plt.legend()
plt.show()

运行这段代码:
学习率设置的比较小(0.01):收敛比较慢
学习率比较合适(0.1):能够正确的收敛
学习率有点大(0.5):收敛较快,但是会有一些震荡
学习率过大(1.1): 发散,不会收敛到正确的答案

通过这些范例,你可以更直观地理解梯度下降法的原理、步骤以及学习率的影响。在实际应用中,你需要根据具体的问题选择合适的学习率和迭代次数。


4. 泰勒展开

4.1 什么是泰勒展开?

  • 背景: 在数学中,我们经常需要用简单的函数 (如多项式函数) 来近似表示复杂的函数。泰勒展开 (Taylor Expansion) 提供了一种将函数表示为无穷级数 (多项式) 的方法。

  • 思想: 在某一点附近,用函数的多项式来逼近函数的值。

  • 泰勒公式 (Taylor’s Formula):
    设函数 f(x) 在包含 x₀ 的某个开区间 (a, b) 内具有 (n+1) 阶导数,则对于任意 x ∈ (a, b),有:

    1
    f(x) = f(x₀) + f'(x₀)(x - x₀) + f''(x₀)(x - x₀)²/2! + ... + f⁽ⁿ⁾(x₀)(x - x₀)ⁿ/n! + Rₙ(x)

    其中:

    • f’(x₀), f’’(x₀), …, f⁽ⁿ⁾(x₀) 分别表示 f(x) 在 x₀ 处的 1 阶、2 阶、…、n 阶导数。
    • n! 表示 n 的阶乘 (n! = 1 × 2 × 3 × … × n)。
    • Rₙ(x) 是余项 (Remainder),表示泰勒展开的误差。
      • 拉格朗日余项:Rₙ(x) = f⁽ⁿ⁺¹⁾(ξ)(x - x₀)ⁿ⁺¹/(n+1)!,其中 ξ 是介于 x₀ 和 x 之间的某个值。
      • 皮亚诺余项: Rₙ(x) = o((x - x₀)ⁿ)
  • 麦克劳林公式 (Maclaurin’s Formula): 当 x₀ = 0 时,泰勒公式称为麦克劳林公式:

    1
    f(x) = f(0) + f'(0)x + f''(0)x²/2! + ... + f⁽ⁿ⁾(0)xⁿ/n! + Rₙ(x)

4.2 一阶泰勒展开和二阶泰勒展开

  • 一阶泰勒展开 (线性近似):
    只保留泰勒公式的前两项:

    1
    f(x) ≈ f(x₀) + f'(x₀)(x - x₀)

    几何意义:用函数在点 x₀ 处的切线来近似函数的值。

  • 二阶泰勒展开 (二次近似):
    保留泰勒公式的前三项:

    1
    f(x) ≈ f(x₀) + f'(x₀)(x - x₀) + f''(x₀)(x - x₀)²/2!

    几何意义:用函数在点 x₀ 处的抛物线来近似函数的值。

4.3 泰勒展开的应用

  • 近似计算: 可以用泰勒展开来计算函数的近似值,特别是当 x 接近 x₀ 时。
  • 优化: 在优化算法中,可以用泰勒展开来近似目标函数,从而简化优化问题 (例如牛顿法)。
  • 物理学: 在物理学中,泰勒展开被广泛用于近似各种物理量。

代码示例 (Python - SymPy):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sympy as sp

# 定义符号变量
x = sp.Symbol('x')

# 定义函数 (示例:e^x)
f = sp.exp(x)

# 计算泰勒展开 (在 x=0 处展开到 5 阶)
taylor_expansion = f.series(x, 0, 5)

print("泰勒展开:", taylor_expansion)
# 输出:1 + x + x**2/2 + x**3/6 + x**4/24 + O(x**5)

# 计算 e^0.1 的近似值 (使用泰勒展开)
x0 = 0
approx_value = taylor_expansion.subs(x, 0.1).n() # .n() 将结果转换为数值
print("e^0.1 的近似值:", approx_value)

# 计算 e^0.1 的真实值
true_value = sp.exp(0.1).n()
print("e^0.1 的真实值:", true_value)

泰勒展开是一种将函数表示为多项式的方法,可以用于近似计算、优化等。一阶泰勒展开是用切线近似函数,二阶泰勒展开是用抛物线近似函数。

范例 1: eˣ 的泰勒展开

  1. 函数: f(x) = eˣ

  2. 麦克劳林展开 (在 x = 0 处展开):

    1
    eˣ = 1 + x + x²/2! + x³/3! + x⁴/4! + ...
  3. Python 代码 (使用 SymPy):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    import sympy as sp
    import numpy as np
    import matplotlib.pyplot as plt

    # 定义符号变量
    x = sp.Symbol('x')

    # 定义函数
    f = sp.exp(x)

    # 计算不同阶数的泰勒展开
    taylor_1 = f.series(x, 0, 1) # 1 阶
    taylor_3 = f.series(x, 0, 3) # 3 阶
    taylor_5 = f.series(x, 0, 5) # 5 阶

    print("1 阶泰勒展开:", taylor_1)
    print("3 阶泰勒展开:", taylor_3)
    print("5 阶泰勒展开:", taylor_5)

    # 可视化
    x_values = np.linspace(-2, 2, 400)
    f_values = [f.subs(x, val).n() for val in x_values] # 真实值
    t1_values = [taylor_1.subs(x, val).n() for val in x_values] # 1 阶
    t3_values = [taylor_3.subs(x, val).n() for val in x_values] # 3 阶
    t5_values = [taylor_5.subs(x, val).n() for val in x_values] # 5 阶

    plt.figure(figsize=(10, 6))
    plt.plot(x_values, f_values, label='eˣ')
    plt.plot(x_values, t1_values, label='1st Order')
    plt.plot(x_values, t3_values, label='3rd Order')
    plt.plot(x_values, t5_values, label='5th Order')
    plt.ylim(-1, 8) # 设置 y 轴范围
    plt.legend()
    plt.title('Taylor Expansion of eˣ')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.grid(True)
    plt.show()

    运行这段代码,你会看到 eˣ 的图像以及不同阶数泰勒展开的图像。在 x = 0 附近,高阶泰勒展开与原函数的拟合程度更好。

范例 2:sin(x) 的泰勒展开

  1. 函数: f(x) = sin(x)

  2. 麦克劳林展开 (在 x = 0 处展开):

    1
    sin(x) = x - x³/3! + x⁵/5! - x⁷/7! + ...
  3. Python 代码 (使用 SymPy):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    import sympy as sp
    import numpy as np
    import matplotlib.pyplot as plt

    # 定义符号变量
    x = sp.Symbol('x')

    # 定义函数
    f = sp.sin(x)

    # 计算不同阶数的泰勒展开
    taylor_1 = f.series(x, 0, 2) # 1 阶 (注意:sin(x) 的 1 阶和 2 阶展开相同)
    taylor_3 = f.series(x, 0, 4) # 3 阶
    taylor_5 = f.series(x, 0, 6) # 5 阶

    print("1 阶泰勒展开:", taylor_1)
    print("3 阶泰勒展开:", taylor_3)
    print("5 阶泰勒展开:", taylor_5)

    # 可视化
    x_values = np.linspace(-2*np.pi, 2*np.pi, 400)
    f_values = [f.subs(x, val).n() for val in x_values] # 真实值
    t1_values = [taylor_1.subs(x, val).n() for val in x_values] # 1 阶
    t3_values = [taylor_3.subs(x, val).n() for val in x_values] # 3 阶
    t5_values = [taylor_5.subs(x, val).n() for val in x_values] # 5 阶

    plt.figure(figsize=(10, 6))
    plt.plot(x_values, f_values, label='sin(x)')
    plt.plot(x_values, t1_values, label='1st Order')
    plt.plot(x_values, t3_values, label='3rd Order')
    plt.plot(x_values, t5_values, label='5th Order')
    plt.ylim(-2, 2)
    plt.legend()
    plt.title('Taylor Expansion of sin(x)')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.grid(True)
    plt.show()

    运行这段代码,你会看到 sin(x) 的图像以及不同阶数泰勒展开的图像。在 x = 0 附近,高阶泰勒展开与原函数的拟合程度更好。随着远离展开点,误差会逐渐增大。

范例3. 一元二次函数进行泰勒展开

以 f(x) = x² + 2x + 1, 在x=1处进行泰勒展开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt

# 定义符号变量
x = sp.Symbol('x')
# 定义函数
f = x**2 + 2*x +1

# 计算不同阶数的泰勒展开
x0 = 1
taylor_0 = f.series(x, x0, 1) # 0 阶
taylor_1 = f.series(x, x0, 2) # 1 阶
taylor_2 = f.series(x, x0, 3) # 2 阶

print("0 阶泰勒展开:", taylor_0)
print("1 阶泰勒展开:", taylor_1)
print("2 阶泰勒展开:", taylor_2)

# 可视化
x_values = np.linspace(-2, 4, 400)
f_values = [f.subs(x, val).n() for val in x_values] # 真实值
t0_values = [taylor_0.subs(x, val).n() for val in x_values] # 1 阶
t1_values = [taylor_1.subs(x, val).n() for val in x_values] # 3 阶
t2_values = [taylor_2.subs(x, val).n() for val in x_values] # 5 阶

plt.figure(figsize=(10, 6))
plt.plot(x_values, f_values, label='f(x)')
plt.plot(x_values, t0_values, label='0st Order')
plt.plot(x_values, t1_values, label='1st Order')
plt.plot(x_values, t2_values, label='2nd Order')
plt.ylim(-1, 8) # 设置 y 轴范围
plt.legend()
plt.title('Taylor Expansion of f(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.show()

可以看到对于2次函数, 其二阶泰勒展开和原函数是完全相同的

通过这些范例,你可以看到泰勒展开是如何用多项式来逼近函数的,以及展开的阶数越高,在展开点附近逼近的效果越好。


好的,我们继续学习微积分的下一个知识点:凸优化 (选学)

5. 凸优化 (Convex Optimization)

5.1 为什么学习凸优化?

  • 在深度学习中,许多优化问题被设计为凸优化问题,因为凸优化问题具有良好的性质:局部最优解就是全局最优解。这使得优化算法更容易找到全局最优解,而不用担心陷入局部最优解。

5.2 凸集 (Convex Set)

  • 定义: 在一个集合中,如果任意两点之间的连线上的所有点都属于这个集合,那么这个集合就是凸集。

  • 数学表达: 对于集合 C 中的任意两点 x₁ 和 x₂,以及任意 θ ∈ [0, 1],如果 θx₁ + (1 - θ)x₂ ∈ C,那么集合 C 是凸集。

  • 直观理解: 凸集没有“凹陷”的部分。

  • 常见凸集:

    • 直线
    • 线段
    • 平面
    • 球体
    • 多面体
  • 非凸集

    • 存在“凹陷”的部分

5.3 凸函数 (Convex Function)

  • 定义: 如果一个函数的定义域是凸集,并且对于定义域中的任意两点 x₁ 和 x₂,以及任意 θ ∈ [0, 1],满足:

    f(θx₁ + (1 - θ)x₂) ≤ θf(x₁) + (1 - θ)f(x₂)

    那么这个函数就是凸函数。

  • 几何意义: 函数图像上任意两点之间的连线 (弦) 位于函数图像的上方或与其重合。

  • 直观理解: 凸函数像一个“碗”的形状,没有“波峰”。

  • 常见凸函数:

    • 线性函数 (f(x) = ax + b)
    • 二次函数 (f(x) = ax² + bx + c,其中 a ≥ 0)
    • 指数函数 (f(x) = eˣ)
    • 负对数函数 (f(x) = -log(x))
    • 范数函数 (f(x) = ||x||)
  • 严格凸函数 (Strictly Convex Function):
    如果对于定义域中的任意两点 x₁ 和 x₂ (x₁ ≠ x₂),以及任意 θ ∈ (0, 1),满足:

    f(θx₁ + (1 - θ)x₂) < θf(x₁) + (1 - θ)f(x₂)

    那么这个函数就是严格凸函数。

5.4 凸优化问题

  • 定义: 在一个凸集上,最小化一个凸函数的问题,称为凸优化问题。

  • 标准形式:

    1
    2
    minimize  f(x)
    subject to x ∈ C

    其中:

    • f(x) 是凸函数。
    • C 是凸集。
  • 性质: 凸优化问题的任何局部最优解都是全局最优解。

5.5 凸性判断

  • 一阶条件: 对于可微函数 f(x),如果其定义域是凸集,且对于定义域中的任意两点 x 和 y,满足:

    f(y) ≥ f(x) + ∇f(x)ᵀ(y - x)

    那么 f(x) 是凸函数。

  • 二阶条件: 对于二次可微函数 f(x),如果其定义域是凸集,且其 Hessian 矩阵 (二阶偏导数矩阵) 是半正定的,那么 f(x) 是凸函数。

凸优化问题具有良好的性质:局部最优解就是全局最优解。这使得凸优化问题在深度学习中非常重要。了解凸集、凸函数和凸优化问题的定义,以及凸性的判断方法,有助于你更好地理解深度学习中的优化算法。

范例 1:凸集和非凸集

  1. 图形示例:

        graph LR
        subgraph Convex Sets
            A(圆形)
            B(正方形)
            C(三角形)
            D(线段)
        end
    
        subgraph Non-convex Sets
            E(星形)
            F(环形)
            G(凹多边形)
        end
    
        A --> |任意两点连线仍在集合内| H(凸集)
        B --> |任意两点连线仍在集合内| H
        C --> |任意两点连线仍在集合内| H
        D --> |任意两点连线仍在集合内| H
    
        E --> |存在两点连线不在集合内| I(非凸集)
        F --> |存在两点连线不在集合内| I
        G --> |存在两点连线不在集合内| I
  2. 代码示例 (判断点是否在集合内):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    import numpy as np
    import matplotlib.pyplot as plt

    # 凸集示例:圆形
    def is_in_circle(point, center, radius):
    return np.linalg.norm(np.array(point) - np.array(center)) <= radius

    # 非凸集示例:星形 (简化版)
    def is_in_star(point):
    x, y = point
    if -1 <= x <= 1 and -0.2 <= y <= 0.2:
    return True
    if -0.2 <= x <= 0.2 and -1 <= y <= 1:
    return True
    return False

    # 测试点
    point1 = (0.5, 0.5) # 圆内
    point2 = (2, 2) # 圆外
    point3 = (0.5, 0.5) # 星形内
    point4 = (1.5, 1.5) # 星形外

    # 判断
    print(f"点 {point1} 是否在圆形内: {is_in_circle(point1, (0, 0), 1)}")
    print(f"点 {point2} 是否在圆形内: {is_in_circle(point2, (0, 0), 1)}")
    print(f"点 {point3} 是否在星形内: {is_in_star(point3)}")
    print(f"点 {point4} 是否在星形内: {is_in_star(point4)}")

    # 可视化 (圆形)
    circle = plt.Circle((0, 0), 1, color='blue', alpha=0.5)
    fig, ax = plt.subplots()
    ax.add_patch(circle)
    ax.scatter(*point1, color='green', label='In Circle')
    ax.scatter(*point2, color='red', label='Out of Circle')
    ax.set_aspect('equal', adjustable='box')
    plt.xlim(-2, 2)
    plt.ylim(-2, 2)
    plt.legend()
    plt.title('Convex Set: Circle')
    plt.grid(True)
    plt.show()

范例 2:凸函数和非凸函数

  1. 图形示例:

用mermaid代码表示如下:

    graph LR
subgraph 凸函数
A(y = x^2)
B(y = e^x)
C(y = |x|)
A -->|弦在图像上方|D(凸函数性质)
B -->|弦在图像上方|D
C -->|弦在图像上方|D
end

subgraph 非凸函数
    E(y = x^3)
    F(y = sin(x))
    E -->|存在弦在图像下方|G(非凸函数)
    F -->|存在弦在图像下方|G
end</pre>
  1. 代码示例 (判断凸性 - 利用二阶导数):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    import sympy as sp

    # 定义符号变量
    x = sp.Symbol('x')

    # 凸函数示例:f(x) = x²
    f1 = x**2
    f1_second_derivative = sp.diff(f1, x, 2) # 求二阶导数
    print(f"f1(x) = x² 的二阶导数: {f1_second_derivative}") # 输出:2 (恒大于 0,为凸函数)

    # 非凸函数示例:f(x) = x³
    f2 = x**3
    f2_second_derivative = sp.diff(f2, x, 2) # 求二阶导数
    print(f"f2(x) = x³ 的二阶导数: {f2_second_derivative}") # 输出:6*x (可正可负,非凸函数)

    # 可视化
    x_values = np.linspace(-2, 2, 400)
    f1_values = [f1.subs(x, val).n() for val in x_values]
    f2_values = [f2.subs(x, val).n() for val in x_values]

    plt.figure(figsize=(8, 6))
    plt.plot(x_values, f1_values, label='f(x) = x² (Convex)')
    plt.plot(x_values, f2_values, label='f(x) = x³ (Non-convex)')
    plt.legend()
    plt.title('Convex and Non-convex Functions')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.grid(True)
    plt.show()

范例 3:凸优化问题示例

  1. 问题: 在半径为 1 的圆内,找到距离原点最近的点。

  2. 数学表达:

    1
    2
    minimize  ||x||₂  (欧几里得范数)
    subject to x² + y² ≤ 1 (x = [x, y])
    • 目标函数:||x||₂ 是凸函数。
    • 约束条件:x² + y² ≤ 1 定义了一个凸集 (圆形区域)。
  3. 这是一个凸优化问题。 其全局最优解显然是原点 (0, 0)。

通过这些范例,你可以看到凸集和非凸集、凸函数和非凸函数的区别,以及凸优化问题的形式。在深度学习中,我们通常希望优化问题是凸的,因为这样可以保证找到全局最优解。


好的,我们进入下一个大的知识点:IV. 概率论与数理统计基础

概率论与数理统计是深度学习中非常重要的数学工具。深度学习模型很多时候是在处理不确定性,概率论提供了一套描述和量化不确定性的方法。数理统计则提供了从数据中学习和推断的方法。

我们从第一个小知识点开始:1. 随机事件与概率

1.1 随机事件

  • 随机试验 (Random Experiment):

    • 可以在相同条件下重复进行。
    • 每次试验的结果不止一个,且事先知道所有可能的结果。
    • 每次试验前不能确定会出现哪一个结果。
  • 样本空间 (Sample Space): 随机试验的所有可能结果组成的集合,通常用 Ω (大写 Omega) 表示。

  • 随机事件 (Random Event): 样本空间 Ω 的子集。

    • 基本事件 (Elementary Event): 由一个样本点组成的单点集。
    • 必然事件 (Certain Event): 样本空间 Ω 本身 (每次试验中必定发生的事件)。
    • 不可能事件 (Impossible Event): 空集 ∅ (每次试验中都不会发生的事件)。

举例:

  • 抛硬币:
    • 试验:抛一枚硬币,观察正面 (H) 还是反面 (T) 朝上。
    • 样本空间:Ω = {H, T}
    • 事件:
      • 出现正面:{H}
      • 出现反面:{T}
      • 必然事件:{H, T}
      • 不可能事件:∅
  • 掷骰子:
    • 试验:掷一颗骰子,观察出现的点数。
    • 样本空间:Ω = {1, 2, 3, 4, 5, 6}
    • 事件:
      • 出现偶数点:{2, 4, 6}
      • 出现奇数点:{1, 3, 5}
      • 点数大于 4:{5, 6}
      • 必然事件:{1, 2, 3, 4, 5, 6}
      • 不可能事件:∅

1.2 事件的关系与运算

  • 包含: 如果事件 A 发生必然导致事件 B 发生,则称事件 B 包含事件 A,记作 A ⊆ B 或 B ⊇ A。
  • 相等: 如果 A ⊆ B 且 B ⊆ A,则称事件 A 与事件 B 相等,记作 A = B。
  • 并 (和): 事件 A 或事件 B 至少有一个发生,称为事件 A 与事件 B 的并 (或和),记作 A ∪ B。
  • 交 (积): 事件 A 和事件 B 同时发生,称为事件 A 与事件 B 的交 (或积),记作 A ∩ B 或 AB。
  • 互斥 (互不相容): 如果事件 A 和事件 B 不能同时发生 (A ∩ B = ∅),则称事件 A 与事件 B 互斥。
  • 对立 (互逆): 如果事件 A 和事件 B 有且仅有一个发生 (A ∪ B = Ω 且 A ∩ B = ∅),则称事件 A 与事件 B 互为对立事件,A 的对立事件记作 A̅。
  • 差: 事件 A 发生但事件 B 不发生,称为事件 A 与事件 B 的差,记作 A - B。

1.3 概率

  • 概率的定义:

    • 古典定义 (Classical Definition): 如果一个随机试验满足:

      1. 样本空间 Ω 中只有有限个样本点。
      2. 每个样本点发生的可能性相等。

      则事件 A 的概率定义为:P(A) = A 中包含的样本点数 / Ω 中包含的样本点数

      • 例如:掷骰子,出现偶数点的概率 P({2, 4, 6}) = 3/6 = 1/2
    • 几何定义 (Geometric Definition): 如果一个随机试验满足:

      1. 样本空间 Ω 是一个可以度量的几何区域 (如长度、面积、体积)。
      2. 每个样本点落入 Ω 中任何一个可度量的子区域的可能性与该子区域的度量成正比,而与该子区域的位置和形状无关。

      则事件 A 的概率定义为:P(A) = A 的度量 / Ω 的度量

      • 例如:向一个圆形靶子上射击,击中靶心 (一个小圆形区域) 的概率与靶心区域的面积成正比。
    • 频率定义 (Frequency Definition): 在相同的条件下,重复进行 n 次试验,事件 A 发生的次数 m 称为事件 A 的频数,m/n 称为事件 A 的频率。当 n 足够大时,频率 m/n 会稳定在一个常数附近,这个常数就认为是事件 A 的概率。

    • 公理化定义 (Axiomatic Definition): 设 Ω 是一个样本空间,如果对于 Ω 中的每一个事件 A,都赋予一个实数 P(A),满足以下三个条件:

      1. 非负性: 对于任意事件 A,P(A) ≥ 0。
      2. 规范性: P(Ω) = 1。
      3. 可列可加性: 对于两两互斥的事件 A₁, A₂, A₃, ...,P(A₁ ∪ A₂ ∪ A₃ ∪ ...) = P(A₁) + P(A₂) + P(A₃) + ...

      则称 P(A) 为事件 A 的概率。

  • 概率的性质:

    • 0 ≤ P(A) ≤ 1
    • P(∅) = 0
    • P(A̅) = 1 - P(A)
    • 如果 A ⊆ B,则 P(B - A) = P(B) - P(A)
    • P(A ∪ B) = P(A) + P(B) - P(A ∩ B)

随机事件是样本空间的子集。概率是用来度量随机事件发生可能性的数值。理解随机事件、样本空间、事件的关系与运算,以及概率的不同定义和性质,是学习概率论的基础。

范例 1:抛硬币

  1. 试验: 抛一枚均匀的硬币两次,观察正面 (H) 和反面 (T) 出现的情况。

  2. 样本空间: Ω = {HH, HT, TH, TT}

  3. 事件:

    • A: 至少出现一次正面 = {HH, HT, TH}
    • B: 两次都是正面 = {HH}
    • C: 两次都是反面 = {TT}
    • D: 一次正面一次反面 = {HT, TH}
  4. 概率 (古典概型):

    • P(A) = 3/4
    • P(B) = 1/4
    • P(C) = 1/4
    • P(D) = 2/4 = 1/2
  5. Python 代码 (模拟):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import random

    # 模拟抛硬币
    def toss_coin():
    return random.choice(['H', 'T'])

    # 模拟抛硬币两次
    def toss_coin_twice():
    return [toss_coin(), toss_coin()]

    # 模拟多次试验
    num_trials = 10000
    outcomes = []
    for _ in range(num_trials):
    outcomes.append(toss_coin_twice())

    # 计算事件发生的频率
    count_A = 0 # 至少一次正面
    count_B = 0 # 两次都是正面
    count_C = 0 # 两次都是反面
    count_D = 0 # 一次正面一次反面

    for outcome in outcomes:
    if 'H' in outcome:
    count_A += 1
    if outcome == ['H', 'H']:
    count_B += 1
    if outcome == ['T', 'T']:
    count_C += 1
    if outcome == ['H', 'T'] or outcome == ['T', 'H']:
    count_D += 1

    # 输出频率 (近似概率)
    print(f"至少一次正面的频率: {count_A / num_trials}")
    print(f"两次都是正面的频率: {count_B / num_trials}")
    print(f"两次都是反面的频率: {count_C / num_trials}")
    print(f"一次正面一次反面的频率: {count_D / num_trials}")

    运行这段代码,你会发现频率会接近上面计算的概率。

范例 2:掷骰子

  1. 试验: 掷一颗均匀的骰子,观察出现的点数。

  2. 样本空间: Ω = {1, 2, 3, 4, 5, 6}

  3. 事件:

    • A: 出现偶数点 = {2, 4, 6}
    • B: 出现奇数点 = {1, 3, 5}
    • C: 点数大于 4 = {5, 6}
  4. 概率 (古典概型):

    • P(A) = 3/6 = 1/2
    • P(B) = 3/6 = 1/2
    • P(C) = 2/6 = 1/3
  5. Python 代码 (模拟):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import random

# 模拟掷骰子
def roll_dice():
return random.randint(1, 6)

# 模拟多次试验
num_trials = 10000
outcomes = []
for _ in range(num_trials):
outcomes.append(roll_dice())

# 计算事件发生的频率
count_A = 0 # 偶数点
count_B = 0 # 奇数点
count_C = 0 # 点数大于 4

for outcome in outcomes:
if outcome in [2, 4, 6]:
count_A += 1
if outcome in [1, 3, 5]:
count_B += 1
if outcome in [5, 6]:
count_C += 1

# 输出频率 (近似概率)
print(f"偶数点的频率: {count_A / num_trials}")
print(f"奇数点的频率: {count_B / num_trials}")
print(f"点数大于 4 的频率: {count_C / num_trials}")

范例 3:事件的关系与运算
假设有一个样本空间 S = {1, 2, 3, 4, 5, 6},对应于掷一个六面骰子的可能结果。我们定义以下事件:

  • 事件 A:掷出偶数 {2, 4, 6}
  • 事件 B:掷出大于 3 的数 {4, 5, 6}

计算以下事件的概率
11. AUB
12. A ∩ B
13. A' (A的补集)

解答

  1. A ∪ B(A 或 B 发生):
    * A ∪ B = {2, 4, 6} ∪ {4, 5, 6} = {2, 4, 5, 6}
    * P(A ∪ B) = 4/6 =2/3

  2. A ∩ B(A 和 B 同时发生):
    * A ∩ B = {2, 4, 6} ∩ {4, 5, 6} = {4, 6}
    * P(A ∩ B) = 2/6=1/3

  3. A'(A 的补集,即 A 不发生):
    * A' = {1, 3, 5}
    * P(A') = 3/6=1/2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import numpy as np
# 定义样本空间
S = {1, 2, 3, 4, 5, 6}

# 定义事件 A 和 B
A = {2, 4, 6}
B = {4, 5, 6}

# 计算 A ∪ B
A_union_B = A.union(B)

# 计算 A ∩ B
A_intersect_B = A.intersection(B)

# 计算 A 的补集
A_complement = S - A

print("A ∪ B:", A_union_B)
print("A ∩ B:", A_intersect_B)
print("A':", A_complement)

# 模拟投骰子
def roll_dice():
return np.random.choice(list(S))

n=10000
#在n次实验中, 统计AUB, A∩B, A' 发生的次数
count_aub = 0
count_aib = 0
count_ac = 0

for _ in range(n):
r = roll_dice()
if r in A_union_B:
count_aub +=1
if r in A_intersect_B:
count_aib += 1
if r in A_complement:
count_ac += 1

print("P(AUB)=", count_aub/n)
print("P(A∩B)=", count_aib/n)
print("P(A')=", count_ac/n)

通过这些范例,你可以更直观地理解随机事件、样本空间、概率的概念,以及如何用 Python 进行简单的模拟和计算。


2. 条件概率

2.1 什么是条件概率?

  • 背景: 在许多情况下,我们需要知道在某个事件已经发生的条件下,另一个事件发生的概率。

  • 定义: 设 A 和 B 是两个事件,且 P(A) > 0,在事件 A 已经发生的条件下,事件 B 发生的概率称为条件概率 (Conditional Probability),记作 P(B|A)。

    1
    P(B|A) = P(A ∩ B) / P(A)

    其中:

    • P(A ∩ B) 表示事件 A 和事件 B 同时发生的概率。
    • P(A) 表示事件 A 发生的概率。
  • 理解:

    • 条件概率 P(B|A) 并不是 B 的概率,而是在 A 发生的前提下,B 的概率。
    • 条件概率 P(B|A) 改变了样本空间,将原本的样本空间 Ω 缩小为 A。

举例:

假设一个盒子里有 5 个球,其中 3 个是红球,2 个是白球。

  • 事件 A:第一次摸到红球。
  • 事件 B:第二次摸到红球。

如果不放回:

  • P(A) = 3/5
  • P(A ∩ B) = (3/5) * (2/4) = 3/10 (第一次摸到红球后,剩下 4 个球,其中 2 个是红球)
  • P(B|A) = P(A ∩ B) / P(A) = (3/10) / (3/5) = 1/2

如果放回:

  • P(A) = 3/5
  • P(A∩B) = (3/5)*(3/5) = 9/25
  • P(B|A) = P(A∩B)/P(A) = (9/25)/(3/5) = 3/5

2.2 条件概率的性质

  • 非负性:P(B|A) ≥ 0
  • 规范性:P(Ω|A) = 1
  • 可列可加性:如果 B₁, B₂, B₃, ... 是两两互斥的事件,则 P(B₁ ∪ B₂ ∪ B₃ ∪ ... | A) = P(B₁|A) + P(B₂|A) + P(B₃|A) + ...
  • P(B̅|A) = 1 - P(B|A)
  • 乘法公式:P(A ∩ B) = P(A)P(B|A) = P(B)P(A|B)

2.3 全概率公式

  • 背景: 有时我们需要计算一个事件 B 的概率,但是直接计算 P(B) 比较困难,而将 B 分解成若干个互斥事件的并集后,更容易计算。

  • 全概率公式 (Law of Total Probability):
    设事件 A₁, A₂, ..., Aₙ 是样本空间 Ω 的一个划分 (即 A₁, A₂, ..., Aₙ 两两互斥,且 A₁ ∪ A₂ ∪ ... ∪ Aₙ = Ω),且 P(Aᵢ) > 0,则对于任意事件 B,有:

    1
    P(B) = P(A₁)P(B|A₁) + P(A₂)P(B|A₂) + ... + P(Aₙ)P(B|Aₙ)

    或者

    1
    P(B) = ∑ P(Aᵢ)P(B|Aᵢ)
  • 理解:

    • 全概率公式将事件 B 的概率分解为在不同“原因” (Aᵢ) 下 B 发生的概率的加权平均。
    • 权重是每个“原因”发生的概率 P(Aᵢ)。

举例:

假设有两家工厂生产同一种产品,甲厂的产量占 60%,乙厂的产量占 40%。甲厂产品的合格率为 95%,乙厂产品的合格率为 90%。现在从这两种产品中随机抽取一件,求它是合格品的概率。

  • 事件 A₁:产品是甲厂生产的。
  • 事件 A₂:产品是乙厂生产的。
  • 事件 B:产品是合格品。

已知:

  • P(A₁) = 0.6
  • P(A₂) = 0.4
  • P(B|A₁) = 0.95
  • P(B|A₂) = 0.90

根据全概率公式:
P(B) = P(A₁)P(B|A₁) + P(A₂)P(B|A₂) = 0.6 * 0.95 + 0.4 * 0.90 = 0.93

2.4 贝叶斯公式

  • 背景: 贝叶斯公式 (Bayes' Theorem) 描述了在已知一些条件下,事件发生的概率是如何改变的。它将 P(B|A) 和 P(A|B) 联系起来。

  • 贝叶斯公式:
    设事件 A₁, A₂, ..., Aₙ 是样本空间 Ω 的一个划分,且 P(Aᵢ) > 0,P(B) > 0,则:

    1
    P(Aᵢ|B) = [P(Aᵢ)P(B|Aᵢ)] / P(B) =  [P(Aᵢ)P(B|Aᵢ)] / [∑ P(Aⱼ)P(B|Aⱼ)]
  • 理解:

    • P(Aᵢ|B) 是后验概率 (Posterior Probability),表示在观察到事件 B 发生后,事件 Aᵢ 发生的概率。
    • P(Aᵢ) 是先验概率 (Prior Probability),表示在没有观察到事件 B 时,事件 Aᵢ 发生的概率。
    • P(B|Aᵢ) 是似然函数 (Likelihood Function),表示在事件 Aᵢ 发生的条件下,事件 B 发生的概率。
    • P(B) 是证据 (Evidence),可以用全概率公式计算。
    • 贝叶斯公式可以看作是根据新的信息 (事件 B) 来更新我们对事件 Aᵢ 的概率的认识。

举例:
沿用全概率公式中的例子, 如果抽到一件产品是合格的,求它是甲厂生产的概率。

  • P(A₁|B) = [P(A₁)P(B|A₁)]/P(B) = [0.6*0.95]/0.93 = 0.613

条件概率是在某个事件已经发生的条件下,另一个事件发生的概率。全概率公式将一个事件的概率分解为在不同条件下发生的概率的加权平均。贝叶斯公式描述了在已知一些条件下,事件发生的概率是如何改变的。

范例 1:盒子摸球 (条件概率)

假设一个盒子里有 5 个红球和 3 个白球。

  1. 不放回摸球:

    • 事件 A:第一次摸到红球。 P(A) = 5/8
    • 事件 B:第二次摸到红球。
    • 求 P(B|A)。
    1
    2
    3
    4
    5
    # 计算 P(B|A)
    p_A = 5/8
    p_A_and_B = (5/8) * (4/7) # 第一次红球,第二次红球
    p_B_given_A = p_A_and_B / p_A
    print(f"不放回摸球,P(B|A) = {p_B_given_A}") # 输出:0.5714 (4/7)
  2. 放回摸球:

    • 事件 A:第一次摸到红球。 P(A) = 5/8
    • 事件 B:第二次摸到红球。
    • 求 P(B|A)。
    1
    2
    3
    4
    5
    # 计算 P(B|A)
    p_A = 5/8
    p_A_and_B = (5/8) * (5/8) # 第一次红球,第二次红球
    p_B_given_A = p_A_and_B / p_A
    print(f"放回摸球,P(B|A) = {p_B_given_A}") # 输出:0.625 (5/8)

范例 2:两家工厂生产的产品 (全概率公式和贝叶斯公式)

假设有两家工厂 (A 和 B) 生产同一种零件。A 厂生产 60% 的零件,B 厂生产 40% 的零件。A 厂的次品率为 2%,B 厂的次品率为 5%。

  1. 求任取一个零件是次品的概率 (全概率公式):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 已知条件
    p_A = 0.6 # A 厂生产的概率
    p_B = 0.4 # B 厂生产的概率
    p_defective_given_A = 0.02 # A 厂次品率
    p_defective_given_B = 0.05 # B 厂次品率

    # 全概率公式计算 P(defective)
    p_defective = p_A * p_defective_given_A + p_B * p_defective_given_B
    print(f"任取一个零件是次品的概率: {p_defective}") # 输出:0.032
  2. 如果取到一个零件是次品,求它是 A 厂生产的概率 (贝叶斯公式):

    1
    2
    3
    # 贝叶斯公式计算 P(A|defective)
    p_A_given_defective = (p_A * p_defective_given_A) / p_defective
    print(f"取到次品,是 A 厂生产的概率: {p_A_given_defective}") # 输出: 0.375

范例 3:疾病检测 (贝叶斯公式)

假设某种疾病的发病率为 0.1%。现在有一种检测方法,对于患病者,检测结果为阳性的概率为 99%;对于未患病者,检测结果为阳性的概率为 1% (假阳性)。

如果一个人的检测结果为阳性,求他实际患病的概率。

1
2
3
4
5
6
7
8
9
10
11
12
# 已知条件
p_disease = 0.001 # 发病率
p_positive_given_disease = 0.99 # 患病者检测阳性率
p_positive_given_no_disease = 0.01 # 未患病者检测阳性率

# 全概率公式计算 P(positive)
p_no_disease = 1 - p_disease
p_positive = p_disease * p_positive_given_disease + p_no_disease * p_positive_given_no_disease

# 贝叶斯公式计算 P(disease|positive)
p_disease_given_positive = (p_disease * p_positive_given_disease) / p_positive
print(f"检测结果阳性,实际患病的概率: {p_disease_given_positive}") # 输出:0.09016

结果分析:
尽管检测的准确性相当高(对于患病者有 99% 的阳性率,对于未患病者有 99% 的阴性率),但由于疾病的低发病率,即使检测结果为阳性,实际患病的概率也相对较低(大约 9.02%)。这是因为在大量检测中,假阳性的人数可能会超过真阳性的人数。

通过这些范例,你可以看到条件概率、全概率公式和贝叶斯公式在不同场景下的应用,以及如何用 Python 代码进行计算。这些概念在深度学习中非常重要,例如在朴素贝叶斯分类器、概率图模型等算法中都有应用。


好的,我们继续学习概率论与数理统计的下一个知识点:随机变量

3. 随机变量

3.1 什么是随机变量?

  • 定义: 随机变量 (Random Variable) 是一个变量,其取值依赖于随机试验的结果。

    • 更严格地说,随机变量是从样本空间 Ω 到实数集 R 的一个函数:X = X(ω), ω ∈ Ω。
    • 用大写字母表示随机变量,如 X, Y, Z。
    • 用小写字母表示随机变量的取值,如 x, y, z。
  • 理解:

    • 随机变量将随机试验的结果 (样本点) 映射为数值。
    • 随机变量的取值具有不确定性,但取每个值的概率是可以确定的。

举例:

  • 抛硬币:
    • 试验:抛一枚硬币两次。
    • 样本空间:Ω = {HH, HT, TH, TT}
    • 定义随机变量 X 为两次抛硬币中出现正面的次数。
      • X(HH) = 2
      • X(HT) = 1
      • X(TH) = 1
      • X(TT) = 0
      • X 的可能取值为 {0, 1, 2}
  • 掷骰子:
    • 试验:掷一颗骰子。
    • 样本空间:Ω = {1, 2, 3, 4, 5, 6}
    • 定义随机变量 Y 为掷骰子出现的点数。
      • Y(1) = 1, Y(2) = 2, ..., Y(6) = 6
      • Y 的可能取值为 {1, 2, 3, 4, 5, 6}
  • 灯泡寿命:
    • 试验:测试一个灯泡的寿命。
    • 样本空间:Ω = {t | t ≥ 0} (t 表示时间)
    • 定义随机变量 T 为灯泡的寿命。
      • T 的可能取值为所有非负实数。

3.2 随机变量的分类

  • 离散型随机变量 (Discrete Random Variable): 所有可能取值是有限个或可列无限个的随机变量。
    • 例如:抛硬币两次出现正面的次数、掷骰子出现的点数、一批产品中的次品数。
  • 连续型随机变量 (Continuous Random Variable): 所有可能取值充满一个区间 (或多个区间) 的随机变量。
    • 例如:灯泡的寿命、人的身高、温度。

3.3 离散型随机变量的概率分布

  • 概率分布列 (Probability Distribution): 描述离散型随机变量 X 的所有可能取值及其对应的概率。

    X x₁ x₂ ... xₙ ...
    P(X=xᵢ) p₁ p₂ ... pₙ ...

    其中:

    • pᵢ = P(X = xᵢ) ≥ 0
    • ∑pᵢ = 1
  • 常见离散型分布:

    • 伯努利分布 (Bernoulli Distribution) (0-1 分布):
      • 试验:只有两个可能结果 (成功或失败) 的试验。
      • 随机变量 X:如果成功,X = 1;如果失败,X = 0。
      • 概率分布:P(X = 1) = p, P(X = 0) = 1 - p (0 < p < 1)
    • 二项分布 (Binomial Distribution):
      • 试验:在相同条件下独立重复进行 n 次伯努利试验。
      • 随机变量 X:n 次试验中成功的次数。
      • 概率分布:P(X = k) = C(n, k) * pᵏ * (1 - p)ⁿ⁻ᵏ (k = 0, 1, 2, ..., n),其中 C(n, k) = n! / (k!(n-k)!) 是组合数。
    • 泊松分布 (Poisson Distribution):
      • 描述在一定时间或空间内,稀有事件发生的次数。
      • 概率分布:P(X = k) = (λᵏ * e⁻ˡᵃᵐᵇᵈᵃ) / k! (k = 0, 1, 2, ...),其中 λ > 0 是一个常数。

3.4 连续型随机变量的概率分布

  • 概率密度函数 (Probability Density Function, PDF):

    • 对于连续型随机变量 X,用一个函数 f(x) 来描述其概率分布。
    • f(x) 满足:
      • f(x) ≥ 0
      • ∫f(x)dx = 1 (积分区间为整个实数轴)
    • P(a ≤ X ≤ b) = ∫[a,b] f(x)dx (表示 X 取值在 a 和 b 之间的概率)
    • 注意:对于连续型随机变量,P(X = c) = 0 (c 是一个常数)。
  • 常见连续型分布:

    • 均匀分布 (Uniform Distribution):
      • 在区间 [a, b] 上,随机变量取任意值的概率相等。
      • 概率密度函数:f(x) = 1 / (b - a) (a ≤ x ≤ b), f(x) = 0 (其他)
    • 指数分布 (Exponential Distribution):
      • 描述独立随机事件发生的时间间隔。
      • 概率密度函数:f(x) = λe⁻ˡᵃᵐᵇᵈᵃˣ (x ≥ 0), f(x) = 0 (x < 0),其中 λ > 0 是一个常数。
    • 正态分布 (Normal Distribution) (高斯分布 Gaussian Distribution):
      • 一种非常常见的连续型分布,许多自然现象和社会现象都近似服从正态分布。
      • 概率密度函数:f(x) = (1 / (√(2π)σ)) * e^(-(x-μ)² / (2σ²)),其中 μ 是均值,σ 是标准差。

随机变量是将随机试验的结果映射为数值的变量。离散型随机变量的概率分布用概率分布列描述,连续型随机变量的概率分布用概率密度函数描述。

范例 1:离散型随机变量 - 抛硬币

  1. 试验: 抛一枚均匀的硬币三次。

  2. 随机变量 X: 出现正面的次数。

  3. 概率分布列:

    X 0 1 2 3
    P(X=x) 1/8 3/8 3/8 1/8
  4. Python 代码 (模拟和可视化):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import random
    import numpy as np
    import matplotlib.pyplot as plt

    # 模拟抛硬币三次
    def toss_coin_thrice():
    outcomes = []
    for _ in range(3):
    outcomes.append(random.choice(['H', 'T']))
    return outcomes

    # 计算出现正面的次数
    def count_heads(outcomes):
    count = 0
    for outcome in outcomes:
    if outcome == 'H':
    count += 1
    return count

    # 模拟多次试验
    num_trials = 10000
    results = []
    for _ in range(num_trials):
    outcomes = toss_coin_thrice()
    results.append(count_heads(outcomes))

    # 统计每个值的频率
    values, counts = np.unique(results, return_counts=True)
    frequencies = counts / num_trials

    # 可视化
    plt.bar(values, frequencies)
    plt.xlabel('Number of Heads (X)')
    plt.ylabel('Frequency (Approximate Probability)')
    plt.title('Probability Distribution of X (Number of Heads in 3 Tosses)')
    plt.xticks(values)
    plt.show()

    运行这段代码,你可以看到一个条形图,显示了抛硬币三次出现正面次数的概率分布(模拟结果)。

范例 2:连续型随机变量 - 指数分布

  1. 随机变量 X: 电子元件的寿命 (单位:小时)。

  2. 假设 X 服从指数分布,参数 λ = 0.001。

  3. 概率密度函数: f(x) = 0.001 * e^(-0.001x) (x ≥ 0)

  4. Python 代码 (可视化):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.stats import expon

    # 参数
    lambda_val = 0.001

    # 生成 x 值
    x = np.linspace(0, 5000, 500)

    # 计算概率密度函数
    pdf = expon.pdf(x, scale=1/lambda_val)

    # 可视化
    plt.plot(x, pdf)
    plt.xlabel('x (Hours)')
    plt.ylabel('Probability Density f(x)')
    plt.title('Exponential Distribution (λ = 0.001)')
    plt.grid(True)
    plt.show()

    # 计算 P(1000 ≤ X ≤ 2000)
    prob = expon.cdf(2000, scale=1/lambda_val) - expon.cdf(1000, scale=1/lambda_val)
    print(f"P(1000 ≤ X ≤ 2000) = {prob}")

    这段代码会绘制指数分布的概率密度函数图像,并计算 X 在 1000 到 2000 之间的概率。

范例 3:正态分布

  1. 随机变量 X: 某地区成年男性的身高 (单位:cm)。

  2. 假设 X 服从正态分布,均值 μ = 170,标准差 σ = 5。

  3. 概率密度函数: f(x) = (1 / (√(2π) * 5)) * e^(-(x-170)² / (2 * 5²))

  4. Python 代码 (可视化):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.stats import norm

    # 参数
    mu = 170
    sigma = 5

    # 生成 x 值
    x = np.linspace(150, 190, 100)

    # 计算概率密度函数
    pdf = norm.pdf(x, loc=mu, scale=sigma)

    # 可视化
    plt.plot(x, pdf)
    plt.xlabel('x (Height in cm)')
    plt.ylabel('Probability Density f(x)')
    plt.title('Normal Distribution (μ = 170, σ = 5)')
    plt.grid(True)
    plt.show()

    # 计算 P(165 ≤ X ≤ 175)
    prob = norm.cdf(175, loc=mu, scale=sigma) - norm.cdf(165, loc=mu, scale=sigma)
    print(f"P(165 ≤ X ≤ 175) = {prob}")

    这段代码会绘制出一个正态分布的概率密度函数,即我们常说的“钟形曲线”,并计算出身高在165cm到175cm之间的概率

通过这些范例,你可以看到离散型随机变量和连续型随机变量的概率分布是如何表示的,以及如何用 Python 进行模拟和可视化。


4. 随机变量的数字特征

4.1 期望 (均值)

  • 定义: 期望 (Expectation) 或均值 (Mean) 是随机变量取值的平均水平的度量。

  • 离散型随机变量:
    如果离散型随机变量 X 的概率分布列为 P(X = xᵢ) = pᵢ,则 X 的期望定义为:

    E(X) = ∑ xᵢpᵢ

  • 连续型随机变量:
    如果连续型随机变量 X 的概率密度函数为 f(x),则 X 的期望定义为:

    E(X) = ∫ xf(x) dx (积分区间为整个实数轴)

  • 理解:

    • 期望是随机变量所有可能取值的加权平均,权重是每个取值出现的概率。
    • 期望反映了随机变量的“中心”位置。
  • 性质:

    • E(c) = c (c 是常数)
    • E(cX) = cE(X) (c 是常数)
    • E(X + Y) = E(X) + E(Y) (X 和 Y 是任意两个随机变量)
    • 如果 X 和 Y 相互独立,则 E(XY) = E(X)E(Y)

4.2 方差

  • 定义: 方差 (Variance) 是随机变量取值与其期望的偏离程度的度量。

    Var(X) = E[(X - E(X))²]

  • 离散型随机变量:
    Var(X) = ∑ (xᵢ - E(X))²pᵢ

  • 连续型随机变量:
    Var(X) = ∫ (x - E(X))²f(x) dx

  • 理解:

    • 方差越大,随机变量的取值越分散。
    • 方差越小,随机变量的取值越集中在期望附近。
  • 性质:

    • Var(c) = 0 (c 是常数)
    • Var(cX) = c²Var(X) (c 是常数)
    • 如果 X 和 Y 相互独立,则 Var(X + Y) = Var(X) + Var(Y)
    • Var(X) = E(X²) - (E(X))²

4.3 标准差

  • 定义: 标准差 (Standard Deviation) 是方差的算术平方根。

    SD(X) = √Var(X)

  • 理解:

    • 标准差与随机变量具有相同的量纲,更直观地反映了随机变量取值的离散程度。

4.4 协方差

  • 定义: 协方差 (Covariance) 是衡量两个随机变量 X 和 Y 的线性相关程度的量。

    Cov(X, Y) = E[(X - E(X))(Y - E(Y))]

  • 理解:

    • Cov(X, Y) > 0:X 和 Y 正相关 (当 X 增大时,Y 也倾向于增大)。
    • Cov(X, Y) < 0:X 和 Y 负相关 (当 X 增大时,Y 倾向于减小)。
    • Cov(X, Y) = 0:X 和 Y 不线性相关 (但不一定独立)。
  • 性质:

    • Cov(X, X) = Var(X)
    • Cov(X, Y) = Cov(Y, X)
    • Cov(aX, bY) = abCov(X, Y) (a, b 是常数)
    • Cov(X + a, Y + b) = Cov(X, Y) (a, b 是常数)
    • Cov(X, Y) = E(XY) - E(X)E(Y)

4.5 相关系数

  • 定义: 相关系数 (Correlation Coefficient) 是衡量两个随机变量 X 和 Y 的线性相关程度的标准化量。

    ρ(X, Y) = Cov(X, Y) / (√Var(X) * √Var(Y))

  • 理解:

    • -1 ≤ ρ(X, Y) ≤ 1
    • ρ(X, Y) = 1:X 和 Y 完全正相关。
    • ρ(X, Y) = -1:X 和 Y 完全负相关。
    • ρ(X, Y) = 0:X 和 Y 不线性相关。
    • |ρ(X, Y)| 越接近 1,X 和 Y 的线性相关性越强。

期望、方差、标准差、协方差和相关系数是描述随机变量数字特征的重要概念。期望反映了随机变量的平均水平,方差和标准差反映了随机变量取值的离散程度,协方差和相关系数反映了两个随机变量之间的线性相关程度。

范例 1:离散型随机变量 - 抛硬币

  1. 试验: 抛一枚均匀的硬币三次。

  2. 随机变量 X: 出现正面的次数。

  3. 概率分布列:

    X 0 1 2 3
    P(X=x) 1/8 3/8 3/8 1/8
  4. 计算期望、方差和标准差:

    • E(X) = 0 * (1/8) + 1 * (3/8) + 2 * (3/8) + 3 * (1/8) = 1.5
    • Var(X) = (0 - 1.5)² * (1/8) + (1 - 1.5)² * (3/8) + (2 - 1.5)² * (3/8) + (3 - 1.5)² * (1/8) = 0.75
    • SD(X) = √Var(X) = √0.75 ≈ 0.866
  5. Python 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import numpy as np

    # 概率分布列
    x_values = np.array([0, 1, 2, 3])
    probabilities = np.array([1/8, 3/8, 3/8, 1/8])

    # 计算期望
    expected_value = np.sum(x_values * probabilities)
    print(f"E(X) = {expected_value}")

    # 计算方差
    variance = np.sum((x_values - expected_value)**2 * probabilities)
    print(f"Var(X) = {variance}")

    # 计算标准差
    standard_deviation = np.sqrt(variance)
    print(f"SD(X) = {standard_deviation}")

范例 2:连续型随机变量 - 指数分布

  1. 随机变量 X: 电子元件的寿命 (单位:小时)。

  2. 假设 X 服从指数分布,参数 λ = 0.001。

  3. 概率密度函数: f(x) = 0.001 * e^(-0.001x) (x ≥ 0)

  4. 计算期望、方差和标准差:

    • E(X) = 1/λ = 1/0.001 = 1000
    • Var(X) = 1/λ² = 1/0.001² = 1,000,000
    • SD(X) = √Var(X) = 1000
  5. Python 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from scipy.stats import expon

# 参数
lambda_val = 0.001

# 计算期望、方差和标准差
expected_value = expon.mean(scale=1/lambda_val)
variance = expon.var(scale=1/lambda_val)
standard_deviation = expon.std(scale=1/lambda_val)

print(f"E(X) = {expected_value}")
print(f"Var(X) = {variance}")
print(f"SD(X) = {standard_deviation}")

范例 3:正态分布

  1. 随机变量 X: 某地区成年男性的身高 (单位:cm)。

  2. 假设 X 服从正态分布,均值 μ = 170,标准差 σ = 5。

  3. Python 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import numpy as np
    from scipy.stats import norm

    # 参数
    mu = 170
    sigma = 5
    # 计算期望、方差和标准差
    expected_value = norm.mean(loc=mu, scale=sigma)
    variance = norm.var(loc=mu, scale=sigma)
    standard_deviation = norm.std(loc=mu, scale=sigma)

    print(f"E(X) = {expected_value}")
    print(f"Var(X) = {variance}")
    print(f"SD(X) = {standard_deviation}")

范例 4:协方差和相关系数

假设有两个随机变量 X 和 Y,它们的联合概率分布如下:

X\Y 1 2 3
1 0.1 0.2 0.1
2 0.1 0.1 0.4
  1. 计算 E(X), E(Y), Var(X), Var(Y), Cov(X, Y), ρ(X, Y)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np

# 联合概率分布
joint_prob = np.array([[0.1, 0.2, 0.1],
[0.1, 0.1, 0.4]])

# X 和 Y 的取值
x_values = np.array([1, 2])
y_values = np.array([1, 2, 3])

# 计算边际概率分布
prob_X = np.sum(joint_prob, axis=1)
prob_Y = np.sum(joint_prob, axis=0)

# 计算期望
E_X = np.sum(x_values * prob_X)
E_Y = np.sum(y_values * prob_Y)

print(f"E(X) = {E_X}") # 输出:1.6
print(f"E(Y) = {E_Y}") # 输出:2.2

# 计算方差
Var_X = np.sum((x_values - E_X)**2 * prob_X)
Var_Y = np.sum((y_values - E_Y)**2 * prob_Y)

print(f"Var(X) = {Var_X}") # 输出:0.24
print(f"Var(Y) = {Var_Y}") # 输出:0.56

# 计算协方差
Cov_XY = 0
for i in range(len(x_values)):
for j in range(len(y_values)):
Cov_XY += (x_values[i] - E_X) * (y_values[j] - E_Y) * joint_prob[i, j]

print(f"Cov(X, Y) = {Cov_XY}") # 输出:0.12

# 计算相关系数
Corr_XY = Cov_XY / (np.sqrt(Var_X) * np.sqrt(Var_Y))
print(f"ρ(X, Y) = {Corr_XY}") # 输出:0.3273

通过这些范例,你可以看到如何计算随机变量的期望、方差、标准差、协方差和相关系数,以及如何用 Python 代码来实现。这些数字特征是描述随机变量的重要工具。


5. 最大似然估计 (MLE)

5.1 什么是最大似然估计?

  • 背景: 在统计学中,我们经常需要根据一组观测数据来估计一个概率模型的参数。最大似然估计 (Maximum Likelihood Estimation, MLE) 是一种常用的参数估计方法。

  • 思想: 找到一组参数,使得在这组参数下,观测数据出现的概率最大。

  • “似然” (Likelihood) 的含义:

    • 似然函数 (Likelihood Function) 描述了在给定参数下,观测数据出现的可能性大小。
    • 似然函数与概率函数不同:
      • 概率函数:已知参数,求观测数据出现的概率。
      • 似然函数:已知观测数据,求参数的可能性大小。

5.2 最大似然估计的步骤

  1. 写出似然函数:

    • 假设我们有一组独立同分布的观测数据 x₁, x₂, ..., xₙ,它们来自一个概率模型,该模型的参数为 θ (可以是一个参数,也可以是一个参数向量)。

    • 似然函数 L(θ) 定义为:

      L(θ) = P(x₁, x₂, ..., xₙ | θ)

      由于观测数据是独立同分布的,因此:

      L(θ) = ∏ P(xᵢ | θ) (∏ 表示连乘)

      • 对于离散型随机变量:P(xᵢ | θ) 是概率分布列。
      • 对于连续型随机变量:P(xᵢ | θ) 是概率密度函数。
  2. 取对数:

    • 通常对似然函数取对数,得到对数似然函数 (Log-likelihood Function):

      l(θ) = log L(θ) = ∑ log P(xᵢ | θ)

    • 取对数的好处:

      • 将连乘变为连加,简化计算。
      • 对数函数是单调递增函数,不改变最大值点。
  3. 求导 (或偏导):

    • 对于连续型参数,通常对对数似然函数求导 (或偏导),并令导数 (或偏导数) 等于 0。

      ∂l(θ)/∂θ = 0

  4. 解方程 (或方程组):

    • 解上述方程 (或方程组),得到参数 θ 的估计值,记作 θ̂。
    • θ̂ 就是参数 θ 的最大似然估计。

5.3 举例

示例 1:伯努利分布

假设我们有一组独立同分布的伯努利试验结果 x₁, x₂, ..., xₙ,其中 xᵢ = 1 表示成功,xᵢ = 0 表示失败。我们要估计成功的概率 p。

  1. 似然函数:
    L(p) = ∏ pˣⁱ(1 - p)¹⁻ˣⁱ

  2. 对数似然函数:
    l(p) = ∑ [xᵢ log(p) + (1 - xᵢ) log(1 - p)]

  3. 求导:
    dl(p)/dp = ∑ [xᵢ/p - (1 - xᵢ)/(1 - p)]

  4. 解方程:
    令 dl(p)/dp = 0,解得:
    p̂ = (∑ xᵢ) / n (即样本中成功的比例)

示例 2:正态分布

假设我们有一组独立同分布的观测数据 x₁, x₂, ..., xₙ,它们来自一个正态分布 N(μ, σ²)。我们要估计均值 μ 和方差 σ²。

  1. 似然函数
    L(μ, σ²) = ∏ (1 / (√(2π)σ)) * e^(-(xᵢ-μ)² / (2σ²))

  2. 对数似然函数
    l(μ, σ²) = -n/2 * log(2π) - n/2 * log(σ²) - 1/(2σ²) * ∑(xᵢ - μ)²

  3. 求导:
    ∂l/∂μ = 1/σ² * ∑(xᵢ - μ)
    ∂l/∂σ² = -n/(2σ²) + 1/(2σ⁴) * ∑(xᵢ - μ)²

  4. 解方程:
    令偏导数为 0,解得:
    μ̂ = (∑ xᵢ) / n (样本均值)
    σ²̂ = (∑ (xᵢ - μ̂)²) / n (样本方差)

最大似然估计是一种常用的参数估计方法。它的基本思想是找到一组参数,使得在这组参数下,观测数据出现的概率最大。最大似然估计的步骤包括:写出似然函数、取对数、求导 (或偏导) 和解方程 (或方程组)。

范例 1:伯努利分布 (硬币投掷)

假设我们投掷一枚硬币 n 次,出现了 k 次正面。我们想用最大似然估计来估计硬币正面向上的概率 p。

  1. 模型: 伯努利分布 (Bernoulli Distribution)

    • P(X = 1) = p (正面)
    • P(X = 0) = 1 - p (反面)
  2. 数据: n 次投掷,k 次正面,n-k 次反面。

  3. 似然函数:
    L(p) = pᵏ(1 - p)ⁿ⁻ᵏ

  4. 对数似然函数:
    l(p) = k log(p) + (n - k) log(1 - p)

  5. 求导:
    dl(p)/dp = k/p - (n - k)/(1 - p)

  6. 解方程:
    令 dl(p)/dp = 0,解得:
    p̂ = k/n (样本中正面的比例)

  7. Python 代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import numpy as np

    # 模拟投硬币
    def toss_coin(n, p):
    return np.random.binomial(1, p, n) # 1 表示正面,0 表示反面

    # 真实概率 (用于模拟)
    true_p = 0.6

    # 投掷次数
    n = 100

    # 生成数据
    data = toss_coin(n, true_p)
    k = np.sum(data) # 正面次数

    # 最大似然估计
    estimated_p = k / n

    print(f"真实概率: {true_p}")
    print(f"投掷 {n} 次,正面 {k} 次")
    print(f"最大似然估计: {estimated_p}")

范例 2:正态分布 (身高)

假设我们有一组某地区成年男性的身高数据 (单位:cm),我们假设身高服从正态分布 N(μ, σ²)。我们想用最大似然估计来估计均值 μ 和方差 σ²。

  1. 模型: 正态分布 (Normal Distribution)

    • 概率密度函数:f(x) = (1 / (√(2π)σ)) * e^(-(x-μ)² / (2σ²))
  2. 数据: x₁, x₂, ..., xₙ

  3. 似然函数:
    L(μ, σ²) = ∏ (1 / (√(2π)σ)) * e^(-(xᵢ-μ)² / (2σ²))

  4. 对数似然函数:
    l(μ, σ²) = -n/2 * log(2π) - n/2 * log(σ²) - 1/(2σ²) * ∑(xᵢ - μ)²

  5. 求偏导:
    ∂l/∂μ = 1/σ² * ∑(xᵢ - μ)
    ∂l/∂σ² = -n/(2σ²) + 1/(2σ⁴) * ∑(xᵢ - μ)²

  6. 解方程组:
    令偏导数为 0,解得:
    μ̂ = (∑ xᵢ) / n (样本均值)
    σ²̂ = (∑ (xᵢ - μ̂)²) / n (样本方差)

  7. Python 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np

# 模拟生成数据 (正态分布)
def generate_data(n, mu, sigma):
return np.random.normal(mu, sigma, n)

# 真实参数
true_mu = 170
true_sigma = 5

# 样本数量
n = 1000

# 生成数据
data = generate_data(n, true_mu, true_sigma)

# 最大似然估计
estimated_mu = np.mean(data)
estimated_sigma2 = np.var(data)

print(f"真实均值: {true_mu}")
print(f"真实标准差: {true_sigma}")
print(f"样本数量: {n}")
print(f"估计均值: {estimated_mu}")
print(f"估计方差: {estimated_sigma2}")
print(f"估计标准差: {np.sqrt(estimated_sigma2)}")

通过这些范例,你可以看到如何针对不同的概率模型,使用最大似然估计来估计参数。最大似然估计是一种非常常用且有效的参数估计方法。


6. 信息熵与交叉熵

6.1 信息熵 (Entropy)

  • 定义: 信息熵 (Entropy) 是用来衡量随机变量不确定性的度量。

    • 熵越高,随机变量的不确定性越大。
    • 熵越低,随机变量的不确定性越小。
  • 公式:

    • 对于离散型随机变量 X,其概率分布列为 P(X = xᵢ) = pᵢ,则 X 的信息熵定义为:

      H(X) = -∑ pᵢ log₂(pᵢ) (通常以 2 为底,单位为比特 bits)
      = -∑ pᵢ log(pᵢ) (也可以用e为底,单位为奈特 nats)
      (规定:如果 pᵢ = 0,则 pᵢ log₂(pᵢ) = 0)

    • 对于连续型随机变量 X,其概率密度函数为 f(x),则 X 的信息熵定义为:

      H(X) = -∫ f(x) log₂(f(x)) dx

  • 理解:

    • 信息熵可以看作是“平均信息量”。
    • 如果一个事件发生的概率很小,那么它发生时带来的信息量就很大。
    • 如果一个事件发生的概率很大,那么它发生时带来的信息量就很小。
    • 信息熵就是所有可能事件的信息量的期望。
  • 性质:

    • H(X) ≥ 0
    • 当 X 服从均匀分布时,H(X) 最大。

举例:

  1. 抛硬币 (均匀):

    • X = {正面, 反面}
    • P(正面) = 1/2, P(反面) = 1/2
    • H(X) = - (1/2)log₂(1/2) - (1/2)log₂(1/2) = 1 比特
  2. 抛硬币 (不均匀):

    • X = {正面, 反面}
    • P(正面) = 0.8, P(反面) = 0.2
    • H(X) = - 0.8log₂(0.8) - 0.2log₂(0.2) ≈ 0.72 比特

6.2 交叉熵 (Cross Entropy)

  • 定义: 交叉熵 (Cross Entropy) 是用来衡量两个概率分布之间的差异的度量。

    • 假设我们有一个真实的概率分布 p(x) 和一个模型预测的概率分布 q(x)。
    • 交叉熵衡量的是用 q(x) 来编码 p(x) 的平均编码长度。
  • 公式:

    • 对于离散型随机变量:

      H(p, q) = -∑ p(x) log₂(q(x))

    • 对于连续型随机变量:

      H(p, q) = -∫ p(x) log₂(q(x)) dx

  • 理解:

    • 交叉熵越小,表示两个概率分布越接近。
    • 交叉熵越大,表示两个概率分布差异越大。
    • 交叉熵 H(p, q) ≥ H(p) (吉布斯不等式),当且仅当 p = q 时等号成立。

6.3 相对熵 (Kullback-Leibler Divergence, KL Divergence)

  • 定义: 相对熵 (Relative Entropy) 或 KL 散度 (Kullback-Leibler Divergence) 也是用来衡量两个概率分布之间的差异的度量。

  • 公式:

    • 对于离散型随机变量:

      D KL(p || q) = ∑ p(x) log₂(p(x) / q(x)) = H(p,q) - H(p)

    • 对于连续型随机变量:

      D KL(p || q) = ∫ p(x) log₂(p(x) / q(x)) dx = H(p,q) - H(p)

  • 理解:

    • KL 散度衡量的是用 q(x) 来近似 p(x) 时的信息损失。
    • KL 散度是非对称的:D KL(p || q) ≠ D KL(q || p)
    • KL 散度 ≥ 0,当且仅当 p = q 时等号成立。

6.4 在深度学习中的应用

  • 交叉熵作为损失函数: 在分类问题中,我们通常使用交叉熵作为损失函数。

    • 例如,在二分类问题中,真实标签 y ∈ {0, 1},模型预测的概率为 ŷ,则交叉熵损失为:

      Loss = -[y log(ŷ) + (1 - y) log(1 - ŷ)]

    • 在多分类问题中, 假设有 K 个类别, 真实标签 y 是一个 one-hot 向量 (只有一个元素为 1,其余为 0),模型预测的概率向量为 ŷ (每个元素表示属于该类别的概率, 所有元素之和为1)
      Loss = - ∑yᵢlog(ŷᵢ)

  • KL 散度用于衡量分布差异: 在生成模型 (如变分自编码器 VAE、生成对抗网络 GAN) 中,KL 散度可以用来衡量生成的分布与真实分布之间的差异。

信息熵衡量随机变量的不确定性。交叉熵和 KL 散度衡量两个概率分布之间的差异。在深度学习中,交叉熵常被用作分类问题的损失函数,KL 散度常被用于衡量分布差异。

范例 1:计算信息熵

假设有以下几个离散型随机变量的概率分布:

  1. 均匀分布: X = {A, B, C, D}, P(A) = P(B) = P(C) = P(D) = 1/4
  2. 非均匀分布 1: Y = {A, B, C, D}, P(A) = 1/2, P(B) = 1/4, P(C) = 1/8, P(D) = 1/8
  3. 非均匀分布 2: Z = {A, B, C, D}, P(A) = 0.9, P(B) = 0.05, P(C) = 0.025, P(D) = 0.025

计算这三个随机变量的信息熵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np

# 定义熵计算函数
def entropy(probabilities):
"""计算信息熵."""
entropy = 0
for p in probabilities:
if p > 0: # 避免 log(0) 错误
entropy -= p * np.log2(p)
return entropy

# 均匀分布
prob_X = [1/4, 1/4, 1/4, 1/4]
entropy_X = entropy(prob_X)
print(f"X (均匀分布) 的信息熵: {entropy_X}") # 输出:2.0

# 非均匀分布 1
prob_Y = [1/2, 1/4, 1/8, 1/8]
entropy_Y = entropy(prob_Y)
print(f"Y (非均匀分布 1) 的信息熵: {entropy_Y}") # 输出:1.75

# 非均匀分布 2
prob_Z = [0.9, 0.05, 0.025, 0.025]
entropy_Z = entropy(prob_Z)
print(f"Z (非均匀分布 2) 的信息熵: {entropy_Z}") # 输出:0.622

可以看到,均匀分布的熵最大,非均匀分布的熵较小,且分布越不均匀,熵越小。

范例 2:计算交叉熵

假设有两个概率分布:

  • 真实分布 p: p(A) = 0.5, p(B) = 0.3, p(C) = 0.2
  • 预测分布 q1: q1(A) = 0.6, q1(B) = 0.2, q1(C) = 0.2
  • 预测分布 q2: q2(A) = 0.8, q2(B) = 0.1, q2(C) = 0.1

计算 p 与 q1、p 与 q2 的交叉熵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np

# 定义交叉熵计算函数
def cross_entropy(p, q):
"""计算交叉熵."""
cross_entropy = 0
for i in range(len(p)):
if p[i] > 0:
cross_entropy -= p[i] * np.log2(q[i])
return cross_entropy

# 真实分布
p = [0.5, 0.3, 0.2]

# 预测分布 q1
q1 = [0.6, 0.2, 0.2]

# 预测分布 q2
q2 = [0.8, 0.1, 0.1]

# 计算交叉熵
H_p_q1 = cross_entropy(p, q1)
H_p_q2 = cross_entropy(p, q2)

print(f"H(p, q1) = {H_p_q1}") # 输出:1.826
print(f"H(p, q2) = {H_p_q2}") # 输出:2.039

计算结果表明,q1 比 q2 更接近真实分布 p。

范例 3:交叉熵损失 (二分类)

假设有一个二分类问题,真实标签为 y = 1,模型预测的概率为 ŷ。我们分别计算当 ŷ = 0.9, ŷ = 0.6, ŷ = 0.1 时,交叉熵损失是多少。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np

# 定义交叉熵损失函数 (二分类)
def cross_entropy_loss(y_true, y_pred):
"""计算二分类交叉熵损失."""
return -(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))

# 真实标签
y_true = 1

# 不同的预测概率
y_pred_1 = 0.9
y_pred_2 = 0.6
y_pred_3 = 0.1

# 计算交叉熵损失
loss_1 = cross_entropy_loss(y_true, y_pred_1)
loss_2 = cross_entropy_loss(y_true, y_pred_2)
loss_3 = cross_entropy_loss(y_true, y_pred_3)

print(f"当 ŷ = 0.9 时,交叉熵损失: {loss_1}") # 输出:0.105
print(f"当 ŷ = 0.6 时,交叉熵损失: {loss_2}") # 输出:0.510
print(f"当 ŷ = 0.1 时,交叉熵损失: {loss_3}") # 输出:2.302

结果展示出,预测概率越接近真实标签,交叉熵损失越小。

通过这些范例,你可以看到信息熵、交叉熵的计算方法,以及它们在不同场景下的应用。这些概念在深度学习中非常重要,尤其是在分类问题和生成模型中。


免责声明

本报告(“深度学习数学基础入门”)由[ViniJack.SJX] 根据公开可获得的信息以及作者的专业知识和经验撰写,旨在提供关于网络爬虫技术、相关框架和工具的分析和信息。

1. 信息准确性与完整性:

  • 作者已尽最大努力确保报告中信息的准确性和完整性,但不对其绝对准确性、完整性或及时性做出任何明示或暗示的保证。
  • 报告中的信息可能随时间推移而发生变化,作者不承担更新报告内容的义务。
  • 报告中引用的第三方信息(包括但不限于网站链接、项目描述、数据统计等)均来自公开渠道,作者不对其真实性、准确性或合法性负责。

2. 报告用途与责任限制:

  • 本报告仅供参考和学习之用,不构成任何形式的投资建议、技术建议、法律建议或其他专业建议。
  • 读者应自行判断和评估报告中的信息,并根据自身情况做出决策。
  • 对于因使用或依赖本报告中的信息而导致的任何直接或间接损失、损害或不利后果,作者不承担任何责任。

3. 技术使用与合规性:

  • 本报告中提及的任何爬虫框架、工具或技术,读者应自行负责其合法合规使用。
  • 在使用任何爬虫技术时,读者应遵守相关法律法规(包括但不限于数据隐私保护法、知识产权法、网络安全法等),尊重网站的服务条款和 robots 协议,不得侵犯他人合法权益。
  • 对于因读者违反相关法律法规或不当使用爬虫技术而导致的任何法律责任或纠纷,作者不承担任何责任。

4. 知识产权:

  • 本报告的版权归作者所有,未经作者书面许可,任何人不得以任何形式复制、传播、修改或使用本报告的全部或部分内容。
  • 报告中引用的第三方内容,其知识产权归原作者所有。

5. 其他:

  • 本报告可能包含对未来趋势的预测,这些预测基于作者的判断和假设,不构成任何形式的保证。
  • 作者保留随时修改本免责声明的权利。

请在使用本报告前仔细阅读并理解本免责声明。如果您不同意本免责声明的任何条款,请勿使用本报告。

作者

ViniJack.SJX

发布于

2025-02-20

更新于

2025-02-22

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.