Exemplo n.º 1
0
  def testOneDimNormal(self):
    """Sampling from the Standard Normal Distribution."""
    dtype = np.float32
    num_results, tolerance = self._get_mode_dependent_settings()
    target = tfd.Normal(loc=dtype(0), scale=dtype(1))

    samples, _ = tfp.mcmc.sample_chain(
        num_results=num_results,
        current_state=dtype(1),
        kernel=tfp.mcmc.SliceSampler(
            target.log_prob,
            step_size=1.0,
            max_doublings=5,
            seed=test_util.test_seed_stream()),
        num_burnin_steps=100,
        parallel_iterations=1)  # For determinism.

    sample_mean = tf.reduce_mean(samples, axis=0)
    sample_std = tfp.stats.stddev(samples)

    self.assertAllClose(0., sample_mean, atol=tolerance, rtol=tolerance)
    self.assertAllClose(1., sample_std, atol=tolerance, rtol=tolerance)
Exemplo n.º 2
0
  def test_specifying_event_shape(
      self, event_shape, bijector, dtype, is_static):
    seed = test_util.test_seed_stream()
    surrogate_posterior = (
        tfp.experimental.vi.build_factored_surrogate_posterior(
            event_shape=tf.nest.map_structure(
                lambda s: self.maybe_static(  # pylint: disable=g-long-lambda
                    np.array(s, dtype=np.int32), is_static=is_static),
                event_shape),
            bijector=bijector,
            initial_unconstrained_loc=functools.partial(
                tf.random.uniform, minval=-2., maxval=2., dtype=dtype),
            seed=seed(),
            validate_args=True))
    self.evaluate([v.initializer
                   for v in surrogate_posterior.trainable_variables])

    self._test_shapes(
        surrogate_posterior, batch_shape=[], event_shape=event_shape,
        seed=seed())
    self._test_gradients(surrogate_posterior, seed=seed())
    self._test_dtype(surrogate_posterior, dtype, seed())
Exemplo n.º 3
0
 def testLogBesselKveCorrect(self, dtype, rtol, atol=1e-6):
     seed_stream = test_util.test_seed_stream()
     v = tf.random.uniform([int(1e5)],
                           minval=0.1,
                           maxval=0.5,
                           seed=seed_stream(),
                           dtype=dtype)
     z = tf.random.uniform([int(1e5)],
                           minval=1.,
                           maxval=10.,
                           seed=seed_stream(),
                           dtype=dtype)
     _, _, log_bessel_kve_expected_, log_bessel_kve_actual_ = self.evaluate(
         [
             v, z,
             tf.math.log(tfp.math.bessel_kve(v, z)),
             tfp.math.log_bessel_kve(v, z)
         ])
     self.assertAllClose(log_bessel_kve_expected_,
                         log_bessel_kve_actual_,
                         rtol=rtol,
                         atol=atol)
Exemplo n.º 4
0
def make_multivariate_mixture(batch_shape,
                              num_components,
                              event_shape,
                              use_static_graph,
                              batch_shape_tensor=None):
    if batch_shape_tensor is None:
        batch_shape_tensor = batch_shape
    batch_shape_tensor = tf.convert_to_tensor(value=batch_shape_tensor,
                                              dtype=tf.int32)
    seed_stream = test_util.test_seed_stream('multivariate_mixture')
    logits = -50. + tf.random.uniform(tf.concat(
        (batch_shape_tensor, [num_components]), 0),
                                      -1,
                                      1,
                                      dtype=tf.float32,
                                      seed=seed_stream())
    tensorshape_util.set_shape(
        logits, tensorshape_util.concatenate(batch_shape, num_components))
    static_batch_and_event_shape = (
        tf.TensorShape(batch_shape).concatenate(event_shape))
    event_shape = tf.convert_to_tensor(value=event_shape, dtype=tf.int32)
    batch_and_event_shape = tf.concat((batch_shape_tensor, event_shape), 0)

    def create_component():
        loc = tf.random.normal(batch_and_event_shape, seed=seed_stream())
        scale_diag = 10 * tf.random.uniform(batch_and_event_shape,
                                            seed=seed_stream())
        tensorshape_util.set_shape(loc, static_batch_and_event_shape)
        tensorshape_util.set_shape(scale_diag, static_batch_and_event_shape)
        return tfd.MultivariateNormalDiag(loc=loc,
                                          scale_diag=scale_diag,
                                          validate_args=True)

    components = [create_component() for _ in range(num_components)]
    cat = tfd.Categorical(logits, dtype=tf.int32)
    return tfd.Mixture(cat,
                       components,
                       use_static_graph=use_static_graph,
                       validate_args=True)
