拓冰建站拓冰建站
首页 / 资讯中心 / 正文

朗之万动力学:从物理直觉到扩散模型采样的核心原理

1. 从随机噪声到确定性采样朗之万动力学的核心直觉如果你在机器学习特别是生成模型领域摸爬滚打过一段时间那么“朗之万动力学”这个名字你一定不会陌生。它频繁出现在扩散模型、能量模型、贝叶斯推断等前沿领域的论文和教程里听起来像是一个高深莫测的数学物理概念。但剥开它那层由随机微分方程构成的外壳其核心思想其实非常直观想象一个在复杂地形能量景观中滚动的小球它既受到地形坡度梯度的牵引又不断受到来自四面八方微小随机碰撞噪声的扰动。朗之万动力学描述的就是这个小球的运动轨迹。这个简单的物理图景恰恰是理解许多现代采样和优化算法的钥匙。在传统优化中比如梯度下降我们只关心那个“坡度”希望小球能一路滚到最低点全局最小。但现实世界的数据分布和损失函数往往崎岖不平布满局部极小点。这时如果小球完全服从梯度它很容易卡在某个小坑里出不来。朗之万动力学引入的“噪声”就像给小球注入了一点“热运动”的能量让它有机会跳出局部极小点从而有机会探索到更优的区域。在生成模型中这个逻辑被反过来用。我们不再寻找最低点而是希望让小球按照某种特定的概率分布比如数据分布去“游荡”。朗之万动力学告诉我们如果我们知道这个概率分布对应的“能量地形”通常取概率的负对数即负对数似然那么按照“梯度下降 适当噪声”的规则去驱动小球经过足够长时间的模拟后小球出现在空间中各个位置的概率就会精确地匹配我们想要的分布。这就是它作为马尔可夫链蒙特卡洛MCMC采样器的核心价值它提供了一条从随机噪声出发渐进地生成符合目标分布样本的确定性路径。所以无论你是想深入理解扩散模型的反向过程还是希望在贝叶斯后验采样中找到一个高效的利器亦或是单纯对“噪声如何帮助搜索”这一反直觉现象感到好奇掌握朗之万动力学都至关重要。它不是一个黑盒工具而是一套有着坚实物理基础和数学保证的框架。接下来我将带你从最基本的方程拆解开始一步步看清它的工作原理、实现细节以及在实际应用中那些容易踩坑的地方。2. 方程拆解噪声、梯度与离散化的艺术朗之万动力学的标准形式由一个随机微分方程SDE给出。别被“随机微分方程”吓到我们直接看它在实际计算中最常用的离散化形式这行代码几乎就是它的全部精髓x_{t1} x_t - \gamma \nabla_x U(x_t) \sqrt{2\gamma} \cdot \epsilon_t其中x_t系统在时间步t的状态例如要生成的图像向量、模型参数等。U(x)势能函数。在机器学习中这通常是我们关心的能量函数它与我们想要采样的目标概率分布p(x)通过玻尔兹曼分布关联p(x) \propto \exp(-U(x))。简单说U(x)越小的地方p(x)的概率越大。\nabla_x U(x_t)势能函数在x_t处的梯度。它指向能量上升最快的方向因此负梯度-\nabla_x U(x_t)就指向能量下降的方向试图将x拉向概率密度高的区域。\gamma步长学习率。它控制了每次更新中梯度项的强度。\epsilon_t一个从标准正态分布中采样的随机噪声向量即\epsilon_t \sim \mathcal{N}(0, I)。\sqrt{2\gamma}噪声的缩放系数。这个特定的系数\sqrt{2\gamma}不是随意设置的它确保了在连续时间极限下\gamma无穷小模拟出的样本分布会精确收敛到目标分布p(x) \propto \exp(-U(x))。这是物理学中“涨落-耗散定理”的体现。现在让我们把这三部分拆开来看第一部分- \gamma \nabla_x U(x_t)—— 确定性的漂移力这部分就是熟悉的梯度下降。它代表系统受到的确定性驱动力总是试图将状态x推向能量更低概率更高的区域。如果没有噪声系统就会沿着梯度流最终稳定在一个局部极小点。第二部分 \sqrt{2\gamma} \cdot \epsilon_t—— 随机性的扩散力这是朗之万动力学的灵魂。注入的高斯噪声为系统提供了随机探索的能力。噪声的方差与步长\gamma成正比这意味着步长越大单次更新中噪声的扰动也越大。这个设计非常巧妙它保证了无论步长如何选择只要足够小在长时间模拟后系统的统计性质稳态分布是不变的。第三部分离散化与“艺术”上面给出的是离散时间近似。真正的连续时间朗之万动力学是一个微分方程。离散化会引入误差特别是当步长\gamma不够小时这种误差会导致采样分布偏离目标分布。因此在实际应用中选择\gamma成了一门“艺术”\gamma太大更新步伐大收敛快但噪声项也会过大可能导致更新不稳定甚至发散。更重要的是离散化误差严重采样结果不可信。\gamma太小更新稳定离散化误差小理论上更精确但需要极多的迭代步数才能让样本在空间中得到充分混合计算成本高昂。一个常见的实践经验是采用一个衰减的步长调度。在采样初期使用较大的步长让系统快速从初始区域如随机噪声转移到目标分布的高概率区域在采样后期逐渐减小步长以精细调整样本质量减少离散化误差。这类似于优化算法中的学习率衰减。注意这个离散化公式有时也被称为“非预条件化”的朗之万动力学。在一些复杂场景中人们会引入一个预条件矩阵M类似于优化中的自适应学习率如Adam中的对角缩放将公式变为x_{t1} x_t - \gamma M \nabla_x U(x_t) \sqrt{2\gamma M} \cdot \epsilon_t以在不同维度上采用不同的更新尺度加速收敛。这在采样高维、各向异性的分布时非常有效。3. 与扩散模型的深度关联反向过程即是朗之万采样朗之万动力学在当今最火热的生成模型——扩散模型中扮演着核心角色。理解这一点能让你真正看透扩散模型的工作原理。扩散模型包含两个过程前向过程逐步向数据x_0中添加高斯噪声经过T步后数据变成纯高斯噪声x_T \sim \mathcal{N}(0, I)。这是一个固定的、已知的马尔可夫链。反向过程学习一个模型从噪声x_T出发逐步“去噪”最终恢复出数据x_0。关键来了在去噪扩散概率模型DDPM等重要框架下其反向过程的采样更新公式经过一番推导利用Tweedie公式和重参数化技巧可以写成如下形式x_{t-1} \frac{1}{\sqrt{\alpha_t}} ( x_t - \frac{\beta_t}{\sqrt{1-\bar{\alpha}_t}} \epsilon_\theta(x_t, t) ) \sigma_t z其中z \sim \mathcal{N}(0, I)\alpha_t, \beta_t, \bar{\alpha}_t, \sigma_t是与前向过程噪声调度相关的系数\epsilon_\theta是训练好的去噪网络预测噪声。如果你仔细观察这个公式并将其与朗之万动力学方程进行对比你会发现它们具有完全相同的精神结构x_t - ...这部分包含了基于当前状态x_t的确定性更新。其中\epsilon_\theta(x_t, t)可以理解为对数据对数概率密度梯度得分函数score function的一种估计。因为理论上最优的去噪网络学习到的正是这个得分函数\nabla_{x_t} \log p(x_t)。 \sigma_t z这就是显式添加的高斯噪声项对应于朗之万方程中的\sqrt{2\gamma} \epsilon_t。因此扩散模型的反向生成过程本质上就是在执行一个时变步长\gamma_t由\alpha_t, \beta_t等决定的朗之万动力学采样。其目标分布是随着时间步t变化的一系列中间分布p(x_t)最终收敛到真实数据分布p(x_0)。这种视角带来了巨大的启发解释了为什么需要噪声如果反向过程只做确定性去噪即令\sigma_t 0那就变成了一个确定性映射类似于VAE的解码器。但这样生成的样本多样性会变差且可能因为累积误差而质量下降。朗之万动力学中的噪声保证了采样过程的随机性使得每次采样能生成不同的、来自目标分布的数据样本。连接了更广义的采样框架基于得分的生成模型Score-Based Generative Models直接建模得分函数\nabla_x \log p(x)其生成过程就是纯粹的朗之万动力学采样。扩散模型可以看作是这类模型的一个特例或一种特殊的参数化训练方式。为改进采样器提供了思路既然反向过程是朗之万采样那么所有用于加速或改进MCMC采样的技术都可以被借鉴过来。例如预测器-校正器Predictor-Corrector方法先用一个简单的公式如欧拉法Predictor快速推进一步然后再用朗之万动力学的思想或其他MCMC方法Corrector对这一步的结果进行多次“校正”以降低离散化误差从而允许使用更大的步长、更少的采样步数。DDIMDenoising Diffusion Implicit Models等加速采样算法也可以从这个角度进行理解——它们通过改变随机微分方程的形式或离散化方式来寻找更高效的采样路径。4. 实战模拟从二维演示到代码实现理论再优美也需要代码来验证。让我们用一个经典的例子——采样一个“双月牙”形状的混合高斯分布——来亲手实现并感受朗之万动力学。这个分布不是凸的存在两个分离的模态mode非常适合展示朗之万动力学如何通过噪声在模态间跳转。首先我们定义目标分布。假设我们想采样来自两个二维高斯分布的混合其概率密度函数为p(x) 0.5 * \mathcal{N}(x; \mu_1, \Sigma_1) 0.5 * \mathcal{N}(x; \mu_2, \Sigma_2)其中\mu_1 [2, 2],\mu_2 [-2, -2], 协方差矩阵\Sigma_1 \Sigma_2 [[1, 0.5], [0.5, 1]]。在朗之万动力学中我们需要的是能量函数U(x) -\log p(x)及其梯度。对于高斯混合模型其梯度计算需要用到对数求和但概念是清晰的。下面是一个简单的Python实现使用PyTorch以便于后续与深度学习框架衔接import torch import numpy as np import matplotlib.pyplot as plt # 1. 定义目标分布双高斯混合的参数 mu1 torch.tensor([2.0, 2.0]) mu2 torch.tensor([-2.0, -2.0]) sigma torch.tensor([[1.0, 0.5], [0.5, 1.0]]) # 共享协方差矩阵 sigma_inv torch.inverse(sigma) # 计算高斯分布的归一化常数对数空间 log_norm -0.5 * torch.logdet(2 * torch.pi * sigma) def energy_function(x): 计算能量 U(x) -log p(x) x: shape (batch_size, 2) # 计算两个高斯成分的对数概率密度 diff1 x - mu1 diff2 x - mu2 # 马氏距离部分: -0.5 * (x-\mu)^T \Sigma^{-1} (x-\mu) log_p1 log_norm - 0.5 * (diff1 sigma_inv * diff1).sum(dim-1) log_p2 log_norm - 0.5 * (diff2 sigma_inv * diff2).sum(dim-1) # 混合模型: log(0.5*exp(log_p1) 0.5*exp(log_p2)) # 使用 logsumexp 避免数值下溢 log_p torch.logsumexp(torch.stack([log_p1 np.log(0.5), log_p2 np.log(0.5)]), dim0) return -log_p # 能量是负对数概率 def energy_gradient(x): 计算能量梯度 \nabla_x U(x) 使用自动微分方便且准确 x x.clone().requires_grad_(True) U energy_function(x) U.backward(torch.ones_like(U)) return x.grad # 2. 朗之万动力学采样函数 def langevin_dynamics_sample(initial_state, step_size, n_steps, burn_in500): 执行朗之万动力学采样 initial_state: 初始状态shape (n_samples, 2) step_size: 步长 gamma n_steps: 总步数 burn_in: 退火步数初始阶段的样本丢弃让链达到平稳分布 x initial_state.clone() samples [] for i in range(n_steps): # 计算当前梯度 grad energy_gradient(x) # 采样随机噪声 noise torch.randn_like(x) # 朗之万更新 x x - step_size * grad torch.sqrt(2 * step_size) * noise # 记录退火后的样本 if i burn_in: samples.append(x.detach().clone()) # 将列表转换为张量 samples torch.stack(samples, dim0) # 如果初始状态是多条链可以合并所有链的样本 samples samples.reshape(-1, 2) return samples # 3. 运行采样 torch.manual_seed(42) initial_state torch.randn(100, 2) * 5.0 # 从较分散的初始点开始模拟100条链 step_size 0.05 n_steps 2000 burn_in 500 samples langevin_dynamics_sample(initial_state, step_size, n_steps, burn_in) # 4. 可视化 plt.figure(figsize(12, 5)) # 子图1目标分布的热力图 plt.subplot(1, 2, 1) x_grid, y_grid np.meshgrid(np.linspace(-6, 6, 200), np.linspace(-6, 6, 200)) grid_points torch.tensor(np.stack([x_grid, y_grid], axis-1), dtypetorch.float32).reshape(-1, 2) with torch.no_grad(): energy_vals energy_function(grid_points) prob_vals torch.exp(-energy_vals).reshape(x_grid.shape) plt.contourf(x_grid, y_grid, prob_vals.numpy(), levels20, cmapReds) plt.title(Target Distribution: Mixture of Two Gaussians) plt.xlabel(x1) plt.ylabel(x2) plt.colorbar(labelProbability Density) # 子图2朗之万动力学采样结果 plt.subplot(1, 2, 2) samples_np samples.numpy() plt.scatter(samples_np[:, 0], samples_np[:, 1], s1, alpha0.5, cblue, labelLangevin Samples) # 绘制真实均值点 plt.scatter([mu1[0], mu2[0]], [mu1[1], mu2[1]], cred, s100, markerx, linewidths3, labelTrue Means) plt.xlim(-6, 6) plt.ylim(-6, 6) plt.title(Samples from Langevin Dynamics) plt.xlabel(x1) plt.ylabel(x2) plt.legend() plt.tight_layout() plt.show()运行这段代码你会看到右侧的采样点云大致覆盖了左侧目标概率分布的高概率区域并且点云清晰地分成了两簇围绕在两个真实均值点周围。这说明朗之万动力学成功地从一个简单的初始分布分散的高斯点采样出了目标混合分布的样本。几个关键的实操要点和观察多条链并行我们初始化了100个点100条链同时进行采样。这是MCMC中的常见技巧可以提高采样效率并有助于诊断采样是否收敛。如果所有链最终都聚集在相同的区域说明采样可能稳定了。退火Burn-in我们丢弃了前500步的样本。在采样初期链可能还没有达到平稳分布即目标分布这些样本不能代表目标分布。丢弃这部分样本是必要的。步长选择step_size0.05是一个需要调参的值。你可以尝试将其改为0.2或0.01观察采样结果的变化。过大步长会导致采样点非常分散甚至溢出边界过小步长则会导致采样点混合缓慢可能需要更多的步数才能看到两个模态。梯度计算我们使用了PyTorch的自动微分backward()来计算能量梯度。在实际的深度学习模型中如基于得分的生成模型这个梯度就是通过神经网络得分网络预测出来的。噪声的重要性你可以尝试将更新公式中的噪声项注释掉即 torch.sqrt(2 * step_size) * noise改为 0再运行一次。你会发现所有点最终都会收敛到两个模态中的一个具体是哪一个取决于初始位置和梯度场而永远无法在另一个模态中出现。这直观地证明了噪声对于探索多模态分布、避免陷入局部极小至关重要。5. 超越基础调参技巧、常见陷阱与进阶变体掌握了基本实现后我们需要讨论一些实践中决定成败的细节。5.1 步长调度与退火策略固定步长往往不是最优选择。常见的策略包括多项式衰减\gamma_t \gamma_0 / (1 a \cdot t)^b其中a, b是超参数。早期大步长快速探索后期小步长精细采样。指数衰减\gamma_t \gamma_0 \cdot d^td是衰减率如0.999。在扩散模型中的应用扩散模型的前向噪声调度如cosine schedule本质上定义了一个随时间衰减的“有效步长”。在采样时也可以采用更激进的步长调度来减少采样步数如DDIM的\eta参数当\eta0时为确定性采样\eta1时对应原始DDPM的朗之万采样。一个实用的建议是监控采样轨迹或样本的统计量如均值、方差。如果这些量在迭代后期仍然剧烈波动可能步长太大如果几乎不动则步长可能太小链混合太慢。5.2 梯度噪声与随机梯度朗之万动力学在机器学习中我们的目标分布通常与数据集有关能量函数U(x)往往是所有数据点损失函数的总和即U(x) \sum_{i1}^N U_i(x)。计算全量梯度\nabla U(x)在大数据集上成本极高。这时就需要随机梯度朗之万动力学SGLD。其思想很简单在每一步我们不是计算全量梯度而是随机采样一个小批量mini-batch数据B用其梯度估计来替代全量梯度x_{t1} x_t - \gamma_t \nabla_x \tilde{U}_B(x_t) \sqrt{2\gamma_t} \cdot \epsilon_t其中\nabla_x \tilde{U}_B(x_t) (N/|B|) \sum_{i \in B} \nabla_x U_i(x_t)是无偏估计。这里有一个巨大的陷阱由于我们使用了带噪声的梯度估计注入的噪声\epsilon_t需要相应调整吗理论上SGLD要求步长序列{\gamma_t}满足Robbins-Monro条件\sum_t \gamma_t \infty且\sum_t \gamma_t^2 \infty。这意味着步长必须衰减到0以确保算法收敛。在实践中我们常常忽略第二个噪声项中的\sqrt{2\gamma_t}因为小批量梯度估计本身已经包含了足够的随机性有时甚至能起到类似的效果。但严格来说为了确保收敛到正确的稳态分布仍需保留它并配合衰减的步长。5.3 预条件化处理各向异性的尺度问题想象一下目标分布在一个方向上非常狭窄方差小在另一个方向上非常宽阔方差大。标准的朗之万动力学对所有维度使用相同的步长\gamma这会导致在狭窄维度上更新可能过大不稳定在宽阔维度上更新又过小混合慢。预条件化朗之万动力学Preconditioned Langevin Dynamics通过引入一个正定预条件矩阵M(x)来解决这个问题x_{t1} x_t - \gamma M(x_t) \nabla_x U(x_t) \sqrt{2\gamma M(x_t)} \cdot \epsilon_t其中\sqrt{M}是矩阵M的平方根如Cholesky分解使得\sqrt{M} \epsilon_t的协方差为M。M(x)的作用是重新缩放参数空间使其更接近各向同性。一个自然的选择是使用Fisher信息矩阵的逆或者在实际中更可行的、其对角近似——RMSProp或Adam优化器中的自适应学习率分量。事实上Adam优化器可以看作是一种带有动量和自适应预条件器的随机梯度朗之万动力学变体。当你使用Adam并设置一个衰减的学习率时你已经在无意中使用一个复杂的MCMC采样器了。5.4 诊断与收敛性判断如何知道朗之万动力学采样是否已经“收敛”这是一个难题尤其是在高维空间。一些实用的诊断方法包括多条链可视化对于低维参数如2-3维直接绘制多条链的轨迹。如果它们从不同的起点出发最终都交织混合在相同的区域是一个好迹象。监控统计量跟踪一些关键量的时间序列如目标函数值U(x_t)、参数的均值/方差等。这些序列应该看起来是“平稳”的没有明显的趋势。自相关性计算样本序列的自相关函数。理想的MCMC采样样本应该是低自相关的快速衰减。高自相关意味着链混合缓慢需要更长的采样时间或调整步长/预条件器。Gelman-Rubin诊断R-hat如果你运行了多条独立的链可以计算R-hat统计量。当R-hat接近1时通常1.1表明多条链可能收敛到了同一分布。5.5 一个经典陷阱能量函数未归一化朗之万动力学要求能量函数U(x)与目标概率分布的对数成线性关系U(x) -\log p(x) C其中C是任意常数。这意味着能量函数可以相差一个常数项不影响梯度。这是一个好消息因为我们通常只知道概率分布p(x)的未归一化形式\tilde{p}(x) \propto p(x)。例如在贝叶斯推断中后验分布p(\theta|D) \propto p(D|\theta)p(\theta)我们只能轻松计算右边的乘积未归一化的后验。这时我们可以直接定义U(\theta) -\log [p(D|\theta)p(\theta)]尽管它不等于真正的负对数后验差一个归一化常数但其梯度\nabla U(\theta)是完全正确的因此可以安全地用于朗之万动力学采样。这个特性使得朗之万动力学及MCMC方法在贝叶斯计算中极其强大因为我们永远不需要计算那个棘手的分母归一化常数也称证据。6. 在贝叶斯推断与深度学习中的实际应用场景朗之万动力学不仅仅是一个理论概念它在多个领域有着扎实的应用。场景一贝叶斯神经网络参数采样传统神经网络训练通过优化如SGD得到一组点估计参数。贝叶斯神经网络则希望得到参数的后验分布p(\theta|D)以量化模型的不确定性。直接计算后验分布是难解的。我们可以利用SGLD来从后验分布中采样参数定义能量函数U(\theta) -\log p(D|\theta) - \log p(\theta)即负对数似然加上负对数先验。初始化参数\theta_0。循环每次迭代随机采样一个小批量数据计算U(\theta)的随机梯度执行SGLD更新。丢弃退火期的样本收集之后的{\theta_t}。这些样本近似来自后验分布。预测时我们可以用这些样本做模型平均得到预测分布从而估计不确定性。场景二能量基模型EBM的训练与采样能量基模型直接定义一个标量能量函数E_\phi(x)来描述数据通过玻尔兹曼分布p_\phi(x) \propto \exp(-E_\phi(x))与概率关联。训练EBM需要从当前模型分布p_\phi(x)中采样负样本与真实数据正样本做对比。朗之万动力学正是从p_\phi(x)中采样的核心工具从噪声或数据中初始化x。执行多步朗之万更新x x - \gamma \nabla_x E_\phi(x) \sqrt{2\gamma} \epsilon。得到的x可作为模型分布的负样本用于计算对比损失更新模型参数\phi。 这个过程被称为“对比散度Contrastive Divergence, CD”或“持续性对比散度PCD”算法的核心步骤。场景三扩散模型/得分匹配模型的采样器如前所述这是朗之万动力学当前最火热的舞台。无论是DDPM、DDIM还是更广义的基于得分的生成模型其采样算法都可以统一在朗之万动力学或相关的随机微分方程求解框架下。研究如何设计更高效、更稳定的离散化方案如SDE/ODE求解器是当前加速扩散模型生成的前沿方向之一。场景四非凸优化中的全局搜索虽然朗之万动力学主要用作采样器但其“梯度下降噪声”的模式也为非凸优化提供了启发。在训练深度神经网络时SGD本身固有的噪声就具有一定的探索能力。一些工作尝试显式地在优化器中注入可控噪声以帮助逃离尖锐的局部极小点寻找更平坦的极小点这被认为可能提升模型的泛化能力。从我个人的项目经验来看将朗之万动力学付诸实践时最需要耐心的是调参尤其是步长和迭代次数。它不像确定性优化那样有一个清晰的“收敛”点。你需要像观察一个物理实验一样观察采样过程链是否在“游荡”而不是发散或停滞样本的统计特性是否稳定多模态分布中各模态的样本比例是否大致符合其概率权重这个过程往往是实证性的需要可视化工具和诊断指标的辅助。但一旦调通它能提供传统优化方法无法给予的东西——对整个概率分布的洞察而不仅仅是一个最优点。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门