PINNs 不确定性量化

1. 引言

不确定性量化(Uncertainty Quantification, UQ)是科学机器学习的核心挑战之一。在Physics-Informed Neural Networks (PINNs) 中,UQ对于评估预测可靠性、识别模型缺陷至关重要。NeurIPS 2025的最新研究1提出了基于Extended Fiducial Inference (EFI) 的新框架,极大提升了PINNs的可靠性与可解释性。


2. 不确定性来源

2.1 偶然不确定性(Aleatoric Uncertainty)

由数据本身的随机性产生,不可减少:

  • 测量噪声
  • 传感器精度限制
  • 物理过程的固有随机性

2.2 认知不确定性(Epistemic Uncertainty)

由模型知识不足产生,理论上可通过更多数据减少:

  • 模型参数不确定性
  • 模型结构不确定性
  • 物理参数不确定性

2.3 混合不确定性

实际应用中,两种不确定性通常同时存在:


3. 贝叶斯PINNs

3.1 贝叶斯框架

将网络权重视为随机变量,使用贝叶斯推断:

其中:

  • :似然函数
  • :先验
  • :物理一致性先验

3.2 变分推断近似

使用变分分布 近似后验:

损失函数:

3.3 随机Dropout实现

利用Dropout作为贝叶斯近似2

class BayesianPINN(nn.Module):
    def __init__(self, layers, p_dropout=0.1):
        super().__init__()
        self.layers = nn.ModuleList([
            nn.Linear(layers[i], layers[i+1]) 
            for i in range(len(layers)-1)
        ])
        self.p_dropout = p_dropout
        self.activation = nn.Tanh()
    
    def forward(self, x, t, training=True):
        h = torch.cat([x, t], dim=1)
        for i, layer in enumerate(self.layers[:-1]):
            h = layer(h)
            h = self.activation(h)
            if training:
                h = nn.functional.dropout(h, p=self.p_dropout, training=True)
        return self.layers[-1](h)
    
    def predict_with_uncertainty(self, x, t, n_samples=100):
        """MC Dropout for uncertainty estimation"""
        predictions = []
        for _ in range(n_samples):
            pred = self.forward(x, t, training=True)
            predictions.append(pred)
        
        predictions = torch.stack(predictions)
        mean = predictions.mean(dim=0)
        std = predictions.std(dim=0)
        
        return mean, std

4. Extended Fiducial Inference (EFI)

4.1 Fiducial Inference回顾

Fiducial推断提供了一种无需先验的推断框架。设数据 由参数 通过模型 生成:

其中 为标准随机变量。

4.2 EFI框架

NeurIPS 2025提出的EFI框架1用于PINNs:

核心思想:将物理约束编码为fiducial分布的约束。

数学形式化

定义fiducial分布:

映射到参数空间:

其中 是由PDE 定义的映射。

4.3 大规模模型应用

传统EFI的挑战:

  • 需要计算 Hessian 矩阵
  • 稀疏超网络(sparse hyper-networks)开销大

新方法

  • 无需显式Hessian计算
  • 自动微分驱动的推断
  • 可扩展到大参数空间
# EFI框架简化实现
class EFIPINN:
    def __init__(self, model, pde_residual):
        self.model = model
        self.pde = pde_residual
        self.optimizer = torch.optim.Adam(model.parameters())
    
    def fiducial_sample(self, z, x, t):
        """
        生成fiducial样本
        z: 标准正态样本 (n_samples, latent_dim)
        """
        # 可学习的变换
        theta = self.latent_to_params(z)
        
        # 设置模型参数
        self.set_parameters(theta)
        
        # 计算预测和残差
        u = self.model(x, t)
        residual = self.pde(u, x, t)
        
        return u, residual
    
    def efi_loss(self, x, t, u_obs, n_fiducial=50):
        """
        EFI损失函数
        """
        # 生成fiducial样本
        z = torch.randn(n_fiducial, self.latent_dim)
        
        u_samples = []
        for zi in z:
            u, _ = self.fiducial_sample(zi, x, t)
            u_samples.append(u)
        
        u_samples = torch.stack(u_samples)
        
        # Fiducial统计量
        u_mean = u_samples.mean(dim=0)
        u_var = u_samples.var(dim=0)
        
        # 拟合优度损失
        loss_fit = nn.MSELoss()(u_mean, u_obs)
        
        # Fiducial一致性损失
        # 基于残差的方差
        residual_var = torch.var(self.pde(u_samples, x, t), dim=0).mean()
        
        return loss_fit + 0.1 * residual_var

5. 随机微分方程视角

5.1 SDE建模

将PINNs的预测视为随机过程:

其中

5.2 异方差不确定性

假设噪声方差依赖于输入:

class HeteroscedasticPINN(nn.Module):
    def __init__(self, backbone_dim):
        super().__init__()
        self.backbone = PINNBackbone(backbone_dim)
        self.mean_head = nn.Linear(hidden_dim, 1)
        self.var_head = nn.Sequential(
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, 1),
            nn.Softplus()  # 确保方差为正
        )
    
    def forward(self, x, t):
        h = self.backbone(x, t)
        mean = self.mean_head(h)
        var = self.var_head(h)
        return mean, var