Exemplo n.º 5
0
def assert_univariate_target_conservation(test, target_d, step_size):
    # Sample count limited partly by memory reliably available on Forge.  The test
    # remains reasonable even if the nuts recursion limit is severely curtailed
    # (e.g., 3 or 4 levels), so use that to recover some memory footprint and bump
    # the sample count.
    num_samples = int(5e4)
    num_steps = 1
    strm = tfp_test_util.test_seed_stream()
    initialization = target_d.sample([num_samples], seed=strm())

    @tf.function(autograph=False)
    def run_chain():
        nuts = tfp.mcmc.NoUTurnSampler(target_d.log_prob,
                                       step_size=step_size,
                                       max_tree_depth=3,
                                       unrolled_leapfrog_steps=2,
                                       seed=strm())
        result, _ = tfp.mcmc.sample_chain(num_results=num_steps,
                                          num_burnin_steps=0,
                                          current_state=initialization,
                                          kernel=nuts)
        return result

    result = run_chain()
    test.assertAllEqual([num_steps, num_samples], result.shape)
    answer = result[0]
    check_cdf_agrees = st.assert_true_cdf_equal_by_dkwm(answer,
                                                        target_d.cdf,
                                                        false_fail_rate=1e-6)
    check_enough_power = assert_util.assert_less(
        st.min_discrepancy_of_true_cdfs_detectable_by_dkwm(
            num_samples, false_fail_rate=1e-6, false_pass_rate=1e-6), 0.025)
    movement = tf.abs(answer - initialization)
    test.assertAllEqual([num_samples], movement.shape)
    # This movement distance (1 * step_size) was selected by reducing until 100
    # runs with independent seeds all passed.
    check_movement = assert_util.assert_greater_equal(tf.reduce_mean(movement),
                                                      1 * step_size)
    return (check_cdf_agrees, check_enough_power, check_movement)
  def VerifyPowerSphericalVonMisesFisherZeroKL(self, dim):
    seed_stream = test_util.test_seed_stream()
    mean_direction = tf.random.uniform(
        shape=[5, dim],
        minval=self.dtype(1.),
        maxval=self.dtype(2.),
        dtype=self.dtype,
        seed=seed_stream())
    mean_direction = tf.nn.l2_normalize(mean_direction, axis=-1)
    # Zero concentration is the same as a uniform distribution on the sphere.
    # Check that the KL divergence is zero.
    concentration = self.dtype(0.)

    ps = tfp.distributions.PowerSpherical(
        mean_direction=mean_direction,
        concentration=concentration)
    vmf = tfp.distributions.VonMisesFisher(
        mean_direction=mean_direction,
        concentration=concentration)
    true_kl = tfp.distributions.kl_divergence(ps, vmf)
    true_kl_ = self.evaluate(true_kl)
    self.assertAllClose(true_kl_, np.zeros_like(true_kl_), atol=1e-4)
Exemplo n.º 7
0
    def testFourDimNormal(self):
        """Sampling from a 4-D Multivariate Normal distribution."""

        dtype = np.float32
        true_mean = dtype([0, 4, -8, 2])
        true_cov = np.eye(4, dtype=dtype)
        num_results, tolerance = _get_mode_dependent_settings()
        num_chains = 16
        target = tfd.MultivariateNormalTriL(loc=true_mean, scale_tril=true_cov)

        # Initial state of the chain
        init_state = np.ones([num_chains, 4], dtype=dtype)

        # Run Slice Samper for `num_results` iterations for `num_chains`
        # independent chains:
        states = tfp.mcmc.sample_chain(num_results=num_results,
                                       current_state=init_state,
                                       kernel=tfp.mcmc.SliceSampler(
                                           target_log_prob_fn=tf.function(
                                               target.log_prob,
                                               autograph=False),
                                           step_size=1.0,
                                           max_doublings=5),
                                       num_burnin_steps=100,
                                       trace_fn=None,
                                       seed=test_util.test_seed_stream())

        result = tf.reshape(states, [-1, 4])
        sample_mean = tf.reduce_mean(result, axis=0)
        sample_cov = tfp.stats.covariance(result)

        self.assertAllClose(true_mean,
                            sample_mean,
                            atol=tolerance,
                            rtol=tolerance)
        self.assertAllClose(true_cov,
                            sample_cov,
                            atol=tolerance,
                            rtol=tolerance)
  def test_log_joint_with_missing_observations(self):
    # Test that this component accepts MaskedTimeSeries inputs. In most
    # cases, it is sufficient that the component accesses only
    # `empirical_statistics(observed_time_series)`.
    # TODO(b/139483802): De-flake this test when run with --vary_seed.
    seed = test_util.test_seed_stream(hardcoded_seed=123)
    observed_time_series = np.array(
        [1.0, 2.0, -1000., 0.4, np.nan, 1000., 4.2, np.inf]).astype(np.float32)
    observation_mask = np.array(
        [False, False, True, False, True, True, False, True]).astype(np.bool_)
    masked_time_series = tfp.sts.MaskedTimeSeries(observed_time_series,
                                                  is_missing=observation_mask)

    model = self._build_sts(observed_time_series=masked_time_series)

    log_joint_fn = model.joint_log_prob(
        observed_time_series=masked_time_series)
    lp = self.evaluate(
        log_joint_fn(*[p.prior.sample(seed=seed()) for p in model.parameters]))

    self.assertEqual(tf.TensorShape([]), lp.shape)
    self.assertTrue(np.isfinite(lp))
