class_docstr: Independent distribution from batch of distributions.
  
  This distribution is useful for regarding a collection of independent,
  non-identical distributions as a single random variable. For example, the
  `Independent` distribution composed of a collection of `Bernoulli`
  distributions might define a distribution over an image (where each
  `Bernoulli` is a distribution over each pixel).
  
  More precisely, a collection of `B` (independent) `E`-variate random variables
  (rv) `{X_1, ..., X_B}`, can be regarded as a `[B, E]`-variate random variable
  `(X_1, ..., X_B)` with probability
  `p(x_1, ..., x_B) = p_1(x_1) * ... * p_B(x_B)` where `p_b(X_b)` is the
  probability of the `b`-th rv. More generally `B, E` can be arbitrary shapes.
  
  Similarly, the `Independent` distribution specifies a distribution over `[B,
  E]`-shaped events. It operates by reinterpreting the rightmost batch dims as
  part of the event dimensions. The `reinterpreted_batch_ndims` parameter
  controls the number of batch dims which are absorbed as event dims;
  `reinterpreted_batch_ndims <= len(batch_shape)`.  For example, the `log_prob`
  function entails a `reduce_sum` over the rightmost `reinterpreted_batch_ndims`
  after calling the base distribution's `log_prob`.  In other words, since the
  batch dimension(s) index independent distributions, the resultant multivariate
  will have independent components.
  
  #### Mathematical Details
  
  The probability function is,
  
  ```none
  prob(x; reinterpreted_batch_ndims) = tf.reduce_prod(
      dist.prob(x),
      axis=-1-range(reinterpreted_batch_ndims))
  ```
  
  #### Examples
  
  ```python
  tfd = tfp.distributions
  
  # Make independent distribution from a 2-batch Normal.
  ind = tfd.Independent(
      distribution=tfd.Normal(loc=[-1., 1], scale=[0.1, 0.5]),
      reinterpreted_batch_ndims=1)
  
  # All batch dims have been 'absorbed' into event dims.
  ind.batch_shape  # ==> []
  ind.event_shape  # ==> [2]
  
  # Make independent distribution from a 2-batch bivariate Normal.
  ind = tfd.Independent(
      distribution=tfd.MultivariateNormalDiag(
          loc=[[-1., 1], [1, -1]],
          scale_diag=tf.tile([[1.], [0.5]], [1, 2]),
      reinterpreted_batch_ndims=1)
  
  # All batch dims have been 'absorbed' into event dims.
  ind.batch_shape  # ==> []
  ind.event_shape  # ==> [2, 2]
  ```
