Exemplo n.º 1
0
 def _sample_n(self, n, seed=None):
     a = array_ops.ones_like(self.a_b_sum, dtype=self.dtype) * self.a
     b = array_ops.ones_like(self.a_b_sum, dtype=self.dtype) * self.b
     gamma1_sample = random_ops.random_gamma([n], a, dtype=self.dtype, seed=seed)
     gamma2_sample = random_ops.random_gamma([n], b, dtype=self.dtype, seed=seed)
     beta_sample = gamma1_sample / (gamma1_sample + gamma2_sample)
     return beta_sample
 def loop_fn(i):
   alphas_i = array_ops.gather(alphas, i)
   # Test both scalar and non-scalar params and shapes.
   return (random_ops.random_gamma(alpha=alphas_i[0, 0], shape=[]),
           random_ops.random_gamma(alpha=alphas_i, shape=[]),
           random_ops.random_gamma(alpha=alphas_i[0, 0], shape=[3]),
           random_ops.random_gamma(alpha=alphas_i, shape=[3]))
Exemplo n.º 3
0
  def sample_n(self, n, seed=None, name="sample_n"):
    """Sample `n` observations from the Beta Distributions.

    Args:
      n: `Scalar` `Tensor` of type `int32` or `int64`, the number of
        observations to sample.
      seed: Python integer, the random seed.
      name: The name to give this op.

    Returns:
      samples: `[n, ...]`, a `Tensor` of `n` samples for each
        of the distributions determined by broadcasting the hyperparameters.
    """
    with ops.name_scope(self.name):
      with ops.name_scope(name, values=[self.a, self.b, n]):
        a = array_ops.ones_like(self._a_b_sum, dtype=self.dtype) * self.a
        b = array_ops.ones_like(self._a_b_sum, dtype=self.dtype) * self.b
        n = ops.convert_to_tensor(n, name="n")

        gamma1_sample = random_ops.random_gamma(
            [n,], a, dtype=self.dtype, seed=seed)
        gamma2_sample = random_ops.random_gamma(
            [n,], b, dtype=self.dtype, seed=seed)

        beta_sample = gamma1_sample / (gamma1_sample + gamma2_sample)

        n_val = tensor_util.constant_value(n)
        final_shape = tensor_shape.vector(n_val).concatenate(
            self._a_b_sum.get_shape())

        beta_sample.set_shape(final_shape)
        return beta_sample
Exemplo n.º 4
0
 def _sample_n(self, n, seed=None):
   a = array_ops.ones_like(self.a_b_sum, dtype=self.dtype) * self.a
   b = array_ops.ones_like(self.a_b_sum, dtype=self.dtype) * self.b
   gamma1_sample = random_ops.random_gamma(
       [n,], a, dtype=self.dtype, seed=seed)
   gamma2_sample = random_ops.random_gamma(
       [n,], b, dtype=self.dtype,
       seed=distribution_util.gen_new_seed(seed, "beta"))
   beta_sample = gamma1_sample / (gamma1_sample + gamma2_sample)
   return beta_sample
 def testShape(self):
   # Fully known shape.
   rnd = random_ops.random_gamma([150], 2.0)
   self.assertEqual([150], rnd.get_shape().as_list())
   rnd = random_ops.random_gamma([150], 2.0, beta=[3.0, 4.0])
   self.assertEqual([150, 2], rnd.get_shape().as_list())
   rnd = random_ops.random_gamma([150], array_ops.ones([1, 2, 3]))
   self.assertEqual([150, 1, 2, 3], rnd.get_shape().as_list())
   rnd = random_ops.random_gamma([20, 30], array_ops.ones([1, 2, 3]))
   self.assertEqual([20, 30, 1, 2, 3], rnd.get_shape().as_list())
   rnd = random_ops.random_gamma(
       [123], array_ops.placeholder(
           dtypes.float32, shape=(2,)))
   self.assertEqual([123, 2], rnd.get_shape().as_list())
   # Partially known shape.
   rnd = random_ops.random_gamma(
       array_ops.placeholder(
           dtypes.int32, shape=(1,)), array_ops.ones([7, 3]))
   self.assertEqual([None, 7, 3], rnd.get_shape().as_list())
   rnd = random_ops.random_gamma(
       array_ops.placeholder(
           dtypes.int32, shape=(3,)), array_ops.ones([9, 6]))
   self.assertEqual([None, None, None, 9, 6], rnd.get_shape().as_list())
   # Unknown shape.
   rnd = random_ops.random_gamma(
       array_ops.placeholder(dtypes.int32),
       array_ops.placeholder(dtypes.float32))
   self.assertIs(None, rnd.get_shape().ndims)
   rnd = random_ops.random_gamma([50], array_ops.placeholder(dtypes.float32))
   self.assertIs(None, rnd.get_shape().ndims)
  def testNoCSE(self):
    """CSE = constant subexpression eliminator.

    SetIsStateful() should prevent two identical random ops from getting
    merged.
    """
    for dtype in dtypes.float16, dtypes.float32, dtypes.float64:
      for use_gpu in [False, True]:
        with self.cached_session(use_gpu=use_gpu):
          rnd1 = random_ops.random_gamma([24], 2.0, dtype=dtype)
          rnd2 = random_ops.random_gamma([24], 2.0, dtype=dtype)
          diff = rnd2 - rnd1
          self.assertGreater(np.linalg.norm(diff.eval()), 0.1)
 def testPositive(self):
   n = int(10e3)
   for dt in [dtypes.float16, dtypes.float32, dtypes.float64]:
     with self.cached_session():
       x = random_ops.random_gamma(shape=[n], alpha=0.001, dtype=dt, seed=0)
       self.assertEqual(0, math_ops.reduce_sum(math_ops.cast(
           math_ops.less_equal(x, 0.), dtype=dtypes.int64)).eval())