Exemplo n.º 9
0
  def test_multipart_bijector(self):
    dist = tfd.JointDistributionNamed({
        'a': tfd.Exponential(1.),
        'b': tfd.Normal(0., 1.),
        'c': lambda b, a: tfd.Sample(tfd.Normal(b, a), sample_shape=[5])})

    seed = test_util.test_seed_stream()
    surrogate_posterior = (
        tfp.experimental.vi.build_factored_surrogate_posterior(
            event_shape=dist.event_shape,
            bijector=(
                dist.experimental_default_event_space_bijector()),
            initial_unconstrained_loc=functools.partial(
                tf.random.uniform, minval=-2., maxval=2.),
            seed=seed(),
            validate_args=True))
    self.evaluate([v.initializer
                   for v in surrogate_posterior.trainable_variables])

    # Test that the posterior has the specified event shape(s).
    self.assertAllEqualNested(
        self.evaluate(dist.event_shape_tensor()),
        self.evaluate(surrogate_posterior.event_shape_tensor()))

    posterior_sample_ = self.evaluate(surrogate_posterior.sample(seed=seed()))
    posterior_logprob_ = self.evaluate(
        surrogate_posterior.log_prob(posterior_sample_))

    # Test that all sample Tensors have the expected shapes.
    check_shape = lambda s, x: self.assertAllEqual(s, x.shape)
    self.assertAllAssertsNested(
        check_shape, dist.event_shape, posterior_sample_)

    # Test that samples are finite and not NaN.
    self.assertAllAssertsNested(self.assertAllFinite, posterior_sample_)

    # Test that logprob is scalar, finite, and not NaN.
    self.assertEmpty(posterior_logprob_.shape)
    self.assertAllFinite(posterior_logprob_)
Exemplo n.º 10
0
  def test_kahan_precision(self, jit=False):
    maybe_jit = lambda f: f
    if jit:
      self.skip_if_no_xla()
      maybe_jit = tf.function(jit_compile=True)

    n = 20_000
    stream = test_util.test_seed_stream()
    samps = tfd.Normal(0, 1).sample(n, seed=stream())

    scale = tfd.LogNormal(0, .2).sample([7, 1], seed=stream())
    mvn = tfd.MultivariateNormalDiag(
        loc=tf.zeros([n]), scale_diag=tf.zeros([n]) + scale,
        experimental_use_kahan_sum=True)
    mvn64 = tfd.MultivariateNormalDiag(
        loc=tf.zeros([n], dtype=tf.float64),
        scale_diag=tf.zeros([n], dtype=tf.float64) + tf.cast(scale, tf.float64))
    lp = maybe_jit(mvn.log_prob)(samps)
    lp64 = mvn64.log_prob(tf.cast(samps, tf.float64))
    lp, lp64 = self.evaluate((tf.cast(lp, tf.float64), lp64))
    # Without fastmath, without Kahan fails ~30-100%, max abs error up to .2
    self.assertAllClose(lp64, lp, rtol=0, atol=.006)
Exemplo n.º 11
0
 def testOwensTOddEven(self, dtype):
     seed_stream = test_util.test_seed_stream()
     a = tf.random.uniform(shape=[int(1e3)],
                           minval=0.,
                           maxval=100.,
                           dtype=dtype,
                           seed=seed_stream())
     h = tf.random.uniform(shape=[int(1e3)],
                           minval=0.,
                           maxval=100.,
                           dtype=dtype,
                           seed=seed_stream())
     # OwensT(h, a) = OwensT(-h, a)
     self.assertAllClose(
         self.evaluate(tfp.math.owens_t(h, a)),
         self.evaluate(tfp.math.owens_t(-h, a)),
     )
     # OwensT(h, a) = -OwensT(h, -a)
     self.assertAllClose(
         self.evaluate(tfp_math.owens_t(h, a)),
         self.evaluate(-tfp_math.owens_t(h, -a)),
     )
Exemplo n.º 12
0
  def test_explicit_init_samples(self):
    stream = test_util.test_seed_stream()

    # Compute everything in a function so it is consistent in graph mode
    @tf.function
    def do_sample():
      jd_model = tfd.JointDistributionNamed({
          'x': tfd.HalfNormal(1.),
          'y': lambda x: tfd.Normal(0., x)})
      init = {'x': tf.ones(64)}
      return tfp.experimental.mcmc.windowed_adaptive_hmc(
          10,
          jd_model,
          num_adaptation_steps=200,
          current_state=init,
          num_leapfrog_steps=5,
          discard_tuning=False,
          y=tf.constant(1.),
          seed=stream(),
          trace_fn=None)

    self.evaluate(do_sample())
Exemplo n.º 13
0
 def test_kahan_precision(self, jit=False):
     maybe_jit = lambda f: f
     if jit:
         self.skip_if_no_xla()
         maybe_jit = tf.function(experimental_compile=True)
     stream = test_util.test_seed_stream()
     n = 20_000
     samps = tfd.Poisson(rate=1.).sample(n, seed=stream())
     log_rate = tf.fill([n], tfd.Normal(0, .2).sample(seed=stream()))
     pois = tfd.Poisson(log_rate=log_rate)
     lp_fn = maybe_jit(
         tfd.Independent(pois,
                         reinterpreted_batch_ndims=1,
                         experimental_use_kahan_sum=True).log_prob)
     lp = lp_fn(samps)
     pois64 = tfd.Poisson(log_rate=tf.cast(log_rate, tf.float64))
     lp64 = tfd.Independent(pois64, reinterpreted_batch_ndims=1).log_prob(
         tf.cast(samps, tf.float64))
     # Evaluate together to ensure we use the same samples.
     lp, lp64 = self.evaluate((tf.cast(lp, tf.float64), lp64))
     # Fails ~75% CPU, 1-75% GPU --vary_seed runs w/o experimental_use_kahan_sum.
     self.assertAllClose(lp64, lp, rtol=0., atol=.01)
