If I observe a temperature of 70 degrees, how likely is it to be cloudy?

I have implemented a model from ‘An Introduction to Models in Pyro’ but the inference is wrong. Model aways converges to: P(Cloudy|70degrees) ≈ 0.5

def weather():
    alpha0 = torch.tensor(10.0)
    beta0 = torch.tensor(10.0)
    prob_cloudy = pyro.sample("prob_cloudy", dist.Beta(alpha0, beta0))

    #cloudy = pyro.sample('cloudy', pyro.distributions.Bernoulli(prob_cloudy))
    cloudy = pyro.distributions.Bernoulli(prob_cloudy).sample()
    cloudy = 'cloudy' if cloudy.item() == 1.0 else 'sunny'
    mean_temp = {'cloudy': 55.0, 'sunny': 75.0}[cloudy]
    scale_temp = {'cloudy': 10.0, 'sunny': 15.0}[cloudy]
    temp = pyro.sample('temp', pyro.distributions.Normal(mean_temp, scale_temp))
    return temp

def weather_guide():
    alpha0 = pyro.param("alpha0", torch.tensor(10.0), constraint=constraints.positive)
    beta0 = pyro.param("beta0", torch.tensor(10.0), constraint=constraints.positive)
    pyro.sample("prob_cloudy", dist.Beta(alpha0, beta0))

conditioned_weather = pyro.condition(weather, data={"temp": torch.tensor(70.0)}) 

pyro.clear_param_store()
svi = pyro.infer.SVI(model=conditioned_weather,
                     guide=weather_guide,
                     optim=pyro.optim.SGD({"lr": 0.001, "momentum":0.1}),
                     loss=pyro.infer.Trace_ELBO())

It is easy to estimate that P(Cloudy|70degress) ≈ 0.2

tests = [0.1, 0.2, 0.5, 0.9]
for t in tests:
  conditioned_weather_cloudy = pyro.condition(weather, data={"prob_cloudy": torch.tensor(t)})
  temp = [conditioned_weather_cloudy() for i in range(1000)]
  print(t, 70-np.mean(temp))

Can you please suggest what is wrong?

solved as part of this post.

2 Likes