Ejemplo n.º 1
0
    def sample(
        self,
        tensors,
        n_samples=1,
    ) -> np.ndarray:
        r"""
        Generate observation samples from the posterior predictive distribution.

        The posterior predictive distribution is written as :math:`p(\hat{x} \mid x)`.

        Parameters
        ----------
        tensors
            Tensors dict
        n_samples
            Number of required samples for each cell
        library_size
            Library size to scale scamples to

        Returns
        -------
        x_new : :py:class:`torch.Tensor`
            tensor with shape (n_cells, n_genes, n_samples)
        """
        inference_kwargs = dict(n_samples=n_samples)
        inference_outputs, generative_outputs, = self.forward(
            tensors,
            inference_kwargs=inference_kwargs,
            compute_loss=False,
        )
        px = Normal(generative_outputs["px"], 1).sample()
        return px.cpu().numpy()
Ejemplo n.º 2
0
 def act(self, states):
     with torch.no_grad():
         states = torch.tensor(states,
                               dtype=torch.float).view(1,
                                                       -1).to(self.device)
         means, log_stds = self.pi(states)
         stds = log_stds.exp()
         actions = Normal(means, stds).sample()
         actions = torch.tanh(actions)
         actions = actions.cpu().numpy().reshape(-1)
     return actions
Ejemplo n.º 3
0
def update_belief_and_act(args,
                          env,
                          actor_model,
                          transition_model,
                          encoder,
                          belief,
                          posterior_state,
                          action,
                          observation,
                          deterministic=False):
    # Infer belief over current state q(s_t|o≤t,a<t) from the history
    belief, _, _, _, posterior_state, _, _ = transition_model(
        posterior_state, action.unsqueeze(dim=0), belief,
        encoder(observation).unsqueeze(
            dim=0))  # Action and observation need extra time dimension

    belief, posterior_state = belief.squeeze(dim=0), posterior_state.squeeze(
        dim=0)  # Remove time dimension from belief/state

    #
    # if explore:
    #   action = actor_model(belief, posterior_state).rsample()  # batch_shape=1, event_shape=6
    #   # add exploration noise -- following the original code: line 275-280
    #   action = Normal(action, args.expl_amount).rsample()
    #
    #   # TODO: add this later
    #   # action = torch.clamp(action, [-1.0, 0.0], [1.0, 5.0])
    # else:
    #   action = actor_model(belief, posterior_state).mode()
    action, _ = actor_model(
        belief,
        posterior_state,
        deterministic=deterministic,
        with_logprob=False
    )  # with sac, not need to add exploration noise, the max entropy can maintain it.
    if args.temp == 0 and not deterministic:
        action = Normal(action, args.expl_amount).rsample()
    action[:, 1] = 0.3  # TODO: fix the speed
    next_observation, reward, done = env.step(
        action.cpu() if isinstance(env, EnvBatcher) else action[0].cpu(
        ))  # Perform environment step (action repeats handled internally)

    print(
        bottle(value_model1, (belief.unsqueeze(dim=0),
                              posterior_state.unsqueeze(dim=0))).item())
    return belief, posterior_state, action, next_observation, reward, done
Ejemplo n.º 4
0
def conditional(ctx, datafile, t, outfile, n, a, b, c, maxiters):
    """Forecast stoch vol model and compute log score, conditional on T observations.

    Example:

        stochvol --data_seed=123 --algo_seed=123 conditional experiment.csv 200 SV00200.json --N=100 --a=1. --b=0. --c=0.8
    """
    assert t > 1
    start_date, start_time = str(datetime.today()), time()
    click.echo(_DIVIDER)
    click.echo("Stochastic volatility model: conditional score estimation")
    click.echo(_DIVIDER)
    true_params = dict(a=a, b=b, c=c)
    algo_seed = ctx.obj["algo_seed"]
    data_seed = ctx.obj["data_seed"]
    data = pd.read_csv(datafile)
    click.echo(f"Started at: {start_date}")
    click.echo(f"Reading {t}/{len(data)} observations from {datafile}.")
    click.echo(f"True parameters assumed to be a={a}, b={b}, c={c}")

    # draw N variates from p(y_T+1 | z_T+1, a, b, c)
    click.echo(
        f"Drawing {n} variates from p(y_T+1, z_T+1 | z_T, a, b, c) with "
        f"data_seed={data_seed}"
    )
    torch.manual_seed(data_seed)
    a, b, c = map(torch.tensor, (a, b, c))
    z_next = b + c * data["z"][t - 1] + Normal(0, 1).sample((n,))
    y_next = Normal(0, torch.exp(a) * torch.exp(z_next / 2)).sample()
    y_next_list = y_next.cpu().numpy().squeeze().tolist()  # for saving

    # perform inference
    y = data["y"][:t]
    model = SVModel(input_length=t)
    click.echo(repr(model))
    torch.manual_seed(algo_seed)
    fit = sgvb(model, y, max_iters=maxiters)
    click.echo("Inference summary:")
    click.echo(fit.summary(true=true_params))

    click.echo(f"Generating {n} forecast draws from q...")
    # filter to get p(z_T | y, θ) then project z_{T+1}, z_{T+2}, ...
    forecast, fc_draws = fit.forecast(steps=1)
    fc_draws_list = fc_draws.squeeze().tolist()

    dens = forecast.pdf(y_next)
    scores = np.log(dens[dens > 0])
    score = np.mean(scores)
    score_se = np.std(scores)
    click.echo(f"Forecast log score = {score:.4f} nats (sd = {score_se:.4f}, n = {n})")

    click.echo(f"Writing results to {outfile} in JSON format.")
    y_list = data["y"][:t].tolist()
    z_list = data["z"][:t].tolist()
    summary = {
        "method": "VSMC",
        "algo_seed": algo_seed,
        "data_seed": data_seed,
        "datafile": datafile,
        "t": t,
        "outfile": outfile,
        "fc_draws": fc_draws_list,
        "score": score,
        "score_se": score_se,
        "n": n,
        "y_next": y_next_list,
        "start_date": start_date,
        "elapsed": time() - start_time,
        "true_params": true_params,
        "full_length": len(data),
        "max_iters": maxiters,
        "inference_results": str(fit.summary()),
        "y": y_list,
        "z": z_list,
    }
    with open(outfile, "w", encoding="utf8") as ofilep:
        json.dump(summary, ofilep, indent=4, sort_keys=True)

    click.echo(f"Done in {time() - start_time:.1f} seconds.")
    click.echo(_DIVIDER)