def main():
    # generate data
    (train_x, train_y), (test_x, test_y) = iris()

    # clear parameter store
    pyro.PARAM_STORE.clear()

    # learning rate
    lr = 0.005
    # training steps
    num_steps = 2000

    # SVI for inference
    svi = pyro.SVI(model,
                   guide,
                   optimizer=pyro.Adam({'lr': lr}),
                   loss_fn=pyro.elbo)

    losses, w, b = [], [], []
    for step in tqdm(range(num_steps)):
        loss = svi.step(train_x, train_y)
        # if step % 100 == 0:
        losses.append(loss)
        w.append(pyro.param('w_loc').data.numpy())
        b.append(pyro.param('b_loc').item())

        # if step % 100 == 0:
        # print('[{}] loss : {}'.format(step, loss))

    w_ps = pyro.param('w_loc')
    b_ps = pyro.param('b_loc')

    print('w : {}; b : {}'.format(w_ps, b_ps))

    def predict(x):
        x = torch.tensor(x)
        return torch.sigmoid((w_ps * x).sum() + b_ps)

    correcto = 0
    for xi, yi in zip(test_x, test_y):
        num_samples = 1000
        samples = sample_from_posterior(
            torch.tensor(xi).view(1, -1), prob_forward, num_samples)
        correcto = (((samples > 0.5) == yi.item()).sum())
        print('[{}] {}/{} with {}% certainty'.format(
            yi, correcto, num_samples, 100. * correcto / num_samples))
if __name__ == '__main__':
    # generate data
    (train_x, train_y), (test_x, test_y) = iris()

    # clear parameter store
    pyro.PARAM_STORE.clear()

    # learning rate
    lr = 0.005
    # training steps
    num_steps = 1000

    # SVI for inference
    svi = pyro.SVI(model,
                   guide,
                   optimizer=pyro.Adam({'lr': lr}),
                   loss_fn=pyro.elbo)

    losses, w, b = [], [], []
    for step in range(num_steps):
        loss = svi.step(train_x, train_y)
        # if step % 100 == 0:
        losses.append(loss)
        w.append(pyro.param('w_loc').data.numpy())
        b.append(pyro.param('b_loc').item())

        if step % 100 == 0:
            print('[{}] loss : {}'.format(step, loss))

    w_ps = pyro.param('w_loc')
    b_ps = pyro.param('b_loc')