问题描述
我正在尝试使用 Pyro 实现这个图形模型:
我的实现是:
def model(data):
p = pyro.sample('p',dist.Beta(1,1))
label_axis = pyro.plate("label_axis",data.shape[0],dim=-3)
f_axis = pyro.plate("f_axis",data.shape[1],dim=-2)
with label_axis:
l = pyro.sample('l',dist.Bernoulli(p))
with f_axis:
e = pyro.sample('e',10))
with label_axis,f_axis:
f = pyro.sample('f',dist.Bernoulli(1-e),obs=data)
f = l*f + (1-l)*(1-f)
return f
然而,这对我来说似乎不正确。问题是“f”。由于其分布与伯努利不同。为了从 f 中采样,我使用了伯努利分布中的一个样本,然后在 l=0 时更改了采样值。但我认为这不会改变 Pyro 在幕后为“f”存储的值。这在推理时会出现问题,对吗?
我想使用迭代板而不是矢量化板,以便能够在我的板中使用控制语句。但显然,这是不可能的,因为我正在重复使用盘子。
如何正确实施此 pgm?我需要编写自定义发行版吗?或者我可以破解 Pyro 并自己更改“f”的存储值?任何类型的帮助表示赞赏!干杯!
解决方法
这是正确的实现:
import pyro
import pyro.distributions as dist
from pyro.infer import MCMC,NUTS
def model(data):
p = pyro.sample('p',dist.Beta(1,1))
label_axis = pyro.plate("label_axis",data.shape[0],dim=-2)
f_axis = pyro.plate("f_axis",data.shape[1],dim=-1)
with label_axis:
l = pyro.sample('l',dist.Bernoulli(p))
with f_axis:
e = pyro.sample('e',10))
with label_axis,f_axis:
prob = l * (1 - e) + (1 - l) * e
return pyro.sample('f',dist.Bernoulli(prob),obs=data)
mcmc = MCMC(NUTS(model),500,500)
data = dist.Bernoulli(0.5).sample((20,4))
mcmc.run(data)