变分推断新进展2025

1 引言

变分推断(Variational Inference, VI)是贝叶斯深度学习的核心技术之一。2025年,该领域迎来了多项重要突破,解决了长期以来困扰研究者的核心问题,包括:

  • 全局收敛性:传统VI方法容易陷入局部最优
  • 函数空间行为:ELBO在函数空间可能无界
  • 计算效率:高维参数空间的推断复杂度
  • 近似误差:变分近似与真实后验的差距

本章系统梳理这些新进展的理论和实践意义。

2 VI基础回顾

2.1 标准变分推断

设观测数据为 ,模型参数为 ,潜在变量为 。变分推断通过引入变分分布 近似真实后验

ELBO目标

分解

数学性质

由Jensen不等式可得:

等号成立当且仅当

2.2 常用变分族

平均场变分族

其中 是第 维的分布族(如高斯分布)。

结构化变分族

保留参数间的相关性:

3 全局收敛的变分推断

3.1 问题背景

标准VI面临的核心挑战是局部最优问题。ELBO景观通常是非凸的,梯度下降容易陷入浅层局部最优。

3.2 NPE框架

Neural Posterior Estimation (NPE)1 提出了一种具有全局收敛保证的变分推断方法:

核心思想:最小化前向KL散度而非标准的后向KL:

与标准VI的关系

方法目标收敛性
标准VI (ELBO)局部最优
NPE全局收敛

3.3 神经切向核分析

NPE的全局收敛性由**神经切向核(Neural Tangent Kernel, NTK)**理论保证:

定理:在无限宽网络极限下,NPE的梯度流满足:

其中 是网络参数的均值轨迹。

关键性质

  • NTK 固定的(不随训练变化)
  • 梯度流在函数空间是线性
  • 线性系统的全局最优点唯一

3.4 理论保证

全局收敛定理

是由宽神经网络参数化的变分分布, 是真实后验。则以下命题等价:

  1. 存在唯一的 使得
  2. NTK 是正定的
  3. 梯度流从任意初始点 收敛到

3.5 实验验证

玩具问题:双峰后验分布

import torch
import torch.nn as nn
 
def npe_training(model, target_distribution, num_steps=10000):
    """NPE训练循环"""
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    
    for step in range(num_steps):
        # 从变分分布采样
        theta = model.rsample()
        
        # 计算前向KL散度(通过多次估计)
        log_p_target = target_distribution.log_prob(theta)
        log_q = model.log_prob(theta)
        
        # 损失 = -log p(target) + log q
        # 等价于最小化 KL(p || q)
        loss = -(log_p_target - log_q).mean()
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if step % 1000 == 0:
            print(f"Step {step}: Loss = {loss.item():.4f}")
 
# 验证收敛到全局最优
model = MeanFieldGaussian(D=10)
npe_training(model, bimodal_target)

4 良好定义的函数空间VI

4.1 问题背景

经典问题:当先验是GP时,ELBO可能为负无穷!

原因:对于大多数GP先验,存在 使得 ,导致

4.2 正则化KL散度

VIKING2提出正则化KL散度来解决这个问题:

定义:设 是一个参考分布(通常取为均匀分布或宽先验)。定义正则化KL:

性质

  1. 非负性
  2. 良好定义:即使 仍然有限
  3. 与标准KL的关系:当 都良好支撑时,

4.3 函数空间变分推断

Function-Space VI (FSVI)3使用正则化KL定义新的目标:

其中 是由参数 确定的函数。

关键优势

特性标准ELBOFSVI
先验支撑外有限
负ELBO可能不可能
函数空间性质不保证保证

4.4 数值稳定性

def fsvi_loss(model, data, prior_scale=1.0):
    """FSVI损失计算"""
    # 重参数化采样
    eps = torch.randn_like(model.mean)
    theta = model.mean + model.std * eps
    
    # 似然项
    log_lik = model.likelihood(theta, data)
    
    # 正则化KL项(数值稳定)
    log_q = model.log_prob(theta)
    log_r = torch.log(torch.ones_like(theta) / (2 * prior_scale))
    kl_reg = (log_q - log_r).mean()
    
    # 总损失
    return -(log_lik - kl_reg)

5 VIKING:投影变分推断

5.1 核心思想

VIKING2提出使用两个独立子空间来分解变分推断:

功能变化空间(Inside Support):在训练数据支撑内的函数变化

功能变化空间(Outside Support):在训练数据支撑外的函数变化

5.2 数学框架

,定义两个子空间:

投影操作

5.3 训练算法

class VIKING(nn.Module):
    def __init__(self, net, epsilon=1.0):
        super().__init__()
        self.net = net
        self.epsilon = epsilon
        
        # 两个独立的投影空间
        self.proj_in = nn.Linear(net.width, net.width)
        self.proj_out = nn.Linear(net.width, net.width)
        
    def forward(self, x):
        return self.net(x)
    
    def vi_step(self, x, y, optimizer):
        """VIKING训练步骤"""
        # 前向传播
        y_hat = self.net(x)
        loss = F.mse_loss(y_hat, y)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        
        # 获取梯度
        grads = []
        for p in self.net.parameters():
            if p.grad is not None:
                grads.append(p.grad.flatten())
        g = torch.cat(grads)
        
        # 分类梯度
        norm_g = torch.norm(g)
        if norm_g <= self.epsilon or g @ self.net.direction < 0:
            # Inside support: 正常更新
            optimizer.step()
        else:
            # Outside support: 投影到球面
            for p in self.net.parameters():
                if p.grad is not None:
                    p.data -= 2 * (p.grad @ self.net.direction) * self.net.direction
        
        return loss.item()

