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