class_docstr: The finite discrete distribution.
  
  The FiniteDiscrete distribution is parameterized by either probabilities or
  log-probabilities of a set of `K` possible outcomes, which is defined by
  a strictly ascending list of `K` values.
  
  Note: log_prob, prob, cdf, mode, and entropy are differentiable with respect
  to `logits` or `probs` but not with respect to `outcomes`.
  
  #### Mathematical Details
  
  The probability mass function (pmf) is,
  
  ```none
  pmf(x; pi, qi) = prod_j pi_j**[x == qi_j]
  ```
  
  #### Examples
  
  ```python
  
  # Initialize a discrete distribution with 4 possible outcomes and the 2nd
  # outcome being most likely.
  dist = FiniteDiscrete([1., 2., 4., 8.], probs=[0.1, 0.4, 0.3, 0.2])
  dist.prob(2.)
  # ==> 0.4
  
  # Using logits to initialize a discrete distribution with 4 possible outcomes
  # and the 2nd outcome being most likely.
  dist = FiniteDiscrete([1., 2., 4., 8.], logits=np.log([0.1, 0.4, 0.3, 0.2]))
  dist.prob(2.)
  # ==> 0.4
  ```
code: def _parameter_properties(cls, dtype, num_classes=None):
      # pylint: disable=g-long-lambda
      return dict(
          outcomes=parameter_properties.ParameterProperties(
              event_ndims=None,
              shape_fn=lambda sample_shape: [num_classes],
              default_constraining_bijector_fn=ascending.Ascending(),
          ),
          logits=parameter_properties.ParameterProperties(
              event_ndims=1,
              shape_fn=lambda sample_shape: ps.concat(
                  [sample_shape, [num_classes]], axis=0
              ),
          ),
          probs=parameter_properties.ParameterProperties(
              event_ndims=1,
              shape_fn=lambda sample_shape: ps.concat(
                  [sample_shape, [num_classes]], axis=0
              ),
              default_constraining_bijector_fn=softmax_centered_bijector.SoftmaxCentered,
              is_preferred=False,
          ),
          rtol=parameter_properties.ParameterProperties(
              event_ndims=None,  # TODO(b/187469130): standardize batch semantics.
              default_constraining_bijector_fn=(
                  lambda: softplus_bijector.Softplus(
                      low=dtype_util.eps(dtype)
                  )
              ),
              is_preferred=False,
          ),
          atol=parameter_properties.ParameterProperties(
              event_ndims=None,  # TODO(b/187469130): standardize batch semantics.
              default_constraining_bijector_fn=(
                  lambda: softplus_bijector.Softplus(
                      low=dtype_util.eps(dtype)
                  )
              ),
              is_preferred=False,
          ),
      )
  
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import ascending
  from tensorflow_probability.python.bijectors import softmax_centered
  from tensorflow_probability.python.bijectors import softplus
  from tensorflow_probability.python.distributions import categorical
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import reparameterization
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.internal import tensorshape_util
label_desc: Use image node_id 2 for calling the FiniteDiscrete obj's underlying member method code with example usage: obj._parameter_properties(cls, dtype, num_classes) and returns: dict