使用 Pyro 实现图形模型的问题

Problem in Implementing a Graphical Model Using Pyro

我正在尝试使用 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', dist.Beta(1, 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', dist.Beta(1, 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)