Exemplo n.º 8
0
  def _sample_n(self, n, seed):
    batch_shape = self.batch_shape_tensor()
    event_shape = self.event_shape_tensor()
    batch_ndims = array_ops.shape(batch_shape)[0]

    ndims = batch_ndims + 3  # sample_ndims=1, event_ndims=2
    shape = array_ops.concat([[n], batch_shape, event_shape], 0)

    # Complexity: O(nbk**2)
    x = random_ops.random_normal(shape=shape,
                                 mean=0.,
                                 stddev=1.,
                                 dtype=self.dtype,
                                 seed=seed)

    # Complexity: O(nbk)
    # This parametrization is equivalent to Chi2, i.e.,
    # ChiSquared(k) == Gamma(alpha=k/2, beta=1/2)
    expanded_df = self.df * array_ops.ones(
        self.scale_operator.batch_shape_tensor(),
        dtype=self.df.dtype.base_dtype)
    g = random_ops.random_gamma(shape=[n],
                                alpha=self._multi_gamma_sequence(
                                    0.5 * expanded_df, self.dimension),
                                beta=0.5,
                                dtype=self.dtype,
                                seed=distribution_util.gen_new_seed(
                                    seed, "wishart"))

    # Complexity: O(nbk**2)
    x = array_ops.matrix_band_part(x, -1, 0)  # Tri-lower.

    # Complexity: O(nbk)
    x = array_ops.matrix_set_diag(x, math_ops.sqrt(g))

    # Make batch-op ready.
    # Complexity: O(nbk**2)
    perm = array_ops.concat([math_ops.range(1, ndims), [0]], 0)
    x = array_ops.transpose(x, perm)
    shape = array_ops.concat([batch_shape, [event_shape[0]], [-1]], 0)
    x = array_ops.reshape(x, shape)

    # Complexity: O(nbM) where M is the complexity of the operator solving a
    # vector system. E.g., for LinearOperatorDiag, each matmul is O(k**2), so
    # this complexity is O(nbk**2). For LinearOperatorLowerTriangular,
    # each matmul is O(k^3) so this step has complexity O(nbk^3).
    x = self.scale_operator.matmul(x)

    # Undo make batch-op ready.
    # Complexity: O(nbk**2)
    shape = array_ops.concat([batch_shape, event_shape, [n]], 0)
    x = array_ops.reshape(x, shape)
    perm = array_ops.concat([[ndims - 1], math_ops.range(0, ndims - 1)], 0)
    x = array_ops.transpose(x, perm)

    if not self.cholesky_input_output_matrices:
      # Complexity: O(nbk^3)
      x = math_ops.matmul(x, x, adjoint_b=True)

    return x
