Pyro-似然函数和采样维

时间:2019-07-04 20:03:17

标签: python pytorch pyro.ai

我正在学习Pyro,尽管富人和detailed documentation

,但我发现尺寸令人困惑

这是我的模型草图:

DATA_SIZE = 1000

simulated_daily_demand = torch.distributions.Beta(torch.tensor(2.0), torch.tensor(2.0)).sample([DATA_SIZE,])


def model(SIMULATION_DAYS = 30):
    alpha = pyro.param("alpha", pyro.distributions.Uniform(0, 10))
    beta = pyro.param("beta", pyro.distributions.Uniform(0, 10))    
    total_demand = 0
    for t in range(0, SIMULATION_DAYS):
        daily_demand = pyro.sample("daily_demand", pyro.distributions.Beta(alpha, beta), obs=simulated_daily_demand)
        total_demand = total_demand + daily_demand
    return total_demand

model()

我在这里先设置浓度(alphabeta)。 My understanding是用pyro.sample调用observations可以满足数据的要求-我想它可以最大程度地提高给定数据浓度的可能性。

我得到的输出:

len(model())
C:\ProgramData\Anaconda3\lib\site-packages\pyro\primitives.py:85: RuntimeWarning: trying to observe a value outside of inference at daily_demand
  RuntimeWarning)
1000

`size()

我得到的价值观看起来不错。 simulated_daily_demand的平均值约为0.5,而model()的平均值约为15,约为30 * 0.5。 我没有张量的大小。我本来希望它是.size() torch.Size([1])

我也注意到了警告。我想Pyro抱怨了,因为它希望我写一个指南并在可以从“每日需求”中取样之前对参数(例如SVI)进行一些推断。我也想知道在推断潜在浓度后如何运行模型。 略微编写代码确实会有所帮助,谢谢!


事后看来,我认为我可能误解了plates的使用。现在,如果我假设观察结果是独立的,则需要设置一个板块。 像这样:

import torch
import pyro

NUM_RUNS = 5
DATA_SIZE = 1000

simulated_daily_demand = torch.distributions.Beta(torch.tensor(2.0), torch.tensor(2.0)).sample([DATA_SIZE,])


def model(hist_demand, START_INVENTORY = torch.tensor(100.0), SIMULATION_DAYS = 30):
    alpha = pyro.param("alpha", pyro.distributions.Uniform(0, 10))
    beta = pyro.param("beta", pyro.distributions.Uniform(0, 10))    
    total_demand = 0
    for t in range(0, SIMULATION_DAYS):
        with pyro.plate("obs_loop"):
            daily_demand = pyro.sample("daily_demand", pyro.distributions.Beta(alpha, beta), obs=simulated_daily_demand)
        total_demand = total_demand + daily_demand
    return total_demand

total_demand_runs = []
for r in range(0, NUM_RUNS):
    total_demand_runs.append(model(simulated_daily_demand))

哪个返回一个嵌套大小列表(NUM_RUNS,SIMULATION_DAYS),其中包含一个张量大小为DATA_SIZE的张量。在仿真日中,元素(daily_demand)相同。可能越来越近了,但没有雪茄。


import torch
import pyro
import torch.distributions.constraints as constraints

NUM_RUNS = 5
SIMULATION_DAYS = 30
DATA_SIZE = 1000


simulated_daily_demand = torch.distributions.Beta(torch.tensor(2.0), torch.tensor(2.0)).sample([DATA_SIZE, SIMULATION_DAYS])

def model(hist_demand = None, START_INVENTORY = torch.tensor(100.0), SIMULATION_DAYS = SIMULATION_DAYS):
    alpha = pyro.param("alpha", pyro.distributions.Uniform(0, 10))
    beta = pyro.param("beta", pyro.distributions.Uniform(0, 10))
    with pyro.plate("obs_loop"):
        daily_demand_vector = pyro.sample("daily_demand", pyro.distributions.Beta(
            alpha * torch.ones([SIMULATION_DAYS]), 
            beta * torch.ones([SIMULATION_DAYS])), 
            obs=hist_demand
        )
    total_demand = 0
    for t in range(0, SIMULATION_DAYS):
        total_demand = total_demand + daily_demand_vector[t]
    return total_demand

def guide(hist_demand):
    alpha = pyro.param(
        "alpha", 
        pyro.distributions.Normal(torch.tensor(2.0), torch.tensor(0.1)),
        constraint = constraints.positive
        )
    beta = pyro.param(
        "beta",
        pyro.distributions.Normal(torch.tensor(2.0), torch.tensor(0.1)),
        constraint = constraints.positive
        )
    return alpha, beta

from pyro.optim import Adam
adam_params = {"lr": 0.005, "betas": (0.95, 0.999)}
optimizer = Adam(adam_params)
svi = pyro.infer.SVI(model, guide, optimizer, loss=pyro.infer.Trace_ELBO())

n_steps = 5000
# do gradient steps
for step in range(n_steps):
    svi.step(simulated_daily_demand)

alpha_q = pyro.param("alpha").item()
beta_q = pyro.param("beta").item()

类似的事情似乎是有道理的,并且似乎已经趋于融合:SVI会发出大约正确的参数值。现在,问题仍然存在-如何使用推断的alphabeta运行仿真?

0 个答案:

没有答案