Exemplo n.º 14
0
  def testMVNConjugateLinearUpdatePreservesStructuredLinops(self):
    strm = test_util.test_seed_stream()
    num_outputs = 4

    prior_scale = tf.linalg.LinearOperatorScaledIdentity(num_outputs, 4.)
    likelihood_scale = tf.linalg.LinearOperatorScaledIdentity(num_outputs, 0.2)
    linear_transformation = tf.linalg.LinearOperatorIdentity(num_outputs)
    observation = tf.random.normal([num_outputs], seed=strm())
    posterior_mean, posterior_prec = (
        tfd.mvn_conjugate_linear_update(
            prior_scale=prior_scale,
            linear_transformation=linear_transformation,
            likelihood_scale=likelihood_scale,
            observation=observation))
    # TODO(davmre): enable next line once internal CI is updated to recent TF.
    # self.assertIsInstance(posterior_prec,
    #                       tf.linalg.LinearOperatorScaledIdentity)

    self._mvn_linear_update_test_helper(
        prior_mean=tf.zeros([num_outputs]),
        prior_scale=prior_scale.to_dense(),
        linear_transformation=linear_transformation.to_dense(),
        likelihood_scale=likelihood_scale.to_dense(),
        observation=observation,
        candidate_posterior_mean=posterior_mean,
        candidate_posterior_prec=posterior_prec.to_dense())

    # Also check the result against the scalar calculation.
    scalar_posterior_dist = tfd.normal_conjugates_known_scale_posterior(
        prior=tfd.Normal(loc=0., scale=prior_scale.diag_part()),
        scale=likelihood_scale.diag_part(),
        s=observation, n=1)
    (posterior_mean_, posterior_prec_,
     scalar_posterior_mean_, scalar_posterior_prec_) = self.evaluate(
         (posterior_mean, posterior_prec.to_dense(),
          scalar_posterior_dist.mean(),
          tf.linalg.diag(1./scalar_posterior_dist.variance())))
    self.assertAllClose(posterior_mean_, scalar_posterior_mean_)
    self.assertAllClose(posterior_prec_, scalar_posterior_prec_)
    def test_poisson_switchover_graphical_model(self):
        # Build a pretend dataset.
        seed = test_util.test_seed_stream(salt='poisson')
        n = [43, 31]
        count_data = tf.cast(tf.concat([
            tfd.Poisson(rate=15.).sample(n[0], seed=seed()),
            tfd.Poisson(rate=25.).sample(n[1], seed=seed()),
        ],
                                       axis=0),
                             dtype=tf.float32)
        count_data = self.evaluate(count_data)
        n = np.sum(n)

        # Make model.
        gather = lambda tau, lambda_: tf.gather(  # pylint: disable=g-long-lambda
            lambda_,
            indices=tf.cast(tau[..., tf.newaxis] < tf.linspace(0., 1., n),
                            dtype=tf.int32),
            # TODO(b/139204153): Remove static value hack after bug closed.
            batch_dims=int(tf.get_static_value(tf.rank(tau))))

        alpha = tf.math.reciprocal(tf.reduce_mean(count_data))

        joint = tfd.JointDistributionSequential(
            [
                tfd.Sample(tfd.Exponential(rate=alpha), sample_shape=[2]),
                tfd.Uniform(),
                lambda tau, lambda_: tfd.Independent(  # pylint: disable=g-long-lambda
                    tfd.Poisson(rate=gather(tau, lambda_)),
                    reinterpreted_batch_ndims=1),
            ],
            validate_args=True)

        # Verify model correctly "compiles".
        batch_shape = [3, 4]
        self.assertEqual(
            batch_shape,
            joint.log_prob(
                joint.sample(batch_shape, seed=test_util.test_seed())).shape)
Exemplo n.º 16
0
    def testSampleAgainstProb(self):
        seed_stream = test_util.test_seed_stream()

        n = 4
        c1 = self.evaluate(1. + 2. * tf.random.uniform(
            shape=[4, 3, 2], dtype=tf.float32, seed=seed_stream()))
        c0 = self.evaluate(1. + 2. * tf.random.uniform(
            shape=[4, 3, 1], dtype=tf.float32, seed=seed_stream()))
        dist = tfd.BetaBinomial(tf.cast(n, dtype=tf.float32),
                                c1,
                                c0,
                                validate_args=True)

        num_samples = int(1e4)
        x = self.evaluate(
            tf.cast(dist.sample(num_samples, seed=seed_stream()), tf.int32))

        for i in range(n + 1):
            self.assertAllClose(self.evaluate(dist.prob(i)),
                                np.sum(x == i, axis=0) / (num_samples * 1.0),
                                atol=0.01,
                                rtol=0.1)