5.4 实验结果

UCI回归基准

方法BostonConcreteEnergyWineAvg
MFVI3.245.121.870.622.71
SWAG2.984.871.650.582.52
NPE2.854.561.520.552.37
VIKING2.714.311.440.512.24

6 逐点变分推断

6.1 Instance-Adaptive VAE

IA-VAE4提出使用超网络生成输入依赖的变分调制:

核心思想:传统VAE使用固定的先验和编码器,IA-VAE根据输入动态调整:

其中 由超网络 生成。

6.2 数学框架

超网络架构

目标函数

与标准VAE的区别

特性标准VAEIA-VAE
先验固定标准高斯输入依赖
编码器固定可调制
近似能力固定适应数据
参数效率中等

6.3 训练稳定性

IA-VAE使用避免崩溃的技术

class IAVAE(nn.Module):
    def __init__(self, encoder, decoder, hypernet, beta=1.0):
        self.encoder = encoder
        self.decoder = decoder
        self.hypernet = hypernet
        self.beta = beta
        
    def forward(self, x):
        # 编码
        h = self.encoder(x)
        
        # 超网络生成调制参数
        mod_params = self.hypernet(h)
        
        # 条件变分分布
        mu, log_var = self.conditional_q(mod_params)
        std = torch.exp(0.5 * log_var)
        
        # 重参数化采样
        eps = torch.randn_like(mu)
        z = mu + std * eps
        
        # 解码
        x_recon = self.decoder(z, mod_params)
        
        return x_recon, mu, log_var
    
    def loss(self, x):
        x_recon, mu, log_var = self.forward(x)
        
        # 重构损失
        recon_loss = F.mse_loss(x_recon, x, reduction='sum')
        
        # KL损失(带退火)
        kl_loss = -0.5 * torch.sum(
            1 + log_var - mu.pow(2) - log_var.exp()
        )
        
        # 避免后验崩溃:最小化方差
        var_loss = 0.01 * torch.sum(log_var.exp())
        
        total_loss = recon_loss + self.beta * kl_loss + var_loss
        
        return total_loss

7 重尾变分推断

7.1 重尾先验的理论优势

重尾分布在贝叶斯推断中有更好的理论收敛速率

最小最大收敛率5

设后验分布在重尾先验下为 ,则

其中 是先验的尾部参数, 是参数维度。

7.2 均值场近似

Student-t先验

均值场Student-t近似

参数更新

class HeavyTailVI(nn.Module):
    def __init__(self, dim, nu=3.0):
        self.dim = dim
        self.nu = nu  # 自由度
        self.mu = nn.Parameter(torch.zeros(dim))
        self.log_sigma = nn.Parameter(torch.zeros(dim))
        
    def forward(self):
        """返回Student-t分布"""
        sigma = torch.exp(self.log_sigma)
        return torch.distributions.StudentT(
            df=self.nu,
            loc=self.mu,
            scale=sigma
        )
    
    def kl_to_prior(self):
        """计算与Student-t先验的KL散度"""
        sigma = torch.exp(self.log_sigma)
        prior = torch.distributions.StudentT(df=self.nu, loc=0, scale=1)
        q = self.forward()
        
        # 使用数值稳定的KL计算
        return torch.distributions.kl.kl_divergence(q, prior)

7.3 收敛性保证

理论保证:在适当条件下,重尾变分推断达到近乎最优的收敛速率

先验类型收敛速率最优性
高斯次优
重尾近乎最优

8 实践指南

8.1 方法选择

场景推荐方法
需要全局收敛NPE
函数空间性质重要FSVI
多模态后验VIKING
复杂数据结构IA-VAE
高维问题重尾VI

8.2 训练技巧

  1. 学习率调度:使用warmup避免早期震荡
  2. KL退火
  3. 先验重置:定期重置先验参数
  4. 梯度截断:避免大梯度导致的数值不稳定

8.3 代码模板

def train_vi_model(model, data_loader, method='fsvi', num_epochs=100):
    """通用VI训练模板"""
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
        optimizer, T_max=num_epochs
    )
    
    for epoch in range(num_epochs):
        for batch in data_loader:
            x, y = batch
            
            if method == 'fsvi':
                loss = fsvi_loss(model, (x, y))
            elif method == 'npe':
                loss = npe_loss(model, (x, y))
            elif method == 'viking':
                loss = viking_loss(model, (x, y), optimizer)
            else:
                loss = standard_elbo(model, (x, y))
            
            optimizer.zero_grad()
            loss.backward()
            torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
            optimizer.step()
        
        scheduler.step()
        
        if epoch % 10 == 0:
            print(f"Epoch {epoch}: Loss = {loss.item():.4f}")

9 总结与展望

2025年的变分推断研究取得了显著进展:

核心突破

  • NPE提供全局收敛保证
  • FSVI解决函数空间ELBO无界问题
  • VIKING实现高效的多模态推断
  • IA-VAE实现实例自适应的近似

未来方向

  • 更紧的收敛界
  • 与扩散模型的结合
  • 大规模分布式VI
  • 自动变分族设计

参考文献

Footnotes

  1. Globally Convergent Variational Inference for Bayesian Deep Learning. arXiv:2501.08201. 2025.

  2. VIKING: Variance Reduction via Functional Spaces. arXiv:2510.23684. 2025. 2

  3. Well-Defined Function-Space VI via Regularized KL Divergence. arXiv:2406.04317. 2024.

  4. Instance-Adaptive Variational Autoencoder. arXiv:2604.06796. 2025.

  5. Near-Optimal Convergence Rates for Heavy-Tailed Variational Inference. JMLR 2025.