【问题标题】:Why does all my emission mu of HMM in pyro converge to the same number?为什么我在 pyro 中 HMM 的所有发射 mu 都收敛到相同的数字?
【发布时间】:2022-09-24 06:33:18
【问题描述】:

我试图在 pyro 中创建一个高斯 HMM 模型来推断一个非常简单的马尔可夫序列的参数。但是,我的模型无法推断参数,并且在训练过程中发生了一些相关的事情。使用相同的序列,hmmlearn 已成功推断出真实参数。

完整代码可以在这里访问:

https://colab.research.google.com/drive/1u_4J-dg9Y1CDLwByJ6FL4oMWMFUVnVNd#scrollTo=ZJ4PzdTUBgJi

我的模型是根据此处的示例修改的:

https://github.com/pyro-ppl/pyro/blob/dev/examples/hmm.py

我手动创建了一个一阶马尔可夫序列,其中有 3 个状态,真正的均值是 [-10, 0, 10],sigmas 是 [1,2,1]。

这是我的模型

def model(observations, num_state):
    
    assert not torch._C._get_tracing_state()

    with poutine.mask(mask = True):
  
        p_transition = pyro.sample(\"p_transition\",
                                   dist.Dirichlet((1 / num_state) * torch.ones(num_state, num_state)).to_event(1))
        
        p_init = pyro.sample(\"p_init\",
                             dist.Dirichlet((1 / num_state) * torch.ones(num_state)))
        
    p_mu = pyro.param(name = \"p_mu\",
                      init_tensor = torch.randn(num_state),
                      constraint = constraints.real)

    p_tau = pyro.param(name = \"p_tau\",
                       init_tensor = torch.ones(num_state),
                       constraint = constraints.positive)


    current_state = pyro.sample(\"x_0\",
                                dist.Categorical(p_init),
                                infer = {\"enumerate\" : \"parallel\"})
    

    for t in pyro.markov(range(1, len(observations))):

        current_state = pyro.sample(\"x_{}\".format(t),
                                    dist.Categorical(Vindex(p_transition)[current_state, :]),
                                    infer = {\"enumerate\" : \"parallel\"})
        

        pyro.sample(\"y_{}\".format(t),
                    dist.Normal(Vindex(p_mu)[current_state], Vindex(p_tau)[current_state]),
                    obs = observations[t])

我的模型编译为

device = torch.device(\"cuda:0\")
obs = torch.tensor(obs)
obs = obs.to(device)

torch.set_default_tensor_type(\"torch.cuda.FloatTensor\")

guide = AutoDelta(poutine.block(model, expose_fn = lambda msg : msg[\"name\"].startswith(\"p_\")))

Elbo = Trace_ELBO
elbo = Elbo(max_plate_nesting = 1)


optim = Adam({\"lr\": 0.001})
svi = SVI(model, guide, optim, elbo)

随着训练的进行,ELBO 如图所示稳步下降。但是,状态的三种方式是会聚的。

我试图将模型的 for 循环放入 pyro.plate 并将 pyro.param 切换为 pyro.sample ,反之亦然,但对我的模型没有任何作用。

    标签: machine-learning pytorch statistics artificial-intelligence pyro


    【解决方案1】:

    我没有尝试过这个模型,但我认为应该可以通过以下方式修改模型来解决问题: def 模型(观察,num_state):

    assert not torch._C._get_tracing_state()
    
    with poutine.mask(mask = True):
    
        p_transition = pyro.sample("p_transition",
                                dist.Dirichlet((1 / num_state) * torch.ones(num_state, num_state)).to_event(1))
    
        p_init = pyro.sample("p_init",
                            dist.Dirichlet((1 / num_state) * torch.ones(num_state)))
    
    p_mu = pyro.sample("p_mu",
                    dist.Normal(torch.zeros(num_state), torch.ones(num_state)).to_event(1))
    
    p_tau = pyro.sample("p_tau",
                    dist.HalfCauchy(torch.zeros(num_state)).to_event(1))
    
    current_state = pyro.sample("x_0",
                                dist.Categorical(p_init),
                                infer = {"enumerate" : "parallel"})
    
    
    for t in pyro.markov(range(1, len(observations))):
    
        current_state = pyro.sample("x_{}".format(t),
                                    dist.Categorical(Vindex(p_transition)[current_state, :]),
                                    infer = {"enumerate" : "parallel"})
    
    
        pyro.sample("y_{}".format(t),
                    dist.Normal(Vindex(p_mu)[current_state], Vindex(p_tau)[current_state]),
                    obs = observations[t])
    

    然后将使用 MCMC 训练模型:

    # MCMC
    hmc_kernel = NUTS(model, target_accept_prob = 0.9, max_tree_depth = 7)
    mcmc = MCMC(hmc_kernel, num_samples = 1000, warmup_steps = 100, num_chains = 1)
    mcmc.run(obs)
    

    然后可以使用以下方法分析结果: mcmc.get_samples()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-25
      • 2021-11-24
      • 1970-01-01
      • 2015-08-31
      • 2017-07-26
      • 2013-07-04
      • 2018-02-28
      • 1970-01-01
      相关资源
      最近更新 更多