Exemplo n.º 9
0
 def _sample_n(self, n, seed=None):
   return 1. / random_ops.random_gamma(
       shape=[n],
       alpha=self.concentration,
       beta=self.rate,
       dtype=self.dtype,
       seed=seed)
Exemplo n.º 10
0
 def _sample_n(self, n, seed=None):
   n_draws = math_ops.cast(self.n, dtype=dtypes.int32)
   if self.n.get_shape().ndims is not None:
     if self.n.get_shape().ndims != 0:
       raise NotImplementedError(
           "Sample only supported for scalar number of draws.")
   elif self.validate_args:
     is_scalar = check_ops.assert_rank(
         n_draws, 0,
         message="Sample only supported for scalar number of draws.")
     n_draws = control_flow_ops.with_dependencies([is_scalar], n_draws)
   k = self.event_shape()[0]
   unnormalized_logits = array_ops.reshape(
       math_ops.log(random_ops.random_gamma(
           shape=[n],
           alpha=self.alpha,
           dtype=self.dtype,
           seed=seed)),
       shape=[-1, k])
   draws = random_ops.multinomial(
       logits=unnormalized_logits,
       num_samples=n_draws,
       seed=distribution_util.gen_new_seed(seed, salt="dirichlet_multinomial"))
   x = math_ops.reduce_sum(array_ops.one_hot(draws, depth=k),
                           reduction_indices=-2)
   final_shape = array_ops.concat([[n], self.batch_shape(), [k]], 0)
   return array_ops.reshape(x, final_shape)
Exemplo n.º 11
0
 def _sample_n(self, n, seed=None):
   gamma_sample = random_ops.random_gamma(
       shape=[n],
       alpha=self.concentration,
       dtype=self.dtype,
       seed=seed)
   return gamma_sample / math_ops.reduce_sum(gamma_sample, -1, keep_dims=True)
Exemplo n.º 12
0
  def _testCompareToExplicitDerivative(self, dtype):
    """Compare to the explicit reparameterization derivative.

    Verifies that the computed derivative satisfies
    dsample / dalpha = d igammainv(alpha, u) / dalpha,
    where u = igamma(alpha, sample).

    Args:
      dtype: TensorFlow dtype to perform the computations in.
    """
    delta = 1e-3
    np_dtype = dtype.as_numpy_dtype
    try:
      from scipy import misc  # pylint: disable=g-import-not-at-top
      from scipy import special  # pylint: disable=g-import-not-at-top

      alpha_val = np.logspace(-2, 3, dtype=np_dtype)
      alpha = constant_op.constant(alpha_val)
      sample = random_ops.random_gamma([], alpha, np_dtype(1.0), dtype=dtype)
      actual = gradients_impl.gradients(sample, alpha)[0]

      (sample_val, actual_val) = self.evaluate((sample, actual))

      u = special.gammainc(alpha_val, sample_val)
      expected_val = misc.derivative(
          lambda alpha_prime: special.gammaincinv(alpha_prime, u),
          alpha_val, dx=delta * alpha_val)

      self.assertAllClose(actual_val, expected_val, rtol=1e-3, atol=1e-3)
    except ImportError as e:
      tf_logging.warn("Cannot use special functions in a test: %s" % str(e))
Exemplo n.º 13
0
 def _sample_n(self, n, seed=None):
   """See the documentation for tf.random_gamma for more details."""
   return random_ops.random_gamma([n],
                                  self.alpha,
                                  beta=self.beta,
                                  dtype=self.dtype,
                                  seed=seed)