class_docstr_tok: ["Independent","distribution","from","batch","of","distributions",".","This","distribution","is","useful","for","regarding","a","collection","of","independent",",","non-identical","distributions","as","a","single","random","variable",".","For","example",",","the","`","Independent","`","distribution","composed","of","a","collection","of","`","Bernoulli","`","distributions","might","define","a","distribution","over","an","image","(","where","each","`","Bernoulli","`","is","a","distribution","over","each","pixel",")",".","More","precisely",",","a","collection","of","`","B","`","(","independent",")","`","E","`","-variate","random","variables","(","rv",")","`","{","X_1",",","...",",","X_B","}","`",",","can","be","regarded","as","a","`","[","B",",","E","]","`","-variate","random","variable","`","(","X_1",",","...",",","X_B",")","`","with","probability","`","p","(","x_1",",","...",",","x_B",")","=","p_1","(","x_1",")","*","...","*","p_B","(","x_B",")","`","where","`","p_b","(","X_b",")","`","is","the","probability","of","the","`","b","`","-th","rv",".","More","generally","`","B",",","E","`","can","be","arbitrary","shapes",".","Similarly",",","the","`","Independent","`","distribution","specifies","a","distribution","over","`","[","B",",","E","]","`","-shaped","events",".","It","operates","by","reinterpreting","the","rightmost","batch","dims","as","part","of","the","event","dimensions",".","The","`","reinterpreted_batch_ndims","`","parameter","controls","the","number","of","batch","dims","which","are","absorbed","as","event","dims",";","`","reinterpreted_batch_ndims","<","=","len","(","batch_shape",")","`",".","For","example",",","the","`","log_prob","`","function","entails","a","`","reduce_sum","`","over","the","rightmost","`","reinterpreted_batch_ndims","`","after","calling","the","base","distribution","'s","`","log_prob","`",".","In","other","words",",","since","the","batch","dimension","(","s",")","index","independent","distributions",",","the","resultant","multivariate","will","have","independent","components",".","#","#","#","#","Mathematical","Details","The","probability","function","is",",","``","`","none","prob","(","x",";","reinterpreted_batch_ndims",")","=","tf.reduce_prod","(","dist.prob","(","x",")",",","axis=-1-range","(","reinterpreted_batch_ndims",")",")","``","`","#","#","#","#","Examples","``","`","python","tfd","=","tfp.distributions","#","Make","independent","distribution","from","a","2-batch","Normal",".","ind","=","tfd.Independent","(","distribution=tfd.Normal","(","loc=","[","-1.",",","1","]",",","scale=","[","0.1",",","0.5","]",")",",","reinterpreted_batch_ndims=1",")","#","All","batch","dims","have","been","'absorbed","'","into","event","dims",".","ind.batch_shape","#","==",">","[","]","ind.event_shape","#","==",">","[","2","]","#","Make","independent","distribution","from","a","2-batch","bivariate","Normal",".","ind","=","tfd.Independent","(","distribution=tfd.MultivariateNormalDiag","(","loc=","[","[","-1.",",","1","]",",","[","1",",","-1","]","]",",","scale_diag=tf.tile","(","[","[","1",".","]",",","[","0.5","]","]",",","[","1",",","2","]",")",",","reinterpreted_batch_ndims=1",")","#","All","batch","dims","have","been","'absorbed","'","into","event","dims",".","ind.batch_shape","#","==",">","[","]","ind.event_shape","#","==",">","[","2",",","2","]","``","`"]
docstr: Construct an `Independent` distribution.
  
  Args:
    distribution: The base distribution instance to transform. Typically an
      instance of `Distribution`.
    reinterpreted_batch_ndims: Scalar, integer number of rightmost batch dims
      which will be regarded as event dims. When `None` all but the first
      batch axis (batch axis 0) will be transferred to event dimensions
      (analogous to `tf.layers.flatten`).
    validate_args: Python `bool`.  Whether to validate input with asserts.
      If `validate_args` is `False`, and the inputs are invalid,
      correct behavior is not guaranteed.
    experimental_use_kahan_sum: Python `bool`. When `True`, we use Kahan
      summation to aggregate independent underlying log_prob values, which
      improves against the precision of a naive float32 sum. This can be
      noticeable in particular for large dimensions in float32. See CPU caveat
      on `tfp.math.reduce_kahan_sum`.
    name: The name for ops managed by the distribution.
      Default value: `Independent + distribution.name`.
  
  Raises:
    ValueError: if `reinterpreted_batch_ndims` exceeds
      `distribution.batch_ndims`
