2

我正在学习 Pyro,尽管有丰富而详细的文档,但我发现尺寸令人困惑

这是我的模型的草图:

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()

我在这里设置了浓度 ( alpha, beta) 的先验。 我的理解是,对数据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)进行一些推断。我还想知道在推断出潜在浓度之后如何运行模型。代码的小草图会很有帮助,谢谢!


事后看来,我想我可能误解了板块的使用。现在,如果我假设观察结果是独立的,我需要设置一个盘子。就像是:

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 吐出近似正确的参数值。现在,问题仍然存在 - 我如何使用推断的alphaand运行模拟beta

4

0 回答 0