Exemplo n.º 17
0
    def test_specifying_initial_loc(self, event_shape, initial_loc,
                                    implicit_batch_shape, bijector, dtype,
                                    is_static):
        initial_loc = tf.nest.map_structure(
            lambda s: self.maybe_static(  # pylint: disable=g-long-lambda
                np.array(s, dtype=dtype),
                is_static=is_static),
            initial_loc)

        if bijector is not None:
            initial_unconstrained_loc = tf.nest.map_structure(
                lambda x, b: x
                if b is None else b.inverse(x), initial_loc, bijector)
        else:
            initial_unconstrained_loc = initial_loc

        surrogate_posterior = (
            tfp.experimental.vi.build_factored_surrogate_posterior(
                event_shape=event_shape,
                initial_unconstrained_loc=initial_unconstrained_loc,
                initial_unconstrained_scale=1e-6,
                bijector=bijector,
                validate_args=True))
        self.evaluate(
            [v.initializer for v in surrogate_posterior.trainable_variables])

        seed = test_util.test_seed_stream()
        self._test_shapes(surrogate_posterior,
                          batch_shape=implicit_batch_shape,
                          event_shape=event_shape,
                          seed=seed())
        self._test_gradients(surrogate_posterior, seed=seed())
        self._test_dtype(surrogate_posterior, dtype, seed())

        # Check that the sampled values are close to the initial locs.
        posterior_sample_ = self.evaluate(
            surrogate_posterior.sample(seed=seed()))
        self.assertAllCloseNested(initial_loc, posterior_sample_, atol=1e-4)
Exemplo n.º 18
0
  def test_specifying_event_shape(
      self, event_shape, bijector, dtype, is_static):
    seed = test_util.test_seed_stream()
    surrogate_posterior = (
        tfp.experimental.vi.build_factored_surrogate_posterior(
            event_shape=tf.nest.map_structure(
                lambda s: self.maybe_static(  # pylint: disable=g-long-lambda
                    np.array(s, dtype=np.int32), is_static=is_static),
                event_shape),
            bijector=bijector,
            initial_unconstrained_loc=functools.partial(
                tf.random.uniform, minval=-2., maxval=2., dtype=dtype),
            seed=seed(),
            validate_args=True))
    self.evaluate([v.initializer
                   for v in surrogate_posterior.trainable_variables])
    posterior_sample_ = self.evaluate(surrogate_posterior.sample(seed=seed()))
    posterior_logprob_ = self.evaluate(
        surrogate_posterior.log_prob(posterior_sample_))
    posterior_event_shape = self.evaluate(
        surrogate_posterior.event_shape_tensor())

    # Test that the posterior has the specified event shape(s).
    self.assertAllEqualNested(event_shape, posterior_event_shape)

    # Test that all sample Tensors have the expected shapes.
    check_shape = lambda s, x: self.assertAllEqual(s, x.shape)
    tf.nest.map_structure(check_shape, event_shape, posterior_sample_)

    self.assertAllEqual([], posterior_logprob_.shape)

    # Test that gradients are available wrt the variational parameters.
    self.assertNotEmpty(surrogate_posterior.trainable_variables)
    with tf.GradientTape() as tape:
      posterior_logprob = surrogate_posterior.log_prob(posterior_sample_)
    grad = tape.gradient(posterior_logprob,
                         surrogate_posterior.trainable_variables)
    self.assertTrue(all(g is not None for g in grad))
Exemplo n.º 19
0
    def testParamPropertiesAndFromParams(self):
        classes = [
            tfd.Normal,
            tfd.Bernoulli,
            tfd.Beta,
            tfd.Chi2,
            tfd.Exponential,
            tfd.Gamma,
            tfd.InverseGamma,
            tfd.Laplace,
            tfd.StudentT,
            tfd.Uniform,
        ]

        sample_shapes = [(), (10, ), (10, 20, 30)]
        seed_stream = test_util.test_seed_stream('param_shapes')
        for cls in classes:
            for sample_shape in sample_shapes:
                parameter_properties = cls.parameter_properties()
                param_shapes = {
                    name: param.shape_fn(sample_shape)  # pylint: disable=comprehension-too-complex
                    for name, param in parameter_properties.items()
                    if param.is_preferred
                }
                params = {
                    name: tf.random.normal(shape, seed=seed_stream())
                    for name, shape in param_shapes.items()
                }
                dist = cls(**params)
                self.assertAllEqual(
                    sample_shape,
                    self.evaluate(tf.shape(dist.sample(seed=seed_stream()))))
                dist_copy = dist.copy()
                self.assertAllEqual(
                    sample_shape,
                    self.evaluate(
                        tf.shape(dist_copy.sample(seed=seed_stream()))))
                self.assertEqual(dist.parameters, dist_copy.parameters)