Exemplo n.º 14
0
  def testQuadraticLoss(self):
    """Statistical test for the gradient.

    The equation (5) of https://arxiv.org/abs/1805.08498 says
      d/dalpha E_{sample ~ Gamma(alpha, 1)} f(sample)
        = E_{sample ~ Gamma(alpha, 1)} df(sample)/dalpha.

    Choose a quadratic loss function f(sample) = (sample - t)^2.
    Then, the lhs can be computed analytically:
      d/dalpha E_{sample ~ Gamma(alpha, 1)} f(sample)
        = d/dalpha [ (alpha + alpha^2) - 2 * t * alpha + t^2 ]
        = 1 + 2 * alpha - 2 * t.

    We compare the Monte-Carlo estimate of the expectation with the
    true gradient.
    """
    num_samples = 1000
    t = 0.3
    alpha = 0.5
    expected = 1 + 2 * alpha - 2 * t

    alpha = constant_op.constant(alpha)
    sample = random_ops.random_gamma([num_samples], alpha, 1.0)
    loss = math_ops.reduce_mean(math_ops.square(sample - t))
    dloss_dalpha = gradients_impl.gradients(loss, alpha)[0]
    dloss_dalpha_val = self.evaluate(dloss_dalpha)
    self.assertAllClose(expected, dloss_dalpha_val, atol=1e-1, rtol=1e-1)
 def func():
   with self.session(use_gpu=use_gpu, graph=ops.Graph()) as sess:
     rng = random_ops.random_gamma(
         [num], alpha, beta=beta, dtype=dtype, seed=seed)
     ret = np.empty([10, num])
     for i in xrange(10):
       ret[i, :] = sess.run(rng)
   return ret
Exemplo n.º 16
0
 def testGradientsShapeWithOneSamplePerParameter(self):
   shape = []
   alpha = array_ops.ones([2, 2])
   beta = array_ops.ones([1, 2])
   sample = random_ops.random_gamma(shape, alpha, beta)
   grads_alpha, grads_beta = gradients_impl.gradients(sample, [alpha, beta])
   self.assertAllEqual(grads_alpha.shape, alpha.shape)
   self.assertAllEqual(grads_beta.shape, beta.shape)
Exemplo n.º 17
0
 def _sample_n(self, n, seed=None):
   expanded_concentration1 = array_ops.ones_like(
       self.total_concentration, dtype=self.dtype) * self.concentration1
   expanded_concentration0 = array_ops.ones_like(
       self.total_concentration, dtype=self.dtype) * self.concentration0
   gamma1_sample = random_ops.random_gamma(
       shape=[n],
       alpha=expanded_concentration1,
       dtype=self.dtype,
       seed=seed)
   gamma2_sample = random_ops.random_gamma(
       shape=[n],
       alpha=expanded_concentration0,
       dtype=self.dtype,
       seed=distribution_util.gen_new_seed(seed, "beta"))
   beta_sample = gamma1_sample / (gamma1_sample + gamma2_sample)
   return beta_sample
Exemplo n.º 18
0
 def testGradientsShape(self):
   shape = [2, 3]
   alpha = array_ops.ones([2, 2])
   beta = array_ops.ones([1, 2])
   sample = random_ops.random_gamma(shape, alpha, beta, seed=12345)
   grads_alpha, grads_beta = gradients_impl.gradients(sample, [alpha, beta])
   self.assertAllEqual(grads_alpha.shape, alpha.shape)
   self.assertAllEqual(grads_beta.shape, beta.shape)
Exemplo n.º 19
0
  def _sample_n(self, n, seed):
    batch_shape = self.batch_shape()
    event_shape = self.event_shape()
    batch_ndims = array_ops.shape(batch_shape)[0]

    ndims = batch_ndims + 3  # sample_ndims=1, event_ndims=2
    shape = array_ops.concat(((n,), batch_shape, event_shape), 0)

    # Complexity: O(nbk^2)
    x = random_ops.random_normal(shape=shape,
                                 mean=0.,
                                 stddev=1.,
                                 dtype=self.dtype,
                                 seed=seed)

    # Complexity: O(nbk)
    # This parametrization is equivalent to Chi2, i.e.,
    # ChiSquared(k) == Gamma(alpha=k/2, beta=1/2)
    g = random_ops.random_gamma(shape=(n,),
                                alpha=self._multi_gamma_sequence(
                                    0.5 * self.df, self.dimension),
                                beta=0.5,
                                dtype=self.dtype,
                                seed=distribution_util.gen_new_seed(
                                    seed, "wishart"))

    # Complexity: O(nbk^2)
    x = array_ops.matrix_band_part(x, -1, 0)  # Tri-lower.

    # Complexity: O(nbk)
    x = array_ops.matrix_set_diag(x, math_ops.sqrt(g))

    # Make batch-op ready.
    # Complexity: O(nbk^2)
    perm = array_ops.concat((math_ops.range(1, ndims), (0,)), 0)
    x = array_ops.transpose(x, perm)
    shape = array_ops.concat((batch_shape, (event_shape[0], -1)), 0)
    x = array_ops.reshape(x, shape)

    # Complexity: O(nbM) where M is the complexity of the operator solving a
    # vector system.  E.g., for OperatorPDDiag, each matmul is O(k^2), so
    # this complexity is O(nbk^2). For OperatorPDCholesky, each matmul is
    # O(k^3) so this step has complexity O(nbk^3).
    x = self.scale_operator_pd.sqrt_matmul(x)

    # Undo make batch-op ready.
    # Complexity: O(nbk^2)
    shape = array_ops.concat((batch_shape, event_shape, (n,)), 0)
    x = array_ops.reshape(x, shape)
    perm = array_ops.concat(((ndims - 1,), math_ops.range(0, ndims - 1)), 0)
    x = array_ops.transpose(x, perm)

    if not self.cholesky_input_output_matrices:
      # Complexity: O(nbk^3)
      x = math_ops.matmul(x, x, adjoint_b=True)

    return x
