- 仅使用均匀随机数从头实现逆 CDF、拒绝采样和重要性采样
- 为语言模型 token 生成构建 temperature、top-k 和 top-p(nucleus)采样
- 解释重参数化技巧,以及它为何能使 VAE 中的反向传播穿过采样操作
- 运行 Metropolis-Hastings MCMC,从非归一化的目标分布中采样
问题
语言模型处理完你的 prompt 后,会输出一个包含 50,000 个 logit 的向量,词表中每个 token 对应一个。现在它必须从中选一个。怎么选?
如果它总是选择概率最高的 token,每次回复都会一模一样——确定、单调。如果它完全均匀随机地选,输出就是乱码。答案介于这两个极端之间,而这个「中间地带」由采样控制。
采样不只用于文本生成。强化学习通过采样轨迹来估计策略梯度;VAE 通过从学习到的分布中采样并反向传播穿过随机性来学习隐表示;扩散模型通过采样噪声并迭代去噪来生成图像;蒙特卡洛方法估计没有闭式解的积分;MCMC 算法探索无法枚举的高维后验分布。
每个生成式 AI 系统都是一个采样系统。采样策略决定了输出的质量、多样性和可控性。本节课从最底层的均匀随机数开始,逐步构建每一种主要的采样方法,最终覆盖驱动现代 LLM 和生成模型的技术。
概念
为什么采样很重要
采样在 AI 和机器学习中扮演着四种基本角色:
生成。 语言模型、扩散模型和 GAN 都通过采样产生输出。采样算法直接控制创造性、连贯性和多样性。temperature、top-k 和 nucleus 采样是工程师每天调节的旋钮。
训练。 随机梯度下降采样 mini-batch;dropout 采样要关闭的神经元;数据增强采样随机变换;重要性采样通过重新加权样本来降低强化学习(PPO、TRPO)中的梯度方差。
估计。 机器学习中的许多量没有闭式解:数据分布上的期望损失、基于能量模型的配分函数、贝叶斯推断中的证据。蒙特卡洛估计通过对样本取平均来近似所有这些量。
探索。 MCMC 算法探索贝叶斯推断中的后验分布;进化策略采样参数扰动;Thompson 采样在 bandit 中平衡探索与利用。
核心挑战在于:你只能直接从简单分布(均匀、正态)中采样。对于其他所有分布,都需要一种方法把简单样本转换为目标分布的样本。
均匀随机采样
每种采样方法都从这里开始。均匀随机数生成器在 [0, 1) 上产生数值,等长子区间具有相等概率。
U ~ Uniform(0, 1)
P(a <= U <= b) = b - a for 0 <= a <= b <= 1
Properties:
E[U] = 0.5
Var(U) = 1/12要从 n 个离散项中均匀采样,生成 U 并返回 \lfloor n U \rfloor。要从连续区间 [a, b] 中采样,计算 a + (b - a) U。
关键洞察:单个均匀随机数恰好包含产生任意分布一个样本所需的全部随机性。难点在于找到正确的变换。
逆 CDF 方法(逆变换采样)
累积分布函数(CDF)将数值映射为概率:
F(x) = P(X <= x)
Properties:
F is non-decreasing
F(-inf) = 0
F(+inf) = 1
F maps the real line to [0, 1]逆 CDF 把概率映射回数值。如果 U \sim \text{Uniform}(0, 1),那么 X = F^{-1}(U) 服从目标分布。
Algorithm:
1. Generate u ~ Uniform(0, 1)
2. Return F_inverse(u)
Why it works:
P(X <= x) = P(F_inverse(U) <= x) = P(U <= F(x)) = F(x)指数分布示例:
PDF: f(x) = lambda * exp(-lambda * x), x >= 0
CDF: F(x) = 1 - exp(-lambda * x)
Solve F(x) = u for x:
u = 1 - exp(-lambda * x)
exp(-lambda * x) = 1 - u
x = -ln(1 - u) / lambda
Since (1 - U) and U have the same distribution:
x = -ln(u) / lambda当你能写出闭式 F^{-1} 时,这种方法完美无缺。对于正态分布,没有闭式逆 CDF,因此需要使用其他方法(Box-Muller 或数值近似)。
离散版本: 对于离散分布,将 CDF 构建为累积和,生成 U,找到累积和首次超过 U 的索引。这就是第 06 课中 sample_categorical 的工作原理。
拒绝采样
当你无法求逆 CDF,但可以计算目标 PDF(允许差一个常数因子)时,拒绝采样就能工作。
Target distribution: p(x) (can evaluate, possibly unnormalized)
Proposal distribution: q(x) (can sample from)
Bound: M such that p(x) <= M * q(x) for all x
Algorithm:
1. Sample x ~ q(x)
2. Sample u ~ Uniform(0, 1)
3. If u < p(x) / (M * q(x)), accept x
4. Otherwise, reject and go to step 1
Acceptance rate = 1/M边界 M 越紧,接受率越高。在低维(1-3 维)中拒绝采样效果很好。在高维中,接受率指数级下降,因为提议分布的大部分体积都会被拒绝。这就是拒绝采样的维度灾难。
示例:从截断正态分布中采样。 在截断区间上使用均匀提议分布。包络 M 取该区间内正态 PDF 的最大值。
示例:从半圆中采样。 在包围矩形内均匀提议,接受落在半圆内的点。这就是蒙特卡洛计算 \pi 的方式:接受率等于面积比 \pi/4。
重要性采样
有时你不需要目标分布 p(x) 的样本,而是要估计 p(x) 下的期望,而你拥有的样本来自另一个分布 q(x)。
Goal: estimate E_p[f(x)] = integral of f(x) * p(x) dx
Rewrite:
E_p[f(x)] = integral of f(x) * (p(x)/q(x)) * q(x) dx
= E_q[f(x) * w(x)]
where w(x) = p(x) / q(x) are the importance weights.
Estimator:
E_p[f(x)] ~ (1/N) * sum(f(x_i) * w(x_i)) where x_i ~ q(x)这在强化学习中至关重要。在 PPO(Proximal Policy Optimization)中,你在旧策略 \pi_{\text{old}} 下收集轨迹,但希望优化新策略 \pi_{\text{new}}。重要性权重为 \pi_{\text{new}}(a \mid s) / \pi_{\text{old}}(a \mid s)。PPO 会裁剪这些权重,防止新策略偏离旧策略过远。
重要性采样估计量的方差取决于 q 与 p 的相似程度。如果 q 与 p 差异很大,少数样本会获得巨大权重并主导估计。自归一化重要性采样通过除以权重之和来缓解这个问题:
蒙特卡洛估计
蒙特卡洛估计通过随机样本的平均来近似积分。大数定律保证其收敛。
Goal: estimate I = integral of g(x) dx over domain D
Method:
1. Sample x_1, ..., x_N uniformly from D
2. I ~ (Volume of D / N) * sum(g(x_i))
Error: O(1 / sqrt(N)) regardless of dimension误差率与维度无关。这就是为什么蒙特卡洛方法在高维中占据主导,而基于网格的积分则不可行。
估计 pi:
Sample (x, y) uniformly from [-1, 1] x [-1, 1]
Count how many fall inside the unit circle: x^2 + y^2 <= 1
pi ~ 4 * (count inside) / (total count)估计期望:
E[f(X)] ~ (1/N) * sum(f(x_i)) where x_i ~ p(x)
The sample mean converges to the true expectation.
Variance of the estimator = Var(f(X)) / N马尔可夫链蒙特卡洛(MCMC):Metropolis-Hastings 算法
MCMC 构建一个马尔可夫链,使其平稳分布就是目标分布 p(x)。经过足够多的步数后,链上的样本就近似来自 p(x) 的样本。
Target: p(x) (known up to a normalizing constant)
Proposal: q(x'|x) (how to propose the next state given the current state)
Metropolis-Hastings algorithm:
1. Start at some x_0
2. For t = 1, 2, ..., T:
a. Propose x' ~ q(x'|x_t)
b. Compute acceptance ratio:
alpha = [p(x') * q(x_t|x')] / [p(x_t) * q(x'|x_t)]
c. Accept with probability min(1, alpha):
- If u < alpha (u ~ Uniform(0,1)): x_{t+1} = x'
- Otherwise: x_{t+1} = x_t
3. Discard first B samples (burn-in)
4. Return remaining samples对于对称提议分布 (q(x' \mid x) = q(x \mid x')),比率简化为 p(x')/p(x)。这就是原始的 Metropolis 算法。
为什么它有效。 接受规则保证了细致平衡:处于 x 并移动到 x' 的概率,等于处于 x' 并移动到 x 的概率。细致平衡意味着 p(x) 是链的平稳分布。
实际考虑:
- Burn-in:在链达到平衡前丢弃早期样本
- Thinning:每隔 k 个样本保留一个,以降低自相关
- 提议尺度:太小则链移动缓慢(接受率高但探索慢);太大则大部分提议被拒绝(接受率低,原地踏步)
- 高维中高斯提议的最优接受率约为 0.234
Gibbs 采样
Gibbs 采样是 MCMC 在多变量分布上的特例。它不是一次性在所有维度上提议移动,而是每次只从一个变量的条件分布中更新该变量。
Target: p(x_1, x_2, ..., x_d)
Algorithm:
For each iteration t:
Sample x_1^{t+1} ~ p(x_1 | x_2^t, x_3^t, ..., x_d^t)
Sample x_2^{t+1} ~ p(x_2 | x_1^{t+1}, x_3^t, ..., x_d^t)
...
Sample x_d^{t+1} ~ p(x_d | x_1^{t+1}, x_2^{t+1}, ..., x_{d-1}^{t+1})Gibbs 采样要求你能从每个条件分布 p(x_i \mid x_{-i}) 中采样。这对许多模型都很直接:
- 贝叶斯网络:条件分布由图结构决定
- 高斯混合:条件分布是高斯分布
- 伊辛模型:每个自旋的条件只依赖于其邻居
接受率始终为 1(每个提议都被接受),因为从精确的条件分布中采样自动满足细致平衡。
局限。 当变量高度相关时,Gibbs 采样混合得很慢,因为每次只更新一个变量无法在对角线上大幅移动。
温度采样(用于 LLM)
语言模型为词表中的每个 token 输出 logit z_1, \ldots, z_V。softmax 将其转换为概率。temperature 在 softmax 之前重新缩放 logit:
p_i = exp(z_i / T) / sum(exp(z_j / T))
T = 1.0: standard softmax (original distribution)
T -> 0: argmax (deterministic, always picks highest logit)
T -> inf: uniform (all tokens equally likely)
T < 1.0: sharpens the distribution (more confident, less diverse)
T > 1.0: flattens the distribution (less confident, more diverse)为什么它有效。 用 T < 1 去除 logit 会放大 logit 之间的差距。若 z_1 = 2、z_2 = 1,用 T = 0.5 除后得到 z_1/T = 4、z_2/T = 2,差距变大。softmax 后,最高 logit 的 token 获得更大的概率份额。
实践中:
- T = 0.0:贪心解码,最适合事实性问答
- T = 0.3\text{-}0.7:略带创造性,适合代码生成
- T = 0.7\text{-}1.0:平衡,适合一般对话
- T = 1.0\text{-}1.5:创意写作、头脑风暴
- T > 1.5:越来越随机,很少有用
温度不改变哪些 token 是可能的。它改变的是分配给每个 token 的概率质量。
Top-k 采样
Top-k 采样将候选集限制为概率最高的 k 个 token,然后重新归一化并从该受限集合中采样。
Algorithm:
1. Compute softmax probabilities for all V tokens
2. Sort tokens by probability (descending)
3. Keep only the top k tokens
4. Renormalize: p_i' = p_i / sum(p_j for j in top-k)
5. Sample from the renormalized distribution
k = 1: greedy decoding
k = V: no filtering (standard sampling)
k = 40: typical setting, removes long tail of unlikely tokensTop-k 防止模型选择概率分布长尾中极不可能的 token(错字、无意义内容)。问题是 k 是固定的,与上下文无关。当模型很自信(某个 token 概率为 95%)时,k = 40 仍允许 39 个替代项;当模型不确定(概率分散在 1000 个 token 上)时,k = 40 会切断合理的选项。
Top-p(核)采样
Top-p 采样动态调整候选集大小。它保留最小的 token 集合,使其累积概率超过 p。
Algorithm:
1. Compute softmax probabilities for all V tokens
2. Sort tokens by probability (descending)
3. Find smallest k such that sum of top-k probabilities >= p
4. Keep only those k tokens
5. Renormalize and sample
p = 0.9: keeps tokens covering 90% of probability mass
p = 1.0: no filtering
p = 0.1: very restrictive, nearly greedy当模型自信时,核采样只保留少量 token(可能 2-3 个);当模型不确定时,它保留很多(可能 200 个)。这种自适应行为就是核采样通常比 top-k 产生更好文本的原因。
常见组合:
- Temperature 0.7 + top-p 0.9:通用好设置
- Temperature 0.0(贪心):确定性任务的最佳选择
- Temperature 1.0 + top-k 50:Fan 等人(2018)原始论文设置
Top-k 和 top-p 可以组合使用。先应用 top-k,再对剩余集合应用 top-p。
重参数化技巧(用于 VAE)
变分自编码器(VAE)通过将输入编码为隐空间分布、从该分布采样、再解码样本来学习。问题是你无法反向传播穿过采样操作。
Standard sampling (not differentiable):
z ~ N(mu, sigma^2)
The randomness blocks gradient flow.
d/d_mu [sample from N(mu, sigma^2)] = ???重参数化技巧将随机性与参数分离:
Reparameterized sampling:
epsilon ~ N(0, 1) (fixed random noise, no parameters)
z = mu + sigma * epsilon (deterministic function of parameters)
Now z is a deterministic, differentiable function of mu and sigma.
d(z)/d(mu) = 1
d(z)/d(sigma) = epsilon
Gradients flow through mu and sigma.这是因为 \mathcal{N}(\mu, \sigma^2) 与 \mu + \sigma \cdot \mathcal{N}(0, 1) 同分布。关键洞察:把随机性转移到一个无参数的源(\epsilon),然后把样本表示为参数的可微变换。
在 VAE 训练循环中:
- 编码器为每个输入输出 \mu 和 \log(\sigma^2)
- 采样 \epsilon \sim \mathcal{N}(0, 1)
- 计算 z = \mu + \sigma \epsilon
- 解码 z 以重建输入
- 反向传播穿过第 4、3、2、1 步(因为第 3 步可微)
没有重参数化技巧,VAE 就无法用标准反向传播训练。这一单独洞察使 VAE 变得实用。
Gumbel-Softmax(可微分分类采样)
重参数化技巧适用于连续分布(高斯分布)。对于离散分类分布,需要另一种方法。Gumbel-Softmax 提供了分类采样的可微近似。
Gumbel-Max 技巧(不可微):
To sample from a categorical distribution with log-probabilities log(p_1), ..., log(p_k):
1. Sample g_i ~ Gumbel(0, 1) for each category
(g = -log(-log(u)), where u ~ Uniform(0, 1))
2. Return argmax(log(p_i) + g_i)
This produces exact categorical samples.Gumbel-Softmax(可微近似):
Replace the hard argmax with a soft softmax:
y_i = exp((log(p_i) + g_i) / tau) / sum(exp((log(p_j) + g_j) / tau))
tau (temperature) controls the approximation:
tau -> 0: approaches a one-hot vector (hard categorical)
tau -> inf: approaches uniform (1/k, 1/k, ..., 1/k)
tau = 1.0: soft approximationGumbel-Softmax 产生离散样本的连续松弛。输出是概率向量(软 one-hot)而非硬 one-hot。梯度流经 softmax。训练的前向传播中,可以使用 straight-through 估计器:前向传播用硬 argmax,反向传播用软 Gumbel-Softmax 梯度。
应用:
- VAE 中的离散隐变量
- 神经网络架构搜索(选择离散操作)
- 硬注意力机制
- 离散动作强化学习
分层采样
标准蒙特卡洛采样可能偶然在样本空间中留下空隙。分层采样通过将空间划分为若干层并从每层采样来强制均匀覆盖。
Standard Monte Carlo:
Sample N points uniformly from [0, 1]
Some regions may have clusters, others gaps
Stratified sampling:
Divide [0, 1] into N equal strata: [0, 1/N), [1/N, 2/N), ..., [(N-1)/N, 1)
Sample one point uniformly within each stratum
x_i = (i + u_i) / N where u_i ~ Uniform(0, 1), i = 0, ..., N-1分层采样的方差总是小于或等于标准蒙特卡洛:
Var(stratified) <= Var(standard Monte Carlo)
The improvement is largest when f(x) varies smoothly.
For piecewise-constant functions, stratified sampling is exact.应用:
- 数值积分(拟蒙特卡洛)
- 训练数据划分(确保每折类别平衡)
- 与分层结合的重要性采样
- NeRF(Neural Radiance Fields)沿相机光线使用分层采样
与扩散模型的联系
扩散模型通过采样过程生成图像。前向过程在 T 步内逐渐向图像添加高斯噪声,直到变成纯噪声。反向过程学习去噪,逐步恢复原始图像。
Forward process (known):
x_t = sqrt(alpha_t) * x_{t-1} + sqrt(1 - alpha_t) * epsilon
where epsilon ~ N(0, I)
After T steps: x_T ~ N(0, I) (pure noise)
Reverse process (learned):
x_{t-1} = (1/sqrt(alpha_t)) * (x_t - (1 - alpha_t)/sqrt(1 - alpha_bar_t) * epsilon_theta(x_t, t)) + sigma_t * z
where z ~ N(0, I)
Each denoising step is a sampling step.与本节课方法之间的联系:
- 每个去噪步骤都使用重参数化技巧(采样噪声,应用确定性变换)
- 噪声调度 \lbrace \alpha_t \rbrace 控制一种形式的温度退火
- 训练使用蒙特卡洛估计来近似 ELBO(evidence lower bound)
- 扩散模型中的 ancestral 采样是一个马尔可夫链(每步只依赖当前状态)
整个图像生成过程就是迭代采样:从噪声开始,每一步都采样一个以学习到的去噪模型为条件的、噪声略小的版本。
构建它
第 1 步:均匀采样与逆 CDF 采样
pythonimport math
import random
def sample_uniform(a, b):
return a + (b - a) * random.random()
def sample_exponential_inverse_cdf(lam):
u = random.random()
return -math.log(u) / lam生成 10,000 个指数样本,并验证均值是否为 1/\lambda。
第 2 步:拒绝采样
pythondef rejection_sample(target_pdf, proposal_sample, proposal_pdf, M):
while True:
x = proposal_sample()
u = random.random()
if u < target_pdf(x) / (M * proposal_pdf(x)):
return x使用拒绝采样从截断正态分布中抽取样本。通过直方图验证样本形状。
第 3 步:重要性采样
pythondef importance_sampling_estimate(f, target_pdf, proposal_pdf, proposal_sample, n):
total = 0
for _ in range(n):
x = proposal_sample()
w = target_pdf(x) / proposal_pdf(x)
total += f(x) * w
return total / n使用均匀提议估计正态分布下 \mathbb{E}[X^2]。与已知答案(\mu^2 + \sigma^2)比较。
第 4 步:蒙特卡洛估计 pi
pythondef monte_carlo_pi(n):
inside = 0
for _ in range(n):
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
if x*x + y*y <= 1:
inside += 1
return 4 * inside / n第 5 步:Metropolis-Hastings MCMC
pythondef metropolis_hastings(target_log_pdf, proposal_sample, proposal_log_pdf, x0, n_samples, burn_in):
samples = []
x = x0
for i in range(n_samples + burn_in):
x_new = proposal_sample(x)
log_alpha = (target_log_pdf(x_new) + proposal_log_pdf(x, x_new)
- target_log_pdf(x) - proposal_log_pdf(x_new, x))
if math.log(random.random()) < log_alpha:
x = x_new
if i >= burn_in:
samples.append(x)
return samples从双峰分布(两个高斯混合)中采样。可视化链的轨迹。
第 6 步:Gibbs 采样
pythondef gibbs_sampling_2d(conditional_x_given_y, conditional_y_given_x, x0, y0, n_samples, burn_in):
x, y = x0, y0
samples = []
for i in range(n_samples + burn_in):
x = conditional_x_given_y(y)
y = conditional_y_given_x(x)
if i >= burn_in:
samples.append((x, y))
return samples第 7 步:温度采样
pythondef softmax(logits):
max_l = max(logits)
exps = [math.exp(z - max_l) for z in logits]
total = sum(exps)
return [e / total for e in exps]
def temperature_sample(logits, temperature):
scaled = [z / temperature for z in logits]
probs = softmax(scaled)
return sample_from_probs(probs)展示温度如何改变一组 token logit 的输出分布。
第 8 步:Top-k 与 top-p 采样
pythondef top_k_sample(logits, k):
indexed = sorted(enumerate(logits), key=lambda x: -x[1])
top = indexed[:k]
top_logits = [l for _, l in top]
probs = softmax(top_logits)
idx = sample_from_probs(probs)
return top[idx][0]
def top_p_sample(logits, p):
probs = softmax(logits)
indexed = sorted(enumerate(probs), key=lambda x: -x[1])
cumsum = 0
selected = []
for token_idx, prob in indexed:
cumsum += prob
selected.append((token_idx, prob))
if cumsum >= p:
break
sel_probs = [pr for _, pr in selected]
total = sum(sel_probs)
sel_probs = [pr / total for pr in sel_probs]
idx = sample_from_probs(sel_probs)
return selected[idx][0]第 9 步:重参数化技巧
pythondef reparam_sample(mu, sigma):
epsilon = random.gauss(0, 1)
return mu + sigma * epsilon
def reparam_gradient(mu, sigma, epsilon):
dz_dmu = 1.0
dz_dsigma = epsilon
return dz_dmu, dz_dsigma演示梯度可以流经重参数化样本,但不能流经直接采样。
第 10 步:Gumbel-Softmax
pythondef gumbel_sample():
u = random.random()
return -math.log(-math.log(u))
def gumbel_softmax(logits, temperature):
gumbels = [math.log(p) + gumbel_sample() for p in logits]
return softmax([g / temperature for g in gumbels])展示降低温度如何让输出趋近 one-hot 向量。
完整实现及所有可视化见 code/sampling.py。
使用它
使用 NumPy 和 SciPy 的生产级版本:
pythonimport numpy as np
rng = np.random.default_rng(42)
exponential_samples = rng.exponential(scale=2.0, size=10000)
print(f"Exponential mean: {exponential_samples.mean():.4f} (expected 2.0)")
from scipy import stats
normal = stats.norm(loc=0, scale=1)
print(f"CDF at 1.96: {normal.cdf(1.96):.4f}")
print(f"Inverse CDF at 0.975: {normal.ppf(0.975):.4f}")
logits = np.array([2.0, 1.0, 0.5, 0.1, -1.0])
temperature = 0.7
scaled = logits / temperature
probs = np.exp(scaled - scaled.max()) / np.exp(scaled - scaled.max()).sum()
token = rng.choice(len(logits), p=probs)
print(f"Sampled token index: {token}")对于大规模 MCMC,使用专门库:
- PyMC:完整的贝叶斯建模,使用 NUTS(自适应 HMC)
- emcee:集成 MCMC 采样器
- NumPyro/JAX:GPU 加速 MCMC
你已经从头构建了这些方法。现在你知道这些库调用背后的原理了。
练习
- 为柯西分布实现逆 CDF 采样。其 CDF 为 F(x) = 0.5 + \arctan(x)/\pi。生成 10,000 个样本并绘制直方图与真实 PDF 对比。注意重尾(远离中心的极端值)。
- 使用拒绝采样,用 Uniform(0, 1) 提议分布生成 Beta(2, 5) 分布的样本。将接受样本与真实 Beta PDF 绘图对比。理论接受率是多少?
- 用蒙特卡洛估计 \sin(x) 从 0 到 \pi 的积分,分别使用 1,000、10,000 和 100,000 个样本。比较每个规模下的误差。验证误差按 O(1/\sqrt{N}) 缩放。
- 实现 Metropolis-Hastings 算法,从二维分布 p(x, y) 正比于 \exp(-(x^2 y^2 + x^2 + y^2 - 8x - 8y) / 2) 中采样。绘制样本和链轨迹。尝试不同的提议标准差。
- 构建完整文本生成 demo:给定包含 10 个词的词表和对应 logit,使用 (a) 贪心、(b) temperature=0.7、(c) top-k=3、(d) top-p=0.9 生成 20 个 token 的序列。比较 5 次运行中输出的多样性。
提示
练习 1。 解 u = F(x) 得到 x = \tan(\pi(u - 0.5))。检查样本中位数接近 0,且约 6% 的样本满足 \lvert x \rvert > 10,即 1 - (2/\pi)\arctan(10)。
练习 2。 Beta(2, 5) 密度为 30x(1-x)^4。在众数 x = 1/5 处找到最大值并作为 rejection_sample 中的 M。理论接受率为 1/M,因此可与你实际接受的比例比较。
练习 3。 精确值为 2。对每个 n 调用 monte_carlo_integral(math.sin, 0, math.pi, n),并用多个种子重复运行。当 n 增大 10 倍时,平均误差应下降约 \sqrt{10} \approx 3.2。
练习 4。 写出目标的对数,即 -(x^2 y^2 + x^2 + y^2 - 8x - 8y)/2,并传给 metropolis_hastings_2d。记录每种提议标准差下的接受率:过小的值几乎接受每一步但移动缓慢,过大的值几乎拒绝每一步。
练习 5。 贪心解码每步取最大 logit 的索引。其他三种方法分别使用 temperature_sample、top_k_sample 和 top_p_sample。贪心在 5 次运行中必须给出相同序列,因此统计每种方法产生不同序列的数量来衡量多样性。
关键术语
| 术语 | 人们常说 | 实际含义 |
|---|---|---|
| Sampling | "抽取随机值" | 按照概率分布生成数值。所有生成式 AI 背后的机制 |
| Uniform distribution | "全都一样可能" | [a, b] 内每个值的概率密度均为 1/(b-a)。所有采样方法的起点 |
| Inverse CDF | "概率变换" | F^{-1}(U) 将均匀样本转换为任意已知 CDF 分布的样本。精确且高效 |
| Rejection sampling | "提议并接受/拒绝" | 从简单提议分布生成,按目标/提议比例的概率接受。精确但浪费样本 |
| Importance sampling | "重新加权样本" | 用来自 q(x) 的样本,通过权重 p(x)/q(x) 估计 p(x) 下的期望。强化学习中 PPO 的核心 |
| Monte Carlo | "随机样本取平均" | 将积分近似为样本平均。误差 O(1/\sqrt{N}),与维度无关 |
| MCMC | "会收敛的随机游走" | 构造平稳分布为目标的马尔可夫链。Metropolis-Hastings 是基础算法 |
| Metropolis-Hastings | "大概率上山,偶尔下山" | 提议移动,按密度比决定是否接受。细致平衡保证收敛到目标分布 |
| Gibbs sampling | "一次更新一个变量" | 固定其他变量,从每个变量的条件分布中更新。接受率 100% |
| Temperature | "置信度旋钮" | 在 softmax 前将 logit 除以 T。T<1 锐化(更自信),T>1 拉平(更多样) |
| Top-k sampling | "保留最好的 k 个" | 只保留概率最高的 k 个 token,重新归一化后采样。候选集大小固定 |
| Nucleus sampling (top-p) | "保留可能的那些" | 保留累积概率超过 p 的最小 token 集合。候选集大小自适应 |
| Reparameterization trick | "把随机性移到外面" | 写成 z = \mu + \sigma \epsilon,其中 \epsilon \sim \mathcal{N}(0,1)。让采样可微。VAE 训练的关键 |
| Gumbel-Softmax | "软分类采样" | 用 Gumbel 噪声 + 带温度的 softmax 对分类采样做可微近似 |
| Stratified sampling | "强制覆盖" | 将样本空间分层,每层都采样。方差总是低于朴素蒙特卡洛 |
| Burn-in | "预热期" | 链达到平稳分布前丢弃的初始 MCMC 样本 |
| Detailed balance | "可逆性条件" | p(x) T(x \to y) = p(y) T(y \to x)。p 是马尔可夫链平稳分布的充分条件 |
| Diffusion sampling | "迭代去噪" | 从噪声出发,应用学习到的去噪步骤生成数据。每步都是条件采样操作 |
延伸阅读
- Holbrook (2023): The Metropolis-Hastings Algorithm - MCMC 基础的详细教程
- Jang, Gu, Poole (2017): Categorical Reparameterization with Gumbel-Softmax - Gumbel-Softmax 原始论文
- Holtzman et al. (2020): The Curious Case of Neural Text Degeneration - nucleus(top-p)采样论文
- Kingma & Welling (2014): Auto-Encoding Variational Bayes - 引入重参数化技巧的 VAE 论文
- Ho, Jain, Abbeel (2020): Denoising Diffusion Probabilistic Models - 将采样与图像生成联系起来的 DDPM