Exemplo n.º 20
0
    def testLogProbAgainstDirichletMultinomial(self):
        seed_stream = test_util.test_seed_stream()

        n = tf.constant([10., 20., 30.])
        c1 = self.evaluate(1. + 2. * tf.random.uniform(
            shape=[4, 3], dtype=tf.float32, seed=seed_stream()))
        c0 = self.evaluate(1. + 2. * tf.random.uniform(
            shape=[4, 3], dtype=tf.float32, seed=seed_stream()))

        beta_binomial = tfd.BetaBinomial(n, c1, c0, validate_args=True)
        dirichlet_multinomial = tfd.DirichletMultinomial(n,
                                                         tf.stack([c1, c0],
                                                                  axis=-1),
                                                         validate_args=True)

        num_samples = 3

        beta_binomial_sample = self.evaluate(
            beta_binomial.sample(num_samples, seed=seed_stream()))
        beta_binomial_log_prob = beta_binomial.log_prob(beta_binomial_sample)
        dirichlet_multinomial_log_prob = dirichlet_multinomial.log_prob(
            tf.stack([beta_binomial_sample, n - beta_binomial_sample],
                     axis=-1))
        self.assertAllClose(self.evaluate(beta_binomial_log_prob),
                            self.evaluate(dirichlet_multinomial_log_prob),
                            rtol=1e-4,
                            atol=1e-4)

        dirichlet_multinomial_sample = self.evaluate(
            dirichlet_multinomial.sample(num_samples, seed=seed_stream()))
        dirichlet_multinomial_log_prob = dirichlet_multinomial.log_prob(
            dirichlet_multinomial_sample)
        beta_binomial_log_prob = beta_binomial.log_prob(
            tf.squeeze(dirichlet_multinomial_sample[..., 0]))
        self.assertAllClose(self.evaluate(dirichlet_multinomial_log_prob),
                            self.evaluate(beta_binomial_log_prob),
                            rtol=1e-4,
                            atol=1e-4)
Exemplo n.º 21
0
  def test_random_projections(self, dtype):
    strm = tfp_test_util.test_seed_stream()
    rng = np.random.RandomState(seed=strm() % 2**31)
    num_samples = 57000

    # Validate experiment design

    # False fail rate here is the target rate of 1e-6 divided by the number of
    # projections.
    d = st.min_discrepancy_of_true_cdfs_detectable_by_dkwm_two_sample(
        num_samples, num_samples, false_fail_rate=1e-8, false_pass_rate=1e-6)
    # Choose num_samples so the discrepancy is below 0.05, which should be
    # enough to detect a mean shift of around 1/8 of a standard deviation, or a
    # scale increase of around 25% (in any particular projection).
    self.assertLess(self.evaluate(d), 0.05)

    ground_truth = rng.multivariate_normal(
        mean=[0, 0], cov=[[1, 0.5], [0.5, 1]], size=num_samples).astype(dtype)
    more_samples = rng.multivariate_normal(
        mean=[0, 0], cov=[[1, 0.5], [0.5, 1]], size=num_samples).astype(dtype)
    self.evaluate(
        st.assert_multivariate_true_cdf_equal_on_projections_two_sample(
            ground_truth, more_samples, num_projections=100,
            false_fail_rate=1e-6, seed=strm()))

    def assert_catches_mistake(mean, cov):
      wrong_samples = rng.multivariate_normal(
          mean=mean, cov=cov, size=num_samples).astype(dtype=dtype)
      msg = 'Empirical CDFs outside joint K-S envelope'
      with self.assertRaisesOpError(msg):
        self.evaluate(
            st.assert_multivariate_true_cdf_equal_on_projections_two_sample(
                ground_truth, wrong_samples, num_projections=100,
                false_fail_rate=1e-6, seed=strm()))

    assert_catches_mistake([0, 1], [[1, 0.5], [0.5, 1]])
    assert_catches_mistake([0, 0], [[1, 0.7], [0.7, 1]])
    assert_catches_mistake([0, 0], [[1, 0.3], [0.3, 1]])
