def test_kl_divergence_mv_gaussian_v2_chol(self): _, mu1, covar1 = self._random_normal_params(cov_rep.CovarianceFull) chol_covariance1 = np.linalg.cholesky(covar1) _, mu2, covar2 = self._random_normal_params(cov_rep.CovarianceFull) chol_covariance2 = np.linalg.cholesky(covar2) tf_mvnd1 = dist.MultivariateNormalFullCovariance( loc=mu1, covariance_matrix=covar1) tf_mvnd2 = dist.MultivariateNormalFullCovariance( loc=mu2, covariance_matrix=covar2) tf_kldiv = dist.kl_divergence(tf_mvnd1, tf_mvnd2) mu1_tf, mu2_tf = self._convert_to_tensor(mu1, mu2) covar1 = cov_rep.CovarianceCholesky( chol_covariance=tf.convert_to_tensor(chol_covariance1)) covar2 = cov_rep.CovarianceCholesky( chol_covariance=tf.convert_to_tensor(chol_covariance2)) covar_kldiv = kl_divergence_mv_gaussian_v2(sigma1=covar1, sigma2=covar2, mu1=mu1_tf, mu2=mu2_tf, mean_batch=False) self._asset_allclose_tf_feed(tf_kldiv, covar_kldiv) tf_kldiv = tf.reduce_mean(tf_kldiv) covar_kldiv = kl_divergence_mv_gaussian_v2(sigma1=covar1, sigma2=covar2, mu1=mu1_tf, mu2=mu2_tf) self._asset_allclose_tf_feed(tf_kldiv, covar_kldiv)
def _kl_mvnd_tfmvnd(a, b, name=None): """Batched KL divergence `KL(a || b)` for multivariate Normals, when "a" is a tf.contrib.distributions.MultivariateNormal* distribution""" a_cov_obj = cov_rep.CovarianceCholesky(chol_covariance=a.scale.to_dense()) return kl_divergence_mv_gaussian_v2(mu1=a.loc, mu2=b.loc, sigma1=a_cov_obj, sigma2=b.cov_obj, mean_batch=False, name=name)
def _create_covariance_instance(self): self.cov_object = cov_rep.CovarianceCholesky( chol_covariance=self.tf_input, inversion_method=self.inversion_method) self.np_covariance = self.create_random_covariance( self.batch_size, self.features_size, self.dtype, False) self._create_np_precision_cholesky() self.np_input = self.np_chol_covariance
def __init__(self, loc, chol_covariance=None, chol_precision=None, log_diag_chol_covariance=None, log_diag_chol_precision=None, validate_args=False, allow_nan_stats=True, name="MultivariateNormalChol"): parameters = locals() cov_obj = None graph_parents = None if chol_covariance is not None: assert log_diag_chol_covariance is not None, 'Must provide log_diag of Cholesky matrix' chol_covariance = tf.convert_to_tensor(chol_covariance) log_diag_chol_covariance = tf.convert_to_tensor( log_diag_chol_covariance) cov_obj = cov_rep.CovarianceCholesky( chol_covariance=chol_covariance) cov_obj.log_diag_chol_covariance = log_diag_chol_covariance graph_parents = [chol_covariance, log_diag_chol_covariance] assert chol_precision is None if chol_precision is not None: assert log_diag_chol_precision is not None, 'Must provide log_diag of Cholesky matrix' chol_precision = tf.convert_to_tensor(chol_precision) log_diag_chol_precision = tf.convert_to_tensor( log_diag_chol_precision) cov_obj = cov_rep.PrecisionCholesky(chol_precision=chol_precision) cov_obj.log_diag_chol_precision = log_diag_chol_precision graph_parents = [chol_precision, log_diag_chol_precision] assert chol_covariance is None if cov_obj is None: raise RuntimeError( 'Must provide chol_covariance or chol_precision') super().__init__(loc=loc, cov_obj=cov_obj, validate_args=validate_args, allow_nan_stats=allow_nan_stats, name=name) self._parameters = parameters
def test_neg_log_likelihood_mv_gaussian_chol(self): x, mu, covariance = self._random_normal_params( cov_rep.CovarianceCholesky) chol_covariance = np.linalg.cholesky(covariance) tf_mvnd = tfd.MultivariateNormalFullCovariance( loc=mu, covariance_matrix=covariance) tf_nll = -tf_mvnd.log_prob(x) covar = cov_rep.CovarianceCholesky( chol_covariance=tf.convert_to_tensor(chol_covariance)) r_tf = tf.convert_to_tensor(x - mu) nll = neg_log_likelihood_mv_gaussian( r_tf, x_precision_x=covar.x_precision_x(r_tf), log_det_cov=covar.log_det_covariance(), mean_batch=False) self._asset_allclose_tf_feed(nll, tf_nll)