Exemplo n.º 20
0
 def _sample_n(self, n, seed=None):
   # The sampling method comes from the well known fact that if X ~ Normal(0,
   # 1), and Z ~ Chi2(df), then X / sqrt(Z / df) ~ StudentT(df).
   shape = array_ops.concat(0, ([n], self.batch_shape()))
   normal_sample = random_ops.random_normal(
       shape, dtype=self.dtype, seed=seed)
   half = constant_op.constant(0.5, self.dtype)
   df = self.df * array_ops.ones(self.batch_shape(), dtype=self.dtype)
   gamma_sample = random_ops.random_gamma(
       [n,], half * df, beta=half, dtype=self.dtype,
       seed=distribution_util.gen_new_seed(seed, salt="student_t"))
   samples = normal_sample / math_ops.sqrt(gamma_sample / df)
   return samples * self.sigma + self.mu
Exemplo n.º 21
0
 def _sample_n(self, n, seed=None):
   # Here we use the fact that if:
   # lam ~ Gamma(concentration=total_count, rate=(1-probs)/probs)
   # then X ~ Poisson(lam) is Negative Binomially distributed.
   rate = random_ops.random_gamma(
       shape=[n],
       alpha=self.total_count,
       beta=math_ops.exp(-self.logits),
       dtype=self.dtype,
       seed=seed)
   return random_ops.random_poisson(
       rate,
       shape=[],
       dtype=self.dtype,
       seed=distribution_util.gen_new_seed(seed, "negative_binom"))
Exemplo n.º 22
0
  def testGradientsUnknownShape(self):
    shape = array_ops.placeholder(dtypes.int32)
    alpha = array_ops.placeholder(dtypes.float32)
    beta = array_ops.placeholder(dtypes.float32)
    sample = random_ops.random_gamma(shape, alpha, beta)
    grads_alpha, grads_beta = gradients_impl.gradients(sample, [alpha, beta])

    alpha_val = np.ones([1, 2])
    beta_val = np.ones([2, 1])
    with self.cached_session() as sess:
      grads_alpha_val, grads_beta_val = sess.run(
          [grads_alpha, grads_beta],
          {alpha: alpha_val, beta: beta_val, shape: [2, 1]})
    self.assertAllEqual(grads_alpha_val.shape, alpha_val.shape)
    self.assertAllEqual(grads_beta_val.shape, beta_val.shape)
Exemplo n.º 23
0
 def _sample_n(self, n, seed=None):
   # The sampling method comes from the fact that if:
   #   X ~ Normal(0, 1)
   #   Z ~ Chi2(df)
   #   Y = X / sqrt(Z / df)
   # then:
   #   Y ~ StudentT(df).
   shape = array_ops.concat_v2([[n], self.batch_shape()], 0)
   normal_sample = random_ops.random_normal(
       shape, dtype=self.dtype, seed=seed)
   df = self.df * array_ops.ones(self.batch_shape(), dtype=self.dtype)
   gamma_sample = random_ops.random_gamma(
       [n], 0.5 * df, beta=0.5, dtype=self.dtype,
       seed=distribution_util.gen_new_seed(seed, salt="student_t"))
   samples = normal_sample / math_ops.sqrt(gamma_sample / df)
   return samples * self.sigma + self.mu