Exemplo n.º 22
0
    def test_ensemble_kalman_filter_constant_model_multivariate(self):
        def transition_fn(_, particles, extra):
            return tfd.MultivariateNormalDiag(loc=particles,
                                              scale_diag=[1e-11] * 2), extra

        def observation_fn(_, particles, extra):
            return tfd.MultivariateNormalDiag(loc=particles,
                                              scale_diag=[1e-1] * 2), extra

        seed_stream = test_util.test_seed_stream()

        # Initialize the ensemble.
        particles = self.evaluate(
            tf.random.normal(shape=[300, 3, 2],
                             seed=seed_stream(),
                             dtype=tf.float64))

        state = tfs.EnsembleKalmanFilterState(step=0,
                                              particles=particles,
                                              extra={'unchanged': 1})

        for _ in range(8):
            state = tfs.ensemble_kalman_filter_predict(
                state,
                transition_fn=transition_fn,
                seed=seed_stream(),
                inflate_fn=None)

            state = tfs.ensemble_kalman_filter_update(
                state,
                observation=[0., 0.],
                observation_fn=observation_fn,
                seed=seed_stream())

        self.assertAllClose([[0., 0.]] * 3,
                            self.evaluate(
                                tf.reduce_mean(state.particles, axis=0)),
                            atol=1e-2)
    def VerifyPowerSphericalVonMisesFisherKL(self, dim):
        seed_stream = test_util.test_seed_stream()
        mean_direction1 = tf.random.uniform(shape=[5, dim],
                                            minval=self.dtype(1.),
                                            maxval=self.dtype(2.),
                                            dtype=self.dtype,
                                            seed=seed_stream())
        mean_direction2 = tf.random.uniform(shape=[5, dim],
                                            minval=self.dtype(1.),
                                            maxval=self.dtype(2.),
                                            dtype=self.dtype,
                                            seed=seed_stream())

        mean_direction1 = tf.nn.l2_normalize(mean_direction1, axis=-1)
        mean_direction2 = tf.nn.l2_normalize(mean_direction2, axis=-1)
        concentration1 = tf.math.log(
            tf.random.uniform(shape=[2, 1],
                              minval=self.dtype(1.),
                              maxval=self.dtype(100.),
                              dtype=self.dtype,
                              seed=seed_stream()))
        concentration2 = tf.math.log(
            tf.random.uniform(shape=[2, 1],
                              minval=self.dtype(1.),
                              maxval=self.dtype(100.),
                              dtype=self.dtype,
                              seed=seed_stream()))

        ps = tfp.distributions.PowerSpherical(mean_direction=mean_direction1,
                                              concentration=concentration1)
        vmf = tfp.distributions.VonMisesFisher(mean_direction=mean_direction2,
                                               concentration=concentration2)
        x = ps.sample(int(6e4), seed=test_util.test_seed())

        kl_sample = tf.reduce_mean(ps.log_prob(x) - vmf.log_prob(x), axis=0)
        true_kl = tfp.distributions.kl_divergence(ps, vmf)
        true_kl_, kl_sample_ = self.evaluate([true_kl, kl_sample])
        self.assertAllClose(true_kl_, kl_sample_, atol=0.0, rtol=7e-2)
Exemplo n.º 24
0
    def VerifyVonMisesFisherUniformKL(self, dim):
        seed_stream = test_util.test_seed_stream()
        mean_direction = tf.random.uniform(shape=[4, dim],
                                           minval=1.,
                                           maxval=4.,
                                           seed=seed_stream())
        mean_direction = tf.nn.l2_normalize(mean_direction, axis=-1)
        concentration = tf.math.log(
            tf.random.uniform(shape=[2, 1],
                              minval=2.,
                              maxval=20.,
                              seed=seed_stream()))

        vmf = tfp.distributions.VonMisesFisher(mean_direction=mean_direction,
                                               concentration=concentration)
        su = tfp.distributions.SphericalUniform(dimension=dim)

        x = vmf.sample(int(5e4), seed=test_util.test_seed())

        kl_sample = tf.reduce_mean(vmf.log_prob(x) - su.log_prob(x), axis=0)
        true_kl = tfp.distributions.kl_divergence(vmf, su)
        true_kl_, kl_sample_ = self.evaluate([true_kl, kl_sample])
        self.assertAllClose(true_kl_, kl_sample_, atol=0.0, rtol=0.3)
Exemplo n.º 25
0
 def test_step_size_changed(self):
     target_dist = tfd.MultivariateNormalDiag(loc=[0., 0.],
                                              scale_diag=[1., 10.])
     # `hmc_kernel`'s step size is far from optimal
     hmc_kernel = tfp.mcmc.HamiltonianMonteCarlo(
         target_log_prob_fn=target_dist.log_prob,
         num_leapfrog_steps=27,
         step_size=10)
     step_adaptation_kernel = tfp.mcmc.SimpleStepSizeAdaptation(
         inner_kernel=hmc_kernel,
         adaptation_rate=0.8,
         num_adaptation_steps=9)
     trans_kernel = tfp.mcmc.TransformedTransitionKernel(
         inner_kernel=step_adaptation_kernel, bijector=tfb.Exp())
     kernel_results = trans_kernel.inner_kernel.bootstrap_results(
         tf.zeros(2))
     stream = test_util.test_seed_stream()
     for _ in range(2):
         _, kernel_results = trans_kernel.inner_kernel.one_step(
             tf.zeros(2), kernel_results, seed=stream())
     adapted_step_size = self.evaluate(
         kernel_results.inner_results.accepted_results.step_size)
     self.assertLess(adapted_step_size, 7)