docstr_tok: ["Construct","an","`","Independent","`","distribution",".","Args",":","distribution",":","The","base","distribution","instance","to","transform",".","Typically","an","instance","of","`","Distribution","`",".","reinterpreted_batch_ndims",":","Scalar",",","integer","number","of","rightmost","batch","dims","which","will","be","regarded","as","event","dims",".","When","`","None","`","all","but","the","first","batch","axis","(","batch","axis","0",")","will","be","transferred","to","event","dimensions","(","analogous","to","`","tf.layers.flatten","`",")",".","validate_args",":","Python","`","bool","`",".","Whether","to","validate","input","with","asserts",".","If","`","validate_args","`","is","`","False","`",",","and","the","inputs","are","invalid",",","correct","behavior","is","not","guaranteed",".","experimental_use_kahan_sum",":","Python","`","bool","`",".","When","`","True","`",",","we","use","Kahan","summation","to","aggregate","independent","underlying","log_prob","values",",","which","improves","against","the","precision","of","a","naive","float32","sum",".","This","can","be","noticeable","in","particular","for","large","dimensions","in","float32",".","See","CPU","caveat","on","`","tfp.math.reduce_kahan_sum","`",".","name",":","The","name","for","ops","managed","by","the","distribution",".","Default","value",":","`","Independent","+","distribution.name","`",".","Raises",":","ValueError",":","if","`","reinterpreted_batch_ndims","`","exceeds","`","distribution.batch_ndims","`"]
code: def __init__(
      self,
      distribution,
      reinterpreted_batch_ndims=None,
      validate_args=False,
      experimental_use_kahan_sum=False,
      name=None,
  ):
      """Construct an `Independent` distribution.
  
      Args:
        distribution: The base distribution instance to transform. Typically an
          instance of `Distribution`.
        reinterpreted_batch_ndims: Scalar, integer number of rightmost batch dims
          which will be regarded as event dims. When `None` all but the first
          batch axis (batch axis 0) will be transferred to event dimensions
          (analogous to `tf.layers.flatten`).
        validate_args: Python `bool`.  Whether to validate input with asserts.
          If `validate_args` is `False`, and the inputs are invalid,
          correct behavior is not guaranteed.
        experimental_use_kahan_sum: Python `bool`. When `True`, we use Kahan
          summation to aggregate independent underlying log_prob values, which
          improves against the precision of a naive float32 sum. This can be
          noticeable in particular for large dimensions in float32. See CPU caveat
          on `tfp.math.reduce_kahan_sum`.
        name: The name for ops managed by the distribution.
          Default value: `Independent + distribution.name`.
  
      Raises:
        ValueError: if `reinterpreted_batch_ndims` exceeds
          `distribution.batch_ndims`
      """
      parameters = dict(locals())
      self._experimental_use_kahan_sum = experimental_use_kahan_sum
      with tf.name_scope(
          name or ("Independent" + distribution.name)
      ) as name:
          self._distribution = distribution
  
          if reinterpreted_batch_ndims is None:
              # If possible, statically infer reinterpreted_batch_ndims.
              batch_ndims = tensorshape_util.rank(
                  distribution.batch_shape
              )
              if batch_ndims is not None:
                  self._static_reinterpreted_batch_ndims = max(
                      0, batch_ndims - 1
                  )
                  self._reinterpreted_batch_ndims = (
                      ps.convert_to_shape_tensor(
                          self._static_reinterpreted_batch_ndims,
                          dtype_hint=tf.int32,
                          name="reinterpreted_batch_ndims",
                      )
                  )
              else:
                  self._reinterpreted_batch_ndims = None
                  self._static_reinterpreted_batch_ndims = None
  
          else:
              self._reinterpreted_batch_ndims = (
                  tensor_util.convert_nonref_to_tensor(
                      reinterpreted_batch_ndims,
                      dtype_hint=tf.int32,
                      as_shape_tensor=True,
                      name="reinterpreted_batch_ndims",
                  )
              )
              static_val = tf.get_static_value(
                  self._reinterpreted_batch_ndims
              )
              self._static_reinterpreted_batch_ndims = (
                  None if static_val is None else int(static_val)
              )
  
          super(_Independent, self).__init__(
              dtype=self._distribution.dtype,
              reparameterization_type=self._distribution.reparameterization_type,
              validate_args=validate_args,
              allow_nan_stats=self._distribution.allow_nan_stats,
              parameters=parameters,
              name=name,
          )
  
imports: import collections
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import kullback_leibler
  from tensorflow_probability.python.distributions import log_prob_ratio
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import auto_composite_tensor
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.math import generic
  from tensorflow.python.util import deprecation
label_desc: Use image node_id 1 to create a new _Independent object from inherited base classes: distribution_lib with example: obj = _Independent(distribution, reinterpreted_batch_ndims, validate_args, experimental_use_kahan_sum, name)