Exemplo n.º 24
0
    def sample_n(self, n, seed=None, name="sample_n"):
        """Draws `n` samples from the Gamma distribution(s).

    See the doc for tf.random_gamma for further detail.

    Args:
      n: `Scalar` `Tensor` of type `int32` or `int64`, the number of
        observations to sample.
      seed: Python integer, the random seed for this operation.
      name: Optional name for the operation.

    Returns:
      samples: a `Tensor` of shape `(n,) + self.batch_shape + self.event_shape`
          with values of type `self.dtype`.
    """
        with ops.name_scope(self.name, values=[n, self.alpha, self._beta]):
            return random_ops.random_gamma([n], self.alpha, beta=self._beta, dtype=self.dtype, seed=seed, name=name)
 def _sample_n(self, n, seed=None):
   n_draws = math_ops.cast(self.total_count, dtype=dtypes.int32)
   k = self.event_shape_tensor()[0]
   unnormalized_logits = array_ops.reshape(
       math_ops.log(random_ops.random_gamma(
           shape=[n],
           alpha=self.concentration,
           dtype=self.dtype,
           seed=seed)),
       shape=[-1, k])
   draws = random_ops.multinomial(
       logits=unnormalized_logits,
       num_samples=n_draws,
       seed=distribution_util.gen_new_seed(seed, salt="dirichlet_multinomial"))
   x = math_ops.reduce_sum(array_ops.one_hot(draws, depth=k), -2)
   final_shape = array_ops.concat([[n], self.batch_shape_tensor(), [k]], 0)
   return array_ops.reshape(x, final_shape)
Exemplo n.º 26
0
  def testAverageAlphaGradient(self):
    """Statistical test for the gradient.

    Using the equation (5) of https://arxiv.org/abs/1805.08498, we have
      1 = d/dalpha E_{sample ~ Gamma(alpha, 1)} sample
        = E_{sample ~ Gamma(alpha, 1)} dsample/dalpha.
    Here we verify that the rhs is fairly close to one.
    The convergence speed is not great, so we use many samples and loose bounds.
    """
    num_samples = 1000
    alpha = constant_op.constant([0.8, 1e1, 1e3], dtype=dtypes.float32)
    sample = random_ops.random_gamma([num_samples], alpha)
    # We need to average the gradients, which is equivalent to averaging the
    # samples and then doing backprop.
    mean_sample = math_ops.reduce_mean(sample, axis=0)
    dsample_dalpha = gradients_impl.gradients(mean_sample, alpha)[0]
    dsample_dalpha_val = self.evaluate(dsample_dalpha)
    self.assertAllClose(dsample_dalpha_val, [1.0] * 3, atol=1e-1, rtol=1e-1)
Exemplo n.º 27
0
    def sample(self, n, seed=None, name="sample"):
        """Draws `n` samples from these InverseGamma distribution(s).

    See the doc for tf.random_gamma for further details on sampling strategy.

    Args:
      n: Python integer, the number of observations to sample from each
        distribution.
      seed: Python integer, the random seed for this operation.
      name: Optional name for the operation.

    Returns:
      samples: a `Tensor` of shape `(n,) + self.batch_shape + self.event_shape`
          with values of type `self.dtype`.
    """
        with ops.name_scope(self.name):
            with ops.op_scope([n, self._alpha, self._beta], name):
                one = constant_op.constant(1.0, dtype=self.dtype)
                return one / random_ops.random_gamma([n], self._alpha, beta=self._beta, dtype=self.dtype, seed=seed)
Exemplo n.º 28
0
    def sample_n(self, n, seed=None, name="sample_n"):
        """Sample `n` observations from the distributions.

    Args:
      n: `Scalar`, type int32, the number of observations to sample.
      seed: Python integer, the random seed.
      name: The name to give this op.

    Returns:
      samples: `[n, ...]`, a `Tensor` of `n` samples for each
        of the distributions determined by broadcasting the hyperparameters.
    """
        with ops.name_scope(self.name):
            with ops.op_scope([self.alpha, n], name):
                gamma_sample = random_ops.random_gamma([n], self.alpha, dtype=self.dtype, seed=seed)
                n_val = tensor_util.constant_value(n)
                final_shape = tensor_shape.vector(n_val).concatenate(self.alpha.get_shape())

                gamma_sample.set_shape(final_shape)
                return gamma_sample / math_ops.reduce_sum(gamma_sample, reduction_indices=[-1], keep_dims=True)