5.3 不确定性传播

定理(不确定性传播):设输入不确定性 ,输出不确定性 ,则:


6. 物理约束的不确定性

6.1 PDE参数不确定性

考虑PDE参数 的不确定性:

联合不确定性

class ParametricPINN(nn.Module):
    def __init__(self, n_params):
        super().__init__()
        self.pinn = PINNBackbone()
        # 参数的均值和方差
        self.param_mean = nn.Parameter(torch.zeros(n_params))
        self.param_log_var = nn.Parameter(torch.zeros(n_params))
    
    def forward(self, x, t):
        # 采样参数
        if self.training:
            std = torch.exp(0.5 * self.param_log_var)
            params = self.param_mean + std * torch.randn_like(self.param_mean)
        else:
            params = self.param_mean
        
        # 使用采样参数求解
        return self.pinn(x, t, params)

6.2 不确定边界条件

class UncertainBCPINN:
    def __init__(self, base_pinn, bc_std=0.1):
        self.pinn = base_pinn
        self.bc_std = bc_std
    
    def bc_loss(self, x_bc, t_bc):
        """
        不确定边界条件损失
        """
        u_pred = self.pinn(x_bc, t_bc)
        
        # 假设边界条件为高斯
        # 计算预测边界与均值边界的差异
        bc_mean = self.pinn.bc_mean_fn(x_bc, t_bc)
        bc_loss = torch.mean((u_pred - bc_mean)**2)
        
        # 不确定性惩罚:鼓励预测接近观测
        uncertainty_penalty = torch.mean(self.bc_std**2)
        
        return bc_loss + uncertainty_penalty

7. 不确定性校准

7.1 校准定义

预测区间覆盖率(PICP):

目标覆盖率:

7.2 校准损失

Sharqeti分数

7.3 校准方法

class CalibratedPINN:
    def __init__(self, pinn):
        self.pinn = pinn
        self.calibration_scaler = nn.Parameter(torch.tensor(1.0))
    
    def get_prediction_interval(self, x, t, alpha=0.05):
        mean, std = self.pinn.predict_with_uncertainty(x, t)
        
        # 缩放标准差
        k = torch.tensor(1.96)  # 95% interval
        scaled_std = self.calibration_scaler * std
        
        lower = mean - k * scaled_std
        upper = mean + k * scaled_std
        
        return lower, upper, mean, scaled_std
    
    def calibration_loss(self, x_val, t_val, y_val):
        """
        基于验证集的校准损失
        """
        lower, upper, mean, std = self.get_prediction_interval(x_val, t_val)
        
        # PICP损失
        in_interval = ((y_val >= lower) & (y_val <= upper)).float()
        picp = in_interval.mean()
        
        # 宽度惩罚(避免过度自信)
        width_penalty = torch.mean(std)
        
        # 校准损失:鼓励PICP接近目标覆盖率
        target_coverage = 0.95
        coverage_loss = (picp - target_coverage)**2
        
        return coverage_loss + 0.01 * width_penalty

8. 实践指南

8.1 方法选择

场景推荐方法
快速原型MC Dropout
精确不确定性贝叶斯变分推断
大规模模型EFI框架
实时应用异方差回归

8.2 评估指标

  1. NLL (Negative Log-Likelihood):概率预测质量
  2. CRPS (Continuous Ranked Probability Score):分布预测质量
  3. ECE (Expected Calibration Error):校准质量
  4. Sharpness:预测区间宽度
def evaluate_uncertainty(mean, std, y_true):
    """
    评估不确定性预测质量
    """
    # NLL
    nll = 0.5 * torch.log(std**2) + 0.5 * ((y_true - mean)**2 / std**2)
    
    # CRPS (简化版)
    z = (y_true - mean) / (std + 1e-8)
    crps = std * (z * (2 * torch.norm.cdf(z) - 1) + 2 * torch.norm.pdf(z) - 1/np.sqrt(np.pi))
    
    return {
        'nll': nll.mean().item(),
        'crps': crps.mean().item()
    }

8.3 常见陷阱

  1. 过度自信:MC Dropout可能低估不确定性
  2. 欠校准:未使用验证集校准
  3. 忽略物理约束:不确定性应满足物理规律

9. 应用案例

9.1 天气预报

利用PINNs进行降水预测:

  • 偶然不确定性:观测噪声
  • 认知不确定性:模型结构不确定性

9.2 材料科学

预测材料性质:

  • 参数不确定性:制造工艺变异
  • 预测不确定性:材料性能变异

9.3 医学图像重建

联邦学习隐私保护下的PINNs:

  • 分布式数据的不确定性聚合
  • 跨机构预测的可靠性评估

10. 参考文献


相关主题

Footnotes

  1. Shih, F., et al. (2025). Uncertainty Quantification for Physics-Informed Neural Networks with Extended Fiducial Inference. NeurIPS 2025. 2

  2. Gal, Y., & Ghahramani, Z. (2016). Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning. ICML 2016.