网易首页 > 网易号 > 正文 申请入驻

贝叶斯推理三种方法:MCMC 、HMC和SBI

0
分享至

对许多人来说,贝叶斯统计仍然有些陌生。因为贝叶斯统计中会有一些主观的先验,在没有测试数据的支持下了解他的理论还是有一些困难的。本文整理的是作者最近在普林斯顿的一个研讨会上做的演讲幻灯片,这样可以阐明为什么贝叶斯方法不仅在逻辑上是合理的,而且使用起来也很简单。这里将以三种不同的方式实现相同的推理问题。

数据

我们的例子是在具有倾斜背景的噪声数据中找到峰值的问题,这可能出现在粒子物理学和其他多分量事件过程中。

首先生成数据:

%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import matplotlib.pyplot as plt
import numpy as np
def signal(theta, x):
l, m, s, a, b = theta
peak = l * np.exp(-(m-x)**2 / (2*s**2))
background = a + b*x
return peak + background
def plot_results(x, y, y_err, samples=None, predictions=None):
fig = plt.figure()
ax = fig.gca()
ax.errorbar(x, y, yerr=y_err, fmt=".k", capsize=0, label="Data")
x0 = np.linspace(-0.2, 1.2, 100)
ax.plot(x0, signal(theta, x0), "r", label="Truth", zorder=0)
if samples is not None:
inds = np.random.randint(len(samples), size=50)
for i,ind in enumerate(inds):
theta_ = samples[ind]
if i==0:
label='Posterior'
else:
label=None
ax.plot(x0, signal(theta_, x0), "C0", alpha=0.1, zorder=-1, label=label)
elif predictions is not None:
for i, pred in enumerate(predictions):
if i==0:
label='Posterior'
else:
label=None
ax.plot(x0, pred, "C0", alpha=0.1, zorder=-1, label=label)
ax.legend(frameon=False)
ax.set_xlabel("x")
ax.set_ylabel("y")
fig.tight_layout()
plt.close();
return fig
# random x locations
N = 40
np.random.seed(0)
x = np.random.rand(N)
# evaluate the true model at the given x values
theta = [1, 0.5, 0.1, -0.1, 0.4]
y = signal(theta, x)
# add heteroscedastic Gaussian uncertainties only in y direction
y_err = np.random.uniform(0.05, 0.25, size=N)
y = y + np.random.normal(0, y_err)
# plot
plot_results(x, y, y_err)

有了数据我们可以介绍三种方法了

马尔可夫链蒙特卡罗 Markov Chain Monte Carlo

emcee是用纯python实现的,它只需要评估后验的对数作为参数θ的函数。这里使用对数很有用,因为它使指数分布族的分析评估更容易,并且因为它更好地处理通常出现的非常小的数字。

import emcee
def log_likelihood(theta, x, y, yerr):
y_model = signal(theta, x)
chi2 = (y - y_model)**2 / (yerr**2)
return np.sum(-chi2 / 2)
def log_prior(theta):
if all(theta > -2) and (theta[2] > 0) and all(theta < 2):
return 0
return -np.inf
def log_posterior(theta, x, y, yerr):
lp = log_prior(theta)
if np.isfinite(lp):
lp += log_likelihood(theta, x, y, yerr)
return lp
# create a small ball around the MLE the initialize each walker
nwalkers, ndim = 30, 5
theta_guess = [0.5, 0.6, 0.2, -0.2, 0.1]
pos = theta_guess + 1e-4 * np.random.randn(nwalkers, ndim)
# run emcee
sampler = emcee.EnsembleSampler(nwalkers, ndim, log_posterior, args=(x, y, y_err))
sampler.run_mcmc(pos, 10000, progress=True);

结果如下:

100%|██████████| 10000/10000 [00:05<00:00, 1856.57it/s]

我们应该始终检查生成的链,确定burn-in period,并且需要人肉观察平稳性:

fig, axes = plt.subplots(ndim, sharex=True)
mcmc_samples = sampler.get_chain()
labels = ["l", "m", "s", "a", "b"]
for i in range(ndim):
ax = axes[i]
ax.plot(mcmc_samples[:, :, i], "k", alpha=0.3, rasterized=True)
ax.set_xlim(0, 1000)
ax.set_ylabel(labels[i])
axes[-1].set_xlabel("step number");