Exemplo n.º 29
0
  def _testCompareToImplicitDerivative(self, dtype):
    """Compare to the implicit reparameterization derivative.

    Let's derive the formula we compare to.

    Start from the fact that CDF maps a random variable to the Uniform
    random variable:
      igamma(alpha, sample) = u, where u ~ Uniform(0, 1).

    Apply d / dalpha to both sides:
      d igamma(alpha, sample) / dalpha
          + d igamma(alpha, sample) / dsample * dsample/dalpha  = 0
      d igamma(alpha, sample) / dalpha
          + d igamma(alpha, sample) / dsample * dsample / dalpha = 0
      dsample/dalpha = - (d igamma(alpha, sample) / dalpha)
                        / d igamma(alpha, sample) / dsample

    This is the equation (8) of https://arxiv.org/abs/1805.08498

    Args:
      dtype: TensorFlow dtype to perform the computations in.
    """
    np_dtype = dtype.as_numpy_dtype
    alpha = constant_op.constant(np.logspace(-2, 3, dtype=np_dtype))
    sample = random_ops.random_gamma(
        [], alpha, np_dtype(1.0), dtype=dtype, seed=12345)
    actual = gradients_impl.gradients(sample, alpha)[0]

    sample_sg = array_ops.stop_gradient(sample)
    cdf = math_ops.igamma(alpha, sample_sg)
    dcdf_dalpha, dcdf_dsample = gradients_impl.gradients(
        cdf, [alpha, sample_sg])
    # Numerically unstable due to division, do not try at home.
    expected = -dcdf_dalpha / dcdf_dsample

    (actual_val, expected_val) = self.evaluate((actual, expected))

    self.assertAllClose(actual_val, expected_val, rtol=1e-3, atol=1e-3)
 def _sample_n(self, n, seed=None):
     """See the documentation for tf.random_gamma for more details."""
     return 1. / random_ops.random_gamma(
         [n], self.alpha, beta=self.beta, dtype=self.dtype, seed=seed)
 def loop_fn(_):
     return random_ops.random_gamma([3], alpha=[0.5])
Exemplo n.º 32
0
 def _sample_n(self, n, seed=None):
     return 1. / random_ops.random_gamma(
         [n], self.alpha, beta=self.beta, dtype=self.dtype, seed=seed)
Exemplo n.º 33
0
def random_gamma(shape):  # pylint: disable=invalid-name
    return random_ops.random_gamma(shape, 1.0)
Exemplo n.º 34
0
 def computation():
     return random_ops.random_gamma([10], [0.5, 1.5])
Exemplo n.º 35
0
 def _sample_n(self, n, seed=None):
   return random_ops.random_gamma([n],
                                  self.alpha,
                                  beta=self.beta,
                                  dtype=self.dtype,
                                  seed=seed)
Exemplo n.º 36
0
 def _sample_n(self, n, seed=None):
     return 1. / random_ops.random_gamma(shape=[n],
                                         alpha=self.concentration,
                                         beta=self.rate,
                                         dtype=self.dtype,
                                         seed=seed)
Exemplo n.º 37
0
 def testNpDtypes(self):
     self.evaluate(
         random_ops.random_gamma([5],
                                 alpha=np.ones([2, 1, 3]),
                                 beta=np.ones([3]),
                                 dtype=np.float32))
Exemplo n.º 38
0
 def testEmptySamplingNoError(self):
   self.evaluate(random_ops.random_gamma(
       [5], alpha=np.ones([2, 0, 3]), beta=np.ones([3]), dtype=dtypes.float32))
Exemplo n.º 39
0
 def computation():
     samples = random_ops.random_gamma([10], [0.5, 1.5])
     return samples
Exemplo n.º 40
0
 def _sample_n(self, n, seed=None):
   gamma_sample = random_ops.random_gamma(
       [n,], self.alpha, dtype=self.dtype, seed=seed)
   return gamma_sample / math_ops.reduce_sum(
       gamma_sample, reduction_indices=[-1], keep_dims=True)
