'Returns all the goodies for the entire model, per batch.
Args:
data_name: The name of the data dict, to select which in/out matrices
to use.
data_bxtxd:  Numpy array training data with shape:
batch_size x # time steps x # dimensions
ext_input_bxtxi: Numpy array training external input with shape:
batch_size x # time steps x # external input dims
do_eval_cost (optional): If true, the IWAE (Importance Weighted
Autoencoder) log likeihood bound, instead of the VAE version.
do_average_batch (optional): average over the batch, useful for getting
good IWAE costs, and model outputs for a single data point.
Returns:
A dictionary with the outputs of the model decoder, namely:
prior g0 mean, prior g0 variance, approx. posterior mean, approx
posterior mean, the generator initial conditions, the control inputs (if
enabled), the state of the generator, the factors, and the rates.'

def eval_model_runs_batch(self, data_name, data_bxtxd, ext_input_bxtxi=None, do_eval_cost=False, do_average_batch=False):

    session = tf.get_default_session()
    feed_dict = self.build_feed_dict(data_name, data_bxtxd, ext_input_bxtxi, keep_prob=1.0)
    tf_vals = [self.gen_ics, self.gen_states, self.factors, self.output_dist_params]
    tf_vals.append(self.cost)
    tf_vals.append(self.nll_bound_vae)
    tf_vals.append(self.nll_bound_iwae)
    tf_vals.append(self.train_step)
    if (self.hps.ic_dim > 0):
        tf_vals += [self.prior_zs_g0.mean, self.prior_zs_g0.logvar, self.posterior_zs_g0.mean, self.posterior_zs_g0.logvar]
    if (self.hps.co_dim > 0):
        tf_vals.append(self.controller_outputs)
    (tf_vals_flat, fidxs) = flatten(tf_vals)
    np_vals_flat = session.run(tf_vals_flat, feed_dict=feed_dict)
    ff = 0
    gen_ics = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    gen_states = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    factors = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    out_dist_params = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    costs = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    nll_bound_vaes = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    nll_bound_iwaes = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    train_steps = [np_vals_flat[f] for f in fidxs[ff]]
    ff += 1
    if (self.hps.ic_dim > 0):
        prior_g0_mean = [np_vals_flat[f] for f in fidxs[ff]]
        ff += 1
        prior_g0_logvar = [np_vals_flat[f] for f in fidxs[ff]]
        ff += 1
        post_g0_mean = [np_vals_flat[f] for f in fidxs[ff]]
        ff += 1
        post_g0_logvar = [np_vals_flat[f] for f in fidxs[ff]]
        ff += 1
    if (self.hps.co_dim > 0):
        controller_outputs = [np_vals_flat[f] for f in fidxs[ff]]
        ff += 1
    gen_ics = gen_ics[0]
    costs = costs[0]
    nll_bound_vaes = nll_bound_vaes[0]
    nll_bound_iwaes = nll_bound_iwaes[0]
    train_steps = train_steps[0]
    gen_states = list_t_bxn_to_tensor_bxtxn(gen_states)
    factors = list_t_bxn_to_tensor_bxtxn(factors)
    out_dist_params = list_t_bxn_to_tensor_bxtxn(out_dist_params)
    if (self.hps.ic_dim > 0):
        prior_g0_mean = prior_g0_mean[0]
        prior_g0_logvar = prior_g0_logvar[0]
        post_g0_mean = post_g0_mean[0]
        post_g0_logvar = post_g0_logvar[0]
    if (self.hps.co_dim > 0):
        controller_outputs = list_t_bxn_to_tensor_bxtxn(controller_outputs)
    if do_average_batch:
        gen_ics = np.mean(gen_ics, axis=0)
        gen_states = np.mean(gen_states, axis=0)
        factors = np.mean(factors, axis=0)
        out_dist_params = np.mean(out_dist_params, axis=0)
        if (self.hps.ic_dim > 0):
            prior_g0_mean = np.mean(prior_g0_mean, axis=0)
            prior_g0_logvar = np.mean(prior_g0_logvar, axis=0)
            post_g0_mean = np.mean(post_g0_mean, axis=0)
            post_g0_logvar = np.mean(post_g0_logvar, axis=0)
        if (self.hps.co_dim > 0):
            controller_outputs = np.mean(controller_outputs, axis=0)
    model_vals = {}
    model_vals['gen_ics'] = gen_ics
    model_vals['gen_states'] = gen_states
    model_vals['factors'] = factors
    model_vals['output_dist_params'] = out_dist_params
    model_vals['costs'] = costs
    model_vals['nll_bound_vaes'] = nll_bound_vaes
    model_vals['nll_bound_iwaes'] = nll_bound_iwaes
    model_vals['train_steps'] = train_steps
    if (self.hps.ic_dim > 0):
        model_vals['prior_g0_mean'] = prior_g0_mean
        model_vals['prior_g0_logvar'] = prior_g0_logvar
        model_vals['post_g0_mean'] = post_g0_mean
        model_vals['post_g0_logvar'] = post_g0_logvar
    if (self.hps.co_dim > 0):
        model_vals['controller_outputs'] = controller_outputs
    return model_vals