现在我们需要细化链因为我们的样本是相关的。这里有一个方法来计算每个参数的自相关,我们可以将所有的样本结合起来:

tau = sampler.get_autocorr_time()
print("Autocorrelation time:", tau)
mcmc_samples = sampler.get_chain(discard=300, thin=np.int32(np.max(tau)/2), flat=True)
print("Remaining samples:", mcmc_samples.shape)
#结果
Autocorrelation time: [122.51626866 75.87228105 137.195509 54.63572513 79.0331587 ]
Remaining samples: (4260, 5)

emcee 的创建者 Dan Foreman-Mackey 还提供了这一有用的包corner来可视化样本:

import corner
corner.corner(mcmc_samples, labels=labels, truths=theta);

虽然后验样本是推理的主要依据,但参数轮廓本身却很难解释。但是使用样本来生成新数据则要简单得多,因为这个可视化我们对数据空间有更多的理解。以下是来自50个随机样本的模型评估:

plot_results(x, y, y_err, samples=mcmc_samples)

哈密尔顿蒙特卡洛 Hamiltonian Monte Carlo

梯度在高维设置中提供了更多指导。 为了实现一般推理,我们需要一个框架来计算任意概率模型的梯度。 这里关键的本部分是自动微分,我们需要的是可以跟踪参数的各种操作路径的计算框架。 为了简单起见,我们使用的框架是 jax。因为一般情况下在 numpy 中实现的函数都可以在 jax 中的进行类比的替换,而jax可以自动计算函数的梯度。

另外还需要计算概率分布梯度的能力。有几种概率编程语言中可以实现,这里我们选择了 NumPyro。 让我们看看如何进行自动推理:

import jax.numpy as jnp
import jax.random as random
import numpyro
import numpyro.distributions as dist
from numpyro.infer import MCMC, NUTS
def model(x, y=None, y_err=0.1):
# define parameters (incl. prior ranges)
l = numpyro.sample('l', dist.Uniform(-2, 2))
m = numpyro.sample('m', dist.Uniform(-2, 2))
s = numpyro.sample('s', dist.Uniform(0, 2))
a = numpyro.sample('a', dist.Uniform(-2, 2))
b = numpyro.sample('b', dist.Uniform(-2, 2))
# implement the model
# needs jax numpy for differentiability here
peak = l * jnp.exp(-(m-x)**2 / (2*s**2))
background = a + b*x
y_model = peak + background
# notice that we clamp the outcome of this sampling to the observation y
numpyro.sample('obs', dist.Normal(y_model, y_err), obs=y)
# need to split the key for jax's random implementation
rng_key = random.PRNGKey(0)
rng_key, rng_key_ = random.split(rng_key)
# run HMC with NUTS
kernel = NUTS(model, target_accept_prob=0.9)
mcmc = MCMC(kernel, num_warmup=1000, num_samples=3000)
mcmc.run(rng_key_, x=x, y=y, y_err=y_err)
mcmc.print_summary()
#结果如下:
sample: 100%|██████████| 4000/4000 [00:03<00:00, 1022.99it/s, 17 steps of size 2.08e-01. acc. prob=0.94]
mean std median 5.0% 95.0% n_eff r_hat
a -0.13 0.05 -0.13 -0.22 -0.05 1151.15 1.00
b 0.46 0.07 0.46 0.36 0.57 1237.44 1.00
l 0.98 0.05 0.98 0.89 1.06 1874.34 1.00
m 0.50 0.01 0.50 0.49 0.51 1546.56 1.01
s 0.11 0.01 0.11 0.09 0.12 1446.08 1.00
Number of divergences: 0

还是使用corner可视化Numpyro的mcmc结构:

因为我们已经实现了整个概率模型(与emcee相反,我们只实现后验),所以可以直接从样本中创建后验预测。下面,我们将噪声设置为零,以得到纯模型的无噪声表示:

from numpyro.infer import Predictive
# make predictions from posterior
hmc_samples = mcmc.get_samples()
predictive = Predictive(model, hmc_samples)
# need to set noise to zero
# since the full model contains noise contribution
predictions = predictive(rng_key_, x=x0, y_err=0)['obs']
# select 50 predictions to show
inds = random.randint(rng_key_, (50,) , 0, mcmc.num_samples)
predictions = predictions[inds]
plot_results(x, y, y_err, predictions=predictions)

