基础的贝叶斯神经网络(BNN)回归

下面是一个最基础的贝叶斯神经网络(BNN)回归示例,采用PyTorch实现,适合入门理解。
这个例子用BNN拟合 y = x + 噪声 的一维回归问题,输出均值和不确定性(方差)。

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

# 1. 生成数据
np.random.seed(0)
x = np.linspace(-3, 3, 100)
y = x + np.random.normal(0, 0.5, size=x.shape)

# 转为torch tensor
x_train = torch.tensor(x, dtype=torch.float32).unsqueeze(1)
y_train = torch.tensor(y, dtype=torch.float32).unsqueeze(1)

# 2. 定义贝叶斯回归网络(输出均值和log方差)
class BayesianRegressor(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(1, 32), nn.ReLU(),
            nn.Linear(32, 32), nn.ReLU(),
            nn.Linear(32, 2) # 输出均值和log方差
        )
    def forward(self, x):
        out = self.net(x)
        mean = out[:, 0:1]
        logvar = out[:, 1:2]
        return mean, logvar

# 3. 贝叶斯损失函数(负对数似然)
def bayesian_loss(mean, logvar, target):
    # 对应N(y|mean, exp(logvar))
    return (0.5 * torch.exp(-logvar) * (target - mean) ** 2 + 0.5 * logvar).mean()

# 4. 训练网络
model = BayesianRegressor()
optimizer = optim.Adam(model.parameters(), lr=0.01)

for epoch in range(2000):
    mean, logvar = model(x_train)
    loss = bayesian_loss(mean, logvar, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    if (epoch+1) % 200 == 0:
        print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")

# 5. 预测与可视化
x_test = torch.linspace(-3, 3, 100).unsqueeze(1)
mean_pred, logvar_pred = model(x_test)
mean_pred = mean_pred.detach().numpy().flatten()
std_pred = torch.exp(0.5 * logvar_pred).detach().numpy().flatten()

plt.figure(figsize=(8, 5))
plt.scatter(x, y, label='Data', color='gray', s=10)
plt.plot(x, x, 'g--', label='True function')
plt.plot(x_test, mean_pred, 'b-', label='BNN mean')
plt.fill_between(x_test.flatten(), mean_pred-2*std_pred, mean_pred+2*std_pred, color='orange', alpha=0.3, label='BNN ±2std')
plt.legend()
plt.title("Simple Bayesian Neural Network Regression")
plt.show()

### 贝叶斯神经网络 (BNN) 介绍 贝叶斯神经网络是一种概率模型,它通过引入不确定性来改进传统神经网络的表现。与标准前馈神经网络不同,在训练完成后权重固定为特定数值;而在贝叶斯框架下,权重被视作随机变量并假设它们遵循某种先验分布——通常是正态分布[^3]。 #### 数学表示 对于给定的数据集 \(D\) 和模型参数 \(\theta\), 使用贝叶斯法则可以得到后验概率: \[ p(\theta|D)=\frac{p(D|\theta)p(\theta)}{\int_{\Theta}p(D|\theta')p(\theta')d\theta'} \] 其中: - \(p(D | θ)\): 给定参数下的似然函数. - \(p(θ)\): 参数的先验分布. 由于计算上述积分通常非常困难, 实际应用中常采用近似方法如变分推断来进行估计[^2]. ### 工作原理 在贝叶斯神经网络中,每层之间的连接权值不是单一确定性的数而是由一个均值μ和方差δ定义的概率密度函数描述。这意味着每次预测时都会采样一组新的权重用于推理过程,从而允许模型表达对输入数据不确定性的度量。这种特性使得BNN特别适合处理具有噪声标签的任务以及探索未知区域中的泛化能力[^1]。 为了学习这些分布而不是具体的点估计值,贝叶斯神经网络的目标是在最大化边缘似然的同时最小化KL散度损失项,即寻找最优解使真实后验尽可能接近所选的简单形式q(w). ```python import torch from pyro.nn import PyroModule_, PyroSample_ from pyro.infer.autoguide import AutoDiagonalNormal from pyro.infer.mcmc.api import MCMC from pyro.distributions import Normal class BayesianNet(PyroModule_): def __init__(self): super().__init__() self.linear = PyroModule_[torch.nn.Linear](input_dim, output_dim) self.linear.weight = PyroSample_(dist.Normal(loc=0., scale=1.).expand([output_dim, input_dim]).to_event(2)) def forward(self, x, y=None): logits = self.linear(x).squeeze(-1) with pyro.plate("data", x.shape[0]): obs = pyro.sample("obs", dist.Bernoulli(logits=logits), obs=y) return logits ``` 此代码片段展示了如何利用PyTorch和Pyro库构建简单的二分类贝叶斯线性回归器. ### 应用场景 贝叶斯神经网络因其能够量化预测不确定性而广泛应用于多个领域内,特别是在那些决策依赖于可靠置信区间的情况下尤为有用。典型的应用案例包括但不限于自动驾驶汽车感知系统、医疗诊断辅助工具开发等领域.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

V建模忠哥V

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值