系列回顾:前十篇我们把基础数学工具(符号、对数、函数、导数、链式法则)和线性代数(向量、矩阵、点积、高维空间、低秩分解)都打好了底。从这篇开始进入第三阶段:概率与统计。这一阶段是理解语言模型训练目标、强化学习奖励机制、以及 DeepSeek R1 的 GRPO 算法的关键。这篇从最基础的概率概念讲起,把每个概念讲透彻。
先说一个事实:语言模型本质上是一个概率模型。
DeepSeek V3 给你的每一个回答,不是确定性计算出来的,而是从一个概率分布里采样出来的。它在生成"今天天气不错"这句话时,实际上是:
整个生成过程就是一连串的随机采样。训练的目标,是让模型学到一个尽可能准确的概率分布——对于每个上下文,什么词最可能出现。
没有概率论,就没有语言模型的训练目标,没有强化学习的奖励信号,没有 GRPO 算法,没有 DeepSeek R1 的推理能力。概率论是这一切的基础语言。
概率是对"某件事发生的可能性"的数值描述,范围在 0 到 1 之间:
用数学符号写:$P(A)$ 表示事件 $A$ 发生的概率,$0 \leq P(A) \leq 1$。
概率有两种主要的解释方式,深度学习里两者都会用到:
频率学派(Frequentist):概率是长期频率。如果你抛硬币无数次,正面出现的次数除以总次数趋向于 0.5,所以正面的概率是 0.5。这个解释需要"可重复实验",适合描述客观的随机现象。
贝叶斯学派(Bayesian):概率是对不确定性的主观信念程度。即使是不可重复的事件,也可以有概率——"明天下雨的概率是 70%"是我根据现有信息对下雨这件事的信念程度。
DeepSeek R1 的强化学习训练里,贝叶斯视角更自然——"模型对这个答案有多大把握"本质上是一种信念程度,而不是频率。
所有概率计算都建立在这三条基础规则上:
公理 1(非负性):$P(A) \geq 0$,概率不能为负
公理 2(归一性):$P(\Omega) = 1$,所有可能结果的概率之和为 1($\Omega$ 是样本空间,即所有可能结果的集合)
公理 3(可加性):如果 $A$ 和 $B$ 互斥(不能同时发生),则 $P(A \cup B) = P(A) + P(B)$
这三条看起来简单,但整个概率论都从这里出发,推导出所有复杂的结论。
样本空间(Sample Space) $\Omega$:所有可能结果的集合。
事件(Event):样本空间的子集,用大写字母表示。
"骰子出现偶数":$A = \{2, 4, 6\}$,$P(A) = \frac{3}{6} = 0.5$
"语言模型下一个词是'的'":单个元素的事件,概率就是模型对这个 token 的预测概率。
随机变量(Random Variable) 是一个把随机实验的结果映射到数字的函数。
抛硬币的结果是"正"或"反",不是数字,不方便计算。用随机变量 $X$ 定义:正面 $X = 1$,反面 $X = 0$。
现在可以计算 $P(X = 1) = 0.5$,$P(X = 0) = 0.5$。
随机变量的关键:它的值在实验之前是不确定的,实验之后才确定。在未观测时,它由一个概率分布描述。
离散随机变量(Discrete Random Variable):取值是有限个或可数无限个。
概率质量函数(PMF,Probability Mass Function):$P(X = x)$,表示 $X$ 取某个具体值 $x$ 的概率。
归一化条件:$\sum_{x} P(X = x) = 1$(所有可能取值的概率之和为 1)
例子——掷骰子:$X \in \{1,2,3,4,5,6\}$,$P(X=k) = \frac{1}{6}$ 对所有 $k$。
例子——语言模型:下一个 token 是离散随机变量,$X \in \{1, 2, \ldots, 128000\}$,PMF 就是 Softmax 输出的概率向量:$P(X = k) = \text{Softmax}(z)_k$。
连续随机变量(Continuous Random Variable):取值是连续区间。
概率密度函数(PDF,Probability Density Function):$f(x)$,满足:
$$P(a \leq X \leq b) = \int_a^b f(x) dx$$
归一化条件:$\int_{-\infty}^{+\infty} f(x) dx = 1$
注意:连续随机变量取某个精确值的概率为 0($P(X = x) = 0$),只有区间上的概率才有意义。
例子——神经网络的权重初始化:权重通常从高斯分布 $\mathcal{N}(0, \sigma^2)$ 里采样,这是连续随机变量。
例子——注意力分数:注意力机制里的 $\frac{qk^T}{\sqrt{d_k}}$ 是连续值,在分析其统计性质时把它视为连续随机变量。
两个随机变量 $X$ 和 $Y$ 的联合分布:$P(X=x, Y=y)$,表示 $X=x$ 且 $Y=y$ 同时发生的概率。
边缘分布:从联合分布里"积掉"另一个变量:
$$P(X=x) = \sum_y P(X=x, Y=y)$$
直觉:如果联合分布告诉你"每种天气下每种穿衣方式的概率",边缘分布就是"不管穿什么,每种天气出现的概率"——把穿衣这个维度"加"掉了。
期望(Expectation) $\mathbb{E}[X]$ 是随机变量的"加权平均值",权重是对应的概率:
离散:
$$\mathbb{E}[X] = \sum_x x \cdot P(X=x)$$
连续:
$$\mathbb{E}[X] = \int_{-\infty}^{+\infty} x \cdot f(x) dx$$
例1——掷骰子的期望点数:
$$\mathbb{E}[X] = 1 \cdot \frac{1}{6} + 2 \cdot \frac{1}{6} + 3 \cdot \frac{1}{6} + 4 \cdot \frac{1}{6} + 5 \cdot \frac{1}{6} + 6 \cdot \frac{1}{6} = \frac{21}{6} = 3.5$$
掷骰子的平均结果是 3.5 点——虽然不可能真的掷出 3.5,但长期平均就是这个数。
例2——语言模型的预期损失:
设当前位置的真实 token 是 $y^*$,模型预测的概率分布是 $\{p_k\}$。
损失(负对数概率)是随机变量 $L = -\log p_{y^*}$,它的期望就是期望损失:
$$\mathbb{E}[L] = -\sum_{k} P(y^* = k) \log p_k$$
这就是交叉熵损失的本质——真实数据分布下,模型损失的期望值。
期望最重要的性质:无论 $X$ 和 $Y$ 是否独立,线性性都成立:
$$\mathbb{E}[aX + bY] = a\mathbb{E}[X] + b\mathbb{E}[Y]$$
这个性质看起来简单,但极其有用。它意味着:
mini-batch 梯度是全量梯度的无偏估计——从训练集随机采样 $B$ 个样本,mini-batch 损失的梯度的期望,等于全量梯度:
$$\mathbb{E}\left[\frac{1}{B}\sum_{i=1}^B \nabla_\theta \ell(\theta; x^{(i)})\right] = \frac{1}{B} \sum_{i=1}^B \mathbb{E}[\nabla_\theta \ell(\theta; x^{(i)})] = \nabla_\theta L(\theta)$$
这是随机梯度下降(SGD)在理论上可以工作的根本原因。
不只是 $\mathbb{E}[X]$,还可以计算 $X$ 的任意函数 $g(X)$ 的期望:
$$\mathbb{E}[g(X)] = \sum_x g(x) P(X=x)$$
在 GRPO 中的直接应用:
DeepSeek R1 的训练目标是最大化期望奖励:
$$J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta}[R(\tau)]$$
其中 $\tau$ 是模型生成的回答(轨迹),$R(\tau)$ 是奖励函数,$\pi_\theta$ 是模型策略(生成分布)。
这里的期望是对"所有可能生成的回答"求平均——用 $\pi_\theta$ 采样多个回答,计算它们的平均奖励,作为期望奖励的估计,然后最大化这个期望。
方差(Variance) 衡量随机变量偏离期望的程度:
$$\text{Var}[X] = \mathbb{E}[(X - \mathbb{E}[X])^2]$$
展开得到一个常用的计算公式:
$$\text{Var}[X] = \mathbb{E}[X^2] - (\mathbb{E}[X])^2$$
标准差(Standard Deviation) 是方差的平方根,和 $X$ 量纲相同:
$$\sigma_X = \sqrt{\text{Var}[X]}$$
掷骰子的方差:
$$\mathbb{E}[X^2] = 1^2 \cdot \frac{1}{6} + 2^2 \cdot \frac{1}{6} + \cdots + 6^2 \cdot \frac{1}{6} = \frac{1+4+9+16+25+36}{6} = \frac{91}{6} \approx 15.17$$
$$\text{Var}[X] = \mathbb{E}[X^2] - (\mathbb{E}[X])^2 = \frac{91}{6} - 3.5^2 = 15.17 - 12.25 = 2.92$$
$$\sigma_X = \sqrt{2.92} \approx 1.71$$
骰子点数的标准差约 1.71,说明典型偏差是 1.71 点。
作用一:注意力机制的缩放因子
第8篇推导过:若 $q$ 和 $k$ 的分量都是方差为 1 的独立随机变量,则点积 $q \cdot k = \sum_{i=1}^{d_k} q_i k_i$ 的方差为 $d_k$。
为了让 Softmax 输入的方差稳定在 1,需要除以 $\sqrt{d_k}$:
$$\text{Var}\left[\frac{q \cdot k}{\sqrt{d_k}}\right] = \frac{d_k}{d_k} = 1$$
这是 Transformer 注意力分数缩放因子的直接推导来源。
作用二:GRPO 的优势函数归一化
在 DeepSeek R1 的 GRPO 算法中,对每个问题生成 $G$ 个回答,用各回答奖励的均值和标准差来归一化优势函数(Advantage Function):
$$A_i = \frac{R_i - \text{mean}(\{R_j\}_{j=1}^G)}{\text{std}(\{R_j\}_{j=1}^G)}$$
分子减去均值:让模型关注"高于平均"还是"低于平均",而不是绝对奖励大小。
分母除以标准差:让不同问题的梯度信号在同一尺度上,训练更稳定——这正是方差归一化的作用。
作用三:权重初始化
Xavier 初始化把权重方差设为 $\frac{2}{n_{in} + n_{out}}$,目标是让前向传播时每层激活值的方差保持稳定(不因层数增加而爆炸或消失)。Kaiming 初始化类似,专门针对 ReLU 激活函数调整了方差。
标准化(Standardization):
$$\tilde{X} = \frac{X - \mathbb{E}[X]}{\sqrt{\text{Var}[X]}}$$
标准化后:$\mathbb{E}[\tilde{X}] = 0$,$\text{Var}[\tilde{X}] = 1$。
这是 LayerNorm 和 BatchNorm 的数学本质——把激活值的分布归一化为零均值单位方差,使各层之间的信号尺度一致,有助于梯度传播和训练稳定。
伯努利分布(Bernoulli Distribution):最简单的离散分布,只有两个结果(成功/失败,1/0)。
参数 $p \in [0,1]$:成功概率。
$$P(X=1) = p, \quad P(X=0) = 1-p$$
$$\mathbb{E}[X] = p, \quad \text{Var}[X] = p(1-p)$$
在深度学习中的应用:
分类分布(Categorical Distribution):$K$ 个类别,每个类别有对应的概率 $p_k$,$\sum_{k=1}^K p_k = 1$。
$$P(X = k) = p_k, \quad k = 1, 2, \ldots, K$$
这是语言模型的核心分布。
DeepSeek V3 的词表有 $K = 128000$ 个 token,每次生成,模型计算出 128000 个 logit,经过 Softmax 得到分类分布的参数 $\{p_k\}$,然后从这个分布里采样下一个 token。
离散均匀分布:$K$ 个结果等可能,$P(X=k) = \frac{1}{K}$。
连续均匀分布 $\text{Uniform}(a, b)$:
$$f(x) = \frac{1}{b-a}, \quad x \in [a, b]$$
$$\mathbb{E}[X] = \frac{a+b}{2}, \quad \text{Var}[X] = \frac{(b-a)^2}{12}$$
在深度学习中:Xavier 均匀初始化从 $U\left(-\frac{\sqrt{6}}{\sqrt{n_{in}+n_{out}}}, \frac{\sqrt{6}}{\sqrt{n_{in}+n_{out}}}\right)$ 采样权重。边界由方差公式推导:要让 $\text{Var}[W] = \frac{2}{n_{in}+n_{out}}$,代入均匀分布方差公式反解 $a$。
正态分布(Normal Distribution) $\mathcal{N}(\mu, \sigma^2)$:
$$f(x) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)$$
$$\mathbb{E}[X] = \mu, \quad \text{Var}[X] = \sigma^2$$
正态分布是深度学习里用得最多的分布,原因有三:
原因一:中心极限定理。大量独立随机变量之和,不管原始分布是什么,都趋向正态分布。神经网络的激活值是大量权重和输入的加权和,天然趋向正态。
原因二:最大熵性质。在给定均值和方差的约束下,正态分布是熵最大的连续分布——"最不假设额外结构"的分布。在没有其他先验知识时,正态是最自然的选择。
原因三:数学可操作性。正态分布在线性变换下保持正态,方便理论分析。
在深度学习中:Kaiming 初始化用正态分布,VAE 的隐变量是正态分布,扩散模型的噪声是正态分布,分析注意力分数的统计性质时假设正态分布。
68-95-99.7 法则:
$$P(\mu - \sigma \leq X \leq \mu + \sigma) \approx 68.3\%$$ $$P(\mu - 2\sigma \leq X \leq \mu + 2\sigma) \approx 95.4\%$$ $$P(\mu - 3\sigma \leq X \leq \mu + 3\sigma) \approx 99.7\%$$
语言模型生成时的温度(Temperature) $\tau$ 直接影响分类分布的形状:
$$p_k(\tau) = \frac{\exp(z_k / \tau)}{\sum_j \exp(z_j / \tau)}$$
这就是为什么 DeepSeek 的 API 里有 temperature 参数——它控制的是输出分布的"集中程度",本质上是在调节分类分布的形状。
temperature
大数定律(Law of Large Numbers):对 $n$ 个独立同分布的样本 $X_1, X_2, \ldots, X_n$,它们的样本均值依概率收敛到期望:
$$\bar{X}_n = \frac{1}{n}\sum_{i=1}^n X_i \xrightarrow{n \to \infty} \mathbb{E}[X]$$
样本越多,平均值越接近真实期望。
SGD 的正确性基础:每个 mini-batch 的梯度是有噪声的,但大数定律保证:平均跑足够多的步骤后,梯度方向会整体收敛到正确方向。
GRPO 的采样估计:对每个问题采样 $G=8$ 个回答,用 8 个样本的平均奖励来近似期望奖励。$G$ 越大,估计越精确;但计算量也越大。$G=8$ 是精度和效率的工程平衡点。
评估指标的稳定性:用 1000 道题评估模型,比用 10 道题评估更可靠——大数定律保证了大样本评估结果更接近模型的真实性能。
中心极限定理(Central Limit Theorem,CLT):不管 $X_i$ 原始是什么分布,$n$ 个独立同分布样本的均值,在 $n$ 足够大时,近似服从正态分布:
$$\frac{\bar{X}_n - \mu}{\sigma / \sqrt{n}} \xrightarrow{d} \mathcal{N}(0, 1)$$
直觉:把很多独立随机效应叠加,结果趋向正态——不管每个效应是均匀分布、伯努利分布还是其他什么分布。
对深度学习的启示:神经网络每层的输出是大量权重和输入的加权和,CLT 解释了为什么激活值的分布往往接近正态,以及为什么用正态分布来初始化权重和分析激活统计是合理的。
import numpy as np import torch import torch.nn.functional as F np.random.seed(42) torch.manual_seed(42) # ===== 1. 离散随机变量:掷骰子 ===== print("===== 离散随机变量:掷骰子 =====\n") # 理论值 faces = np.array([1, 2, 3, 4, 5, 6]) probs = np.ones(6) / 6 e_x = np.sum(faces * probs) e_x2 = np.sum(faces**2 * probs) var_x = e_x2 - e_x**2 std_x = np.sqrt(var_x) print(f"期望(理论): {e_x:.4f}") print(f"方差(理论): {var_x:.4f}") print(f"标准差(理论): {std_x:.4f}") # 模拟验证(大数定律) for n in [100, 1000, 10000, 100000]: rolls = np.random.choice(faces, size=n, p=probs) print(f" n={n:7d}: 样本均值={rolls.mean():.4f}, 样本标准差={rolls.std():.4f}") # ===== 2. 分类分布:语言模型的 token 采样 ===== print("\n===== 分类分布:语言模型 token 采样 =====\n") # 模拟一个小词表(10个token)的预测 logits = torch.tensor([3.0, 1.5, 0.5, -0.5, 2.0, 1.0, -1.0, 0.0, 0.8, -0.3]) vocab = ["猫", "狗", "跑", "跳", "吃", "睡", "的", "在", "很", "不"] probs_lm = F.softmax(logits, dim=0) print("token 概率分布:") for word, p in sorted(zip(vocab, probs_lm.tolist()), key=lambda x: -x[1]): bar = "█" * int(p * 50) print(f" '{word}': {p:.4f} {bar}") # 不同温度下的采样 print("\n温度对分布的影响:") for tau in [0.1, 0.5, 1.0, 2.0]: p_tau = F.softmax(logits / tau, dim=0) entropy = -(p_tau * torch.log(p_tau + 1e-10)).sum().item() top_token = vocab[p_tau.argmax().item()] print(f" τ={tau:.1f}: 最高概率token='{top_token}'({p_tau.max():.3f}), 熵={entropy:.3f}") # ===== 3. 正态分布:权重初始化验证 ===== print("\n===== 正态分布:权重初始化 =====\n") d_in, d_out = 512, 512 # Xavier 正态初始化:std = sqrt(2 / (n_in + n_out)) std_xavier = np.sqrt(2.0 / (d_in + d_out)) W_xavier = np.random.normal(0, std_xavier, size=(d_in, d_out)) # Kaiming 正态初始化(针对 ReLU):std = sqrt(2 / n_in) std_kaiming = np.sqrt(2.0 / d_in) W_kaiming = np.random.normal(0, std_kaiming, size=(d_in, d_out)) print(f"Xavier 初始化: 理论std={std_xavier:.4f}, 实际std={W_xavier.std():.4f}") print(f"Kaiming 初始化: 理论std={std_kaiming:.4f}, 实际std={W_kaiming.std():.4f}") # 模拟前向传播:验证激活值方差 x = np.random.randn(1000, d_in) # 1000 个样本 # 不用初始化(std=1):激活方差爆炸 W_bad = np.random.randn(d_in, d_out) out_bad = x @ W_bad print(f"\n错误初始化(std=1): 输出方差={out_bad.var():.1f} ← 爆炸!") # Xavier 初始化:激活方差稳定 out_xavier = x @ W_xavier print(f"Xavier 初始化: 输出方差={out_xavier.var():.4f} ← 稳定(接近1)") # ===== 4. 期望与方差:GRPO 优势函数归一化 ===== print("\n===== GRPO 优势函数归一化 =====\n") # 模拟:对同一个问题生成 G=8 个回答,每个有不同奖励 G = 8 rewards = np.array([0.8, 1.0, 0.2, -0.3, 0.9, 0.5, 0.1, 0.7]) mean_r = rewards.mean() std_r = rewards.std() # 归一化优势函数 advantages = (rewards - mean_r) / (std_r + 1e-8) print(f"原始奖励: {rewards}") print(f"奖励均值: {mean_r:.3f}") print(f"奖励标准差: {std_r:.3f}") print(f"归一化优势: {advantages.round(3)}") print(f"\n归一化后: 均值={advantages.mean():.6f}(≈0), 标准差={advantages.std():.6f}(≈1)") print("→ 高于平均的回答有正优势(被强化),低于平均的有负优势(被抑制)") # ===== 5. 大数定律演示 ===== print("\n===== 大数定律演示 =====\n") # 真实期望值(掷骰子)= 3.5 true_mean = 3.5 print(f"真实期望: {true_mean}") print(f"{'样本量':>8} | {'样本均值':>10} | {'误差':>8}") print("-" * 35) for n in [10, 100, 1000, 10000, 100000, 1000000]: samples = np.random.choice([1,2,3,4,5,6], size=n) sample_mean = samples.mean() error = abs(sample_mean - true_mean) print(f"{n:>8,} | {sample_mean:>10.4f} | {error:>8.4f}") # ===== 6. 中心极限定理演示 ===== print("\n===== 中心极限定理 =====\n") # 原始分布是均匀分布(非正态!) # 但 n 个均匀分布样本的均值,趋向正态 n_experiments = 10000 print("均匀分布U(0,1)的样本均值,随n增大趋向正态:") print(f"{'n':>6} | {'样本均值的均值':>14} | {'样本均值的std':>14} | {'理论std(=1/sqrt(12n))':>22}") for n in [1, 5, 30, 100]: # 每次取 n 个均匀样本,计算均值,重复 10000 次 means = np.array([np.random.uniform(0, 1, n).mean() for _ in range(n_experiments)]) theoretical_std = np.sqrt(1/12 / n) # Var[U(0,1)]=1/12 print(f"{n:>6} | {means.mean():>14.4f} | {means.std():>14.4f} | {theoretical_std:>22.4f}")
运行结果解读:
实验1验证大数定律:骰子均值随样本量增加从噪声值收敛到理论值 3.5,样本量 100 时误差约 0.1,样本量 100000 时误差约 0.001。
实验2直观看到温度对语言模型输出分布的影响:$\tau=0.1$ 时几乎全部概率压到"猫",$\tau=2.0$ 时分布均匀,熵大幅增加。
实验3是权重初始化的直接验证:标准正态初始化(std=1)导致输出方差等于 512(输入维度),完全爆炸;Xavier 初始化让输出方差稳定在约 1,这正是我们想要的。
实验4完整模拟了 GRPO 的优势函数归一化:归一化后均值为 0、标准差为 1,不同问题的梯度信号在同一尺度上,高于平均的回答被强化,低于平均的被抑制。
实验5和6分别验证大数定律(样本量增大,均值收敛到期望)和中心极限定理(均匀分布的样本均值随 n 增大趋向正态,标准差按 $1/\sqrt{n}$ 收敛)。
这篇文章把概率基础从直觉到数学公式,再到 DeepSeek 的具体应用,系统地打通了。
第一,概率是对不确定性的数值描述,满足三条公理(非负、归一、可加)。频率学派看频率,贝叶斯学派看信念程度,深度学习两者都用。
第二,随机变量把实验结果映射到数字:离散随机变量用 PMF,连续随机变量用 PDF。语言模型的 token 生成就是从一个 128K 类别的分类分布里采样。
第三,期望是概率加权平均,衡量"平均结果"。期望的线性性是 SGD 理论正确性的基础,也是 GRPO 目标函数(最大化期望奖励)的数学表达。
第四,方差衡量随机变量偏离期望的程度。它直接支撑了注意力机制的 $\sqrt{d_k}$ 缩放因子推导,支撑了 GRPO 的优势函数归一化,以及各种权重初始化方案的设计。
第五,五种常见分布在深度学习里各有用武之地:伯努利(二分类/Dropout)、分类(语言模型 token 生成)、均匀(Xavier 初始化)、正态(Kaiming 初始化/VAE/扩散模型)。温度参数控制分类分布的形状(熵)。
第六,大数定律保证了 SGD 和 GRPO 采样估计的收敛性;中心极限定理解释了神经网络激活值趋向正态的现象,为正态分布的广泛使用提供了理论依据。
下一篇预告:
第12篇,我们讲条件概率与贝叶斯定理:AI 推理的核心思想。
语言模型预测下一个词,本质上是在计算条件概率 $P(\text{下一个词} \mid \text{前面所有词})$。贝叶斯定理告诉我们如何从已知信息推断未知信息。这两个概念,是理解语言模型、RAG(检索增强生成)、以及模型推理机制的数学基础。
概率论不是用来描述"随机性"的——它是用来描述"不确定性"的。语言模型之所以需要概率,不是因为语言本质上是随机的,而是因为预测未知的词本质上是在量化不确定性。把概率论学扎实,你就有了一双能看穿语言模型内部逻辑的眼睛。
还没有评论,来抢沙发吧!
博客管理员
40 篇文章
还没有评论,来抢沙发吧!