def bdmc(model, loader, forward_schedule, n_sample): """Bidirectional Monte Carlo. Backward schedule is set to be the reverse of the forward schedule. Args: model (vae.VAE): VAE model loader (iterator): iterator to loop over pairs of Variables; the first entry being `x`, the second being `z` sampled from the *true* posterior `p(z|x)` forward_schedule: forward temperature schedule n_sample (int): number of importance samples Returns: two lists for forward and backward bounds on batches of data """ # iterator is exhaustible in py3, so need duplicate loader_forward, loader_backward = itertools.tee(loader, 2) # forward chain forward_logws = ais.ais_trajectory( model, loader_forward, forward=True, schedule=forward_schedule, n_sample=n_sample, device=device, ) # backward chain backward_schedule = torch.flip(forward_schedule, dims=(0,)).contiguous() backward_logws = ais.ais_trajectory( model, loader_backward, forward=False, schedule=backward_schedule, n_sample=n_sample, device=device, ) upper_bounds = [] lower_bounds = [] for i, (forward, backward) in enumerate(zip(forward_logws, backward_logws)): lower_bounds.append(forward.mean().detach().item()) upper_bounds.append(backward.mean().detach().item()) upper_bounds = float(np.mean(upper_bounds)) lower_bounds = float(np.mean(lower_bounds)) print( f"Average bounds on simulated data: lower {lower_bounds:.4f}, upper {upper_bounds:.4f}" ) return forward_logws, backward_logws
def bdmc(model, loader, forward_schedule, n_sample, device=torch.device("cpu")): """Bidirectional Monte Carlo. Backward schedule is set to be the reverse of the forward schedule. Args: model (vae.VAE): VAE model loader (iterator): iterator to loop over pairs of Variables; the first entry being `x`, the second being `z` sampled from the *true* posterior `p(z|x)` forward_schedule (list or numpy.ndarray): forward temperature schedule Returns: Two lists for forward and backward bounds on batchs of data """ # iterator is exhaustable in py3, so need duplicate load, load_ = itertools.tee(loader, 2) # forward chain forward_logws = ais.ais_trajectory( model, load, forward=True, schedule=forward_schedule, n_sample=n_sample, device=device, ) # backward chain backward_schedule = np.flip(forward_schedule, axis=0) backward_logws = ais.ais_trajectory( model, load_, forward=False, schedule=backward_schedule, n_sample=n_sample, device=device, ) upper_bounds = [] lower_bounds = [] for i, (forward, backward) in enumerate(zip(forward_logws, backward_logws)): lower_bounds.append(forward.mean()) upper_bounds.append(backward.mean()) upper_bounds = np.mean(upper_bounds) lower_bounds = np.mean(lower_bounds) print('Average bounds on simulated data: lower %.4f, upper %.4f' % (lower_bounds, upper_bounds)) return forward_logws, backward_logws
def forward_ais(model, loader, forward_schedule=np.linspace(0., 1., 500), n_sample=100): """Bidirectional Monte Carlo. Integrate forward and backward AIS. The backward schedule is the reverse of the forward. Args: model (vae.VAE): VAE model loader (iterator): iterator to loop over pairs of Variables; the first entry being `x`, the second being `z` sampled from the true posterior `p(z|x)` forward_schedule (list or numpy.ndarray): forward temperature schedule; backward schedule is used as its reverse Returns: Two lists for forward and backward bounds on batchs of data """ # iterator is exhaustable in py3, so need duplicate load, load_ = itertools.tee(loader, 2) # forward chain forward_logws = ais_trajectory(model, load, mode='forward', schedule=forward_schedule, n_sample=n_sample) lower_bounds = [] for forward in forward_logws: lower_bounds.append(forward.mean()) lower_bounds = np.mean(lower_bounds) return forward_logws