基于仿真的推理 Simulation-based Inference

在某些情况下,我们不能或不想计算可能性。 所以我们只能一个得到一个仿真器(即学习输入之间的映射 θ 和仿真器的输出 D),这个仿真器可以形成似然或后验的近似替代。 与产生无噪声模型的传统模拟案例的一个重要区别是,需要在模拟中添加噪声并且噪声模型应尽可能与观测噪声匹配。 否则我们无法区分由于噪声引起的数据变化和参数变化引起的数据变化。

import torch
from sbi import utils as utils
low = torch.zeros(ndim)
low[3] = -1
high = 1*torch.ones(ndim)
high[0] = 2
prior = utils.BoxUniform(low=low, high=high)
def simulator(theta, x, y_err):
# signal model
l, m, s, a, b = theta
peak = l * torch.exp(-(m-x)**2 / (2*s**2))
background = a + b*x
y_model = peak + background
# add noise consistent with observations
y = y_model + y_err * torch.randn(len(x))
return y

让我们来看看噪声仿真器的输出:

plt.errorbar(x, this_simulator(torch.tensor(theta)), yerr=y_err, fmt=".r", capsize=0)
plt.errorbar(x, y, yerr=y_err, fmt=".k", capsize=0)
plt.plot(x0, signal(theta, x0), "k", label="truth")

现在,我们使用 sbi 从这些模拟仿真中训练神经后验估计 (NPE)。

from sbi.inference.base import infer
this_simulator = lambda theta: simulator(theta, torch.tensor(x), torch.tensor(y_err))
posterior = infer(this_simulator, prior, method='SNPE', num_simulations=10000)

NPE使用条件归一化流来学习如何在给定一些数据的情况下生成后验分布:

