我正在学习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()
我在这里先设置浓度(alpha
,beta
)。
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会发出大约正确的参数值。现在,问题仍然存在-如何使用推断的alpha
和beta
运行仿真?