Exemplo n.º 41
0
    def sample_n(self, n, seed=None, name='sample'):
        # pylint: disable=line-too-long
        """Generate `n` samples.

    Complexity: O(nbk^3)

    The sampling procedure is based on the [Bartlett decomposition](
    https://en.wikipedia.org/wiki/Wishart_distribution#Bartlett_decomposition)
    and [using a Gamma distribution to generate Chi2 random variates](
    https://en.wikipedia.org/wiki/Chi-squared_distribution#Gamma.2C_exponential.2C_and_related_distributions).

    Args:
      n: Scalar. Number of samples to draw from each distribution.
      seed: Python integer; random number generator seed.
      name: The name of this op.

    Returns:
      samples: a `Tensor` of shape `(n,) + self.batch_shape + self.event_shape`
          with values of type `self.dtype`.
    """
        with ops.name_scope(self.name):
            with ops.name_scope(name, values=[n] + list(self.inputs.values())):
                n = ops.convert_to_tensor(n, name='n')
                if n.dtype != dtypes.int32:
                    raise TypeError('n.dtype=%s which is not int32' % n.dtype)
                batch_shape = self.batch_shape()
                event_shape = self.event_shape()
                batch_ndims = array_ops.shape(batch_shape)[0]

                ndims = batch_ndims + 3  # sample_ndims=1, event_ndims=2
                shape = array_ops.concat(0, ((n, ), batch_shape, event_shape))

                # Complexity: O(nbk^2)
                x = random_ops.random_normal(shape=shape,
                                             mean=0.,
                                             stddev=1.,
                                             dtype=self.dtype,
                                             seed=seed)

                # Complexity: O(nbk)
                # This parametrization is equivalent to Chi2, i.e.,
                # ChiSquared(k) == Gamma(alpha=k/2, beta=1/2)
                g = random_ops.random_gamma(shape=(n, ),
                                            alpha=self._multi_gamma_sequence(
                                                0.5 * self.df, self.dimension),
                                            beta=0.5,
                                            dtype=self.dtype,
                                            seed=seed)

                # Complexity: O(nbk^2)
                x = array_ops.batch_matrix_band_part(x, -1, 0)  # Tri-lower.

                # Complexity: O(nbk)
                x = array_ops.batch_matrix_set_diag(x, math_ops.sqrt(g))

                # Make batch-op ready.
                # Complexity: O(nbk^2)
                perm = array_ops.concat(0, (math_ops.range(1, ndims), (0, )))
                x = array_ops.transpose(x, perm)
                shape = array_ops.concat(0,
                                         (batch_shape, (event_shape[0], -1)))
                x = array_ops.reshape(x, shape)

                # Complexity: O(nbM) where M is the complexity of the operator solving a
                # vector system.  E.g., for OperatorPDDiag, each matmul is O(k^2), so
                # this complexity is O(nbk^2). For OperatorPDCholesky, each matmul is
                # O(k^3) so this step has complexity O(nbk^3).
                x = self.scale_operator_pd.sqrt_matmul(x)

                # Undo make batch-op ready.
                # Complexity: O(nbk^2)
                shape = array_ops.concat(0, (batch_shape, event_shape, (n, )))
                x = array_ops.reshape(x, shape)
                perm = array_ops.concat(
                    0, ((ndims - 1, ), math_ops.range(0, ndims - 1)))
                x = array_ops.transpose(x, perm)

                if not self.cholesky_input_output_matrices:
                    # Complexity: O(nbk^3)
                    x = math_ops.batch_matmul(x, x, adj_y=True)

                # Set shape hints.
                if self.scale_operator_pd.get_shape().ndims is not None:
                    x.set_shape(
                        tensor_shape.TensorShape(
                            [tensor_util.constant_value(n)] +
                            self.scale_operator_pd.get_shape().as_list()))
                elif x.get_shape().ndims is not None:
                    x.get_shape()[0].merge_with(
                        tensor_shape.TensorDimension(
                            tensor_util.constant_value(n)))

                return x
Exemplo n.º 42
0
def random_gamma_with_alpha_beta(shape):  # pylint: disable=invalid-name
    return random_ops.random_gamma(shape,
                                   alpha=[[1.], [3.], [5.], [6.]],
                                   beta=[[3., 4.]])