Exemplo n.º 26
0
 def testLargeLogProbDiffScalarUnderlying(self):
     shp = [25, 200]
     d0 = tfd.Sample(tfd.Normal(0., .1), shp)
     d1 = tfd.Sample(tfd.Normal(1e-5, .1), shp)
     strm = test_util.test_seed_stream()
     x0 = self.evaluate(  # overdispersed
         tfd.Normal(0, 2).sample(shp, seed=strm()))
     x1 = self.evaluate(  # overdispersed, perturbed
         x0 + tfd.Normal(0, 1e-6).sample(x0.shape, seed=strm()))
     d0_64 = d0.copy(distribution=tfd.Normal(
         tf.cast(d0.distribution.loc, tf.float64),
         tf.cast(d0.distribution.scale, tf.float64)))
     d1_64 = d1.copy(distribution=tfd.Normal(
         tf.cast(d1.distribution.loc, tf.float64),
         tf.cast(d1.distribution.scale, tf.float64)))
     oracle_64 = tf.reduce_sum(
         d0_64.distribution.log_prob(tf.cast(x0, tf.float64)) -
         d1_64.distribution.log_prob(tf.cast(x1, tf.float64)))
     self.assertAllClose(oracle_64,
                         tfp.experimental.distributions.log_prob_ratio(
                             d0, x0, d1, x1),
                         rtol=0.,
                         atol=0.007)
 def test_recip_scale_exp(self):
     p = tfb.Reciprocal()(tfb.Scale(3.)(tfb.Exp()))
     stream = test_util.test_seed_stream()
     dim = 2
     x = self.evaluate(tf.random.uniform([4, dim], seed=stream()))
     q = tfb.Reciprocal()(tfb.Scale(2.)(tfb.Exp()))
     y = self.evaluate(tf.random.uniform([4, dim], seed=stream()))
     expected_fldjr = ((x - y) +  # Exp.fldj
                       (np.log(3) - np.log(2)) +  # Scale.fldj
                       -2 * (np.log(3. * np.exp(x) /
                                    (2 * np.exp(y))))  # Reciprocal.fldj
                       ).sum(-1)
     self.assertAllClose(
         expected_fldjr,
         tfeb.forward_log_det_jacobian_ratio(p, x, q, y, event_ndims=1))
     self.assertAllClose(
         expected_fldjr,
         p.forward_log_det_jacobian(x, 1) -
         q.forward_log_det_jacobian(y, 1))
     self.assertAllClose(
         p.inverse_log_det_jacobian(x, 1) -
         q.inverse_log_det_jacobian(y, 1),
         tfeb.inverse_log_det_jacobian_ratio(p, x, q, y, event_ndims=1))
Exemplo n.º 28
0
    def testPairwiseSquareDistanceMatrix(self, feature_ndims, dims):
        batch_shape = [2, 3]
        seed_stream = test_util.test_seed_stream('pairwise_square_distance')
        x1 = tf.random.normal(dtype=np.float64,
                              shape=batch_shape + [dims] * feature_ndims,
                              seed=seed_stream())
        x2 = tf.random.normal(dtype=np.float64,
                              shape=batch_shape + [dims] * feature_ndims,
                              seed=seed_stream())
        pairwise_square_distance = util.pairwise_square_distance_matrix(
            x1, x2, feature_ndims)

        x1_pad = util.pad_shape_with_ones(x1,
                                          ndims=1,
                                          start=-(feature_ndims + 1))
        x2_pad = util.pad_shape_with_ones(x2,
                                          ndims=1,
                                          start=-(feature_ndims + 2))
        actual_square_distance = util.sum_rightmost_ndims_preserving_shape(
            tf.math.squared_difference(x1_pad, x2_pad), feature_ndims)
        pairwise_square_distance_, actual_square_distance_ = self.evaluate(
            [pairwise_square_distance, actual_square_distance])
        self.assertAllClose(pairwise_square_distance_, actual_square_distance_)
 def VerifyEntropy(self, dim):
     seed_stream = test_util.test_seed_stream()
     mean_direction = tf.random.uniform(shape=[5, dim],
                                        minval=self.dtype(1.),
                                        maxval=self.dtype(2.),
                                        dtype=self.dtype,
                                        seed=seed_stream())
     mean_direction = tf.nn.l2_normalize(mean_direction, axis=-1)
     concentration = tf.math.log(
         tf.random.uniform(shape=[2, 1],
                           minval=self.dtype(1.),
                           maxval=self.dtype(100.),
                           dtype=self.dtype,
                           seed=seed_stream()))
     ps = tfp.distributions.PowerSpherical(mean_direction=mean_direction,
                                           concentration=concentration,
                                           validate_args=True,
                                           allow_nan_stats=False)
     samples = ps.sample(int(3e4), seed=test_util.test_seed())
     sample_entropy = -tf.reduce_mean(ps.log_prob(samples), axis=0)
     true_entropy, sample_entropy = self.evaluate(
         [ps.entropy(), sample_entropy])
     self.assertAllClose(sample_entropy, true_entropy, rtol=3e-2)
  def test_default_priors_follow_batch_shapes(self):
    seed = test_util.test_seed_stream()
    num_timesteps = 3
    time_series_sample_shape = [4, 2]
    observation_shape_full = time_series_sample_shape + [num_timesteps]
    dummy_observation = np.random.randn(
        *(observation_shape_full)).astype(np.float32)

    model = self._build_sts(observed_time_series=dummy_observation)

    # The model should construct a default parameter prior for *each* observed
    # time series, so the priors will have batch_shape equal to
    # `time_series_sample_shape`.
    for parameter in model.parameters:
      self.assertEqual(parameter.prior.batch_shape, time_series_sample_shape)

    # The initial state prior should also have the appropriate batch shape.
    # To test this, we build the ssm and test that it has a consistent
    # broadcast batch shape.
    param_samples = [p.prior.sample(seed=seed()) for p in model.parameters]
    ssm = model.make_state_space_model(
        num_timesteps=num_timesteps, param_vals=param_samples)
    self.assertEqual(ssm.batch_shape, time_series_sample_shape)