Running 10000 simulations.: 0%| | 0/10000 [00:00

在推理时,以实际数据 y 为条件简单地评估这个神经后验:

sbi_samples = posterior.sample((10000,), x=torch.tensor(y))sbi_samples = sbi_samples.detach().numpy()

可以看到速度非常快几乎不需要什么时间。

Drawing 10000 posterior samples: 0%| | 0/10000 [00:00

然后我们再次可视化后验样本:

corner.corner(sbi_samples, labels=labels, truths=theta);

plot_results(x, y, y_err, samples=sbi_samples)

可以看到仿真SBI的的结果不如 MCMC 和 HMC 的结果。 但是它们可以通过对更多模拟进行训练以及通过调整网络的架构来改进(虽然并不确定改完后就会有提高)。

但是我们可以看到即使在没有拟然性的情况下,SBI 也可以进行近似贝叶斯推理。

https://avoid.overfit.cn/post/7d210cd0e4424371a7d931b6ee247fc7

作者:Peter Melchior

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
枢密院十号:印度也要建第3艘航母了?

枢密院十号:印度也要建第3艘航母了?

环球网资讯
2024-05-17 00:07:26
国家统计局:1—4月份,全国房地产开发投资30928亿元 同比下降9.8%

国家统计局:1—4月份,全国房地产开发投资30928亿元 同比下降9.8%

财联社
2024-05-17 10:06:15
中国终于出手了!只要非法越境者进入南海,海警可直接拘留

中国终于出手了!只要非法越境者进入南海,海警可直接拘留

宇宙看世界啊
2024-05-17 10:49:39
国家统计局:4月各线城市商品住宅销售价格环比、同比降幅均有所扩大

国家统计局:4月各线城市商品住宅销售价格环比、同比降幅均有所扩大

财联社
2024-05-17 09:34:09
亚洲货币保卫战,越南第一个倒下了,曾经被吹上天如今跌落神坛

亚洲货币保卫战,越南第一个倒下了,曾经被吹上天如今跌落神坛

担扑
2024-05-16 18:07:04
新型卖淫方式,让人预想不到,但却真实存在!

新型卖淫方式,让人预想不到,但却真实存在!

雪影的情感
2023-11-18 11:51:16
美国大桥被撞断七周了,全体船员居然还在船上!不是坐牢,胜似坐牢...

美国大桥被撞断七周了,全体船员居然还在船上!不是坐牢,胜似坐牢...

英国那些事儿
2024-05-16 23:03:56
中国曾三次忍辱负重“装孙子”,完美躲过美国制裁!最终迎来崛起

中国曾三次忍辱负重“装孙子”,完美躲过美国制裁!最终迎来崛起

猫眼观史
2024-05-16 18:11:46
打开国门,也融不进现代文明

打开国门,也融不进现代文明

更夫频道
2024-05-16 10:41:47
黄晓明叶珂秀恩爱,女方婚礼吃席男方发视频祝福,与杨颖复合无望

黄晓明叶珂秀恩爱,女方婚礼吃席男方发视频祝福,与杨颖复合无望

不八卦会死星人
2024-05-16 17:59:45
马斯克:低生育率是文明衰落重要原因,对中国人不生孩子深表关切

马斯克:低生育率是文明衰落重要原因,对中国人不生孩子深表关切

大风文字
2024-05-10 12:05:45
50岁大姐,每个月保持3次性生活,已坚持多年,身体指标让人羡慕

50岁大姐,每个月保持3次性生活,已坚持多年,身体指标让人羡慕

39健康网
2024-05-16 23:00:31
俄罗斯用无数年轻人的伤亡,去换取不稀缺的土地,令人费解

俄罗斯用无数年轻人的伤亡,去换取不稀缺的土地,令人费解

高博新视野
2024-05-16 18:41:29
南京男子扶醉酒摔倒老人反被诬陷,家属张口就要赔偿,拒绝看监控

南京男子扶醉酒摔倒老人反被诬陷,家属张口就要赔偿,拒绝看监控

行侠掌轶i
2024-05-16 18:09:43
曝法国没收中国富豪9座酒庄,涉嫌挪用辽宁省和大连市政府3200万欧元补贴所购

曝法国没收中国富豪9座酒庄,涉嫌挪用辽宁省和大连市政府3200万欧元补贴所购

西游日记
2024-05-16 14:26:32
男生宿舍考公“入戏太深”,清一色的行政夹克,校长:比我还有派

男生宿舍考公“入戏太深”,清一色的行政夹克,校长:比我还有派

熙熙说教
2024-05-16 17:25:18
1971年,张万年突然接到领导电话:稳住师政委,千万别让他跑了

1971年,张万年突然接到领导电话:稳住师政委,千万别让他跑了

平安是福呀
2024-05-13 00:34:16
在5个关键摇摆州全面落后,拜登向特朗普下“战书”

在5个关键摇摆州全面落后,拜登向特朗普下“战书”

界面新闻
2024-05-16 19:19:25
普京访华竟然出现搞笑一幕!旁边另外安排四桌,都是企业家

普京访华竟然出现搞笑一幕!旁边另外安排四桌,都是企业家

小布丁看各种书籍
2024-05-16 15:11:21
网传某地30个城管对3个女人暴力执法,抢走一箱水果一个冰柜!

网传某地30个城管对3个女人暴力执法,抢走一箱水果一个冰柜!

兵叔评说
2024-05-17 10:19:03
2024-05-17 12:52:49
deephub
deephub
CV NLP和数据挖掘知识
1341文章数 1414关注度
往期回顾 全部

科技要闻

美媒谈电动车关税:美国,别再装受害者了

头条要闻

男子因建行信用卡逾期频遭第三方催收:1天十几个电话

头条要闻

男子因建行信用卡逾期频遭第三方催收:1天十几个电话

体育要闻

生命最后一年,他决定完成自己的“遗愿清单”

娱乐要闻

《庆余年2》首播口碑出炉!有好有坏

财经要闻

房地产走势?公用事业涨价?统计局回应

汽车要闻

内饰改款/功能升级 新博越L将于5月19日上市

态度原创

游戏
亲子
健康
数码
时尚

LOL新版本最大受益者出现?一个E技能秒坦克,中单玩家上分首选

亲子要闻

东北孩子吃饭就要大大方方,小女孩吃饭疯狂“炫”

在中国,到底哪些人在吃“伟哥”?

数码要闻

百亿补贴来了!RX7900XT极地版OC降价

别总是穿牛仔裤了!夏天中年女人这么搭配,通勤休闲都美极了

无障碍浏览 进入关怀版