code: def _kl_independent(a, b, name="kl_independent"):
      """Batched KL divergence `KL(a || b)` for Independent distributions.
  
      We can leverage the fact that
      ```
      KL(Independent(a) || Independent(b)) = sum(KL(a || b))
      ```
      where the sum is over the `reinterpreted_batch_ndims`.
  
      Args:
        a: Instance of `Independent`.
        b: Instance of `Independent`.
        name: (optional) name to use for created ops. Default 'kl_independent'.
  
      Returns:
        Batchwise `KL(a || b)`.
  
      Raises:
        ValueError: If the event space for `a` and `b`, or their underlying
          distributions don't match.
      """
      p = a.distribution
      q = b.distribution
  
      # The KL between any two (non)-batched distributions is a scalar.
      # Given that the KL between two factored distributions is the sum, i.e.
      # KL(p1(x)p2(y) || q1(x)q2(y)) = KL(p1 || q1) + KL(q1 || q2), we compute
      # KL(p || q) and do a `reduce_sum` on the reinterpreted batch dimensions.
      if tensorshape_util.is_fully_defined(
          a.event_shape
      ) and tensorshape_util.is_fully_defined(b.event_shape):
          if a.event_shape == b.event_shape:
              if p.event_shape == q.event_shape:
                  num_reduce_dims = tensorshape_util.rank(
                      a.event_shape
                  ) - tensorshape_util.rank(p.event_shape)
                  reduce_dims = [
                      -i - 1 for i in range(0, num_reduce_dims)
                  ]
  
                  return tf.reduce_sum(
                      kullback_leibler.kl_divergence(p, q, name=name),
                      axis=reduce_dims,
                  )
              else:
                  raise NotImplementedError(
                      "KL between Independents with different "
                      "event shapes not supported."
                  )
          else:
              raise ValueError("Event shapes do not match.")
      else:
          p_event_shape_tensor = p.event_shape_tensor()
          q_event_shape_tensor = q.event_shape_tensor()
          # NOTE: We could optimize by passing the event_shape_tensor of p and q
          # to a.event_shape_tensor() and b.event_shape_tensor().
          a_event_shape_tensor = a.event_shape_tensor()
          b_event_shape_tensor = b.event_shape_tensor()
          with tf.control_dependencies(
              [
                  assert_util.assert_equal(
                      a_event_shape_tensor,
                      b_event_shape_tensor,
                      message="Event shapes do not match.",
                  ),
                  assert_util.assert_equal(
                      p_event_shape_tensor,
                      q_event_shape_tensor,
                      message="Event shapes do not match.",
                  ),
              ]
          ):
              num_reduce_dims = ps.rank_from_shape(
                  a_event_shape_tensor, a.event_shape
              ) - ps.rank_from_shape(
                  p_event_shape_tensor, p.event_shape
              )
              reduce_dims = ps.range(-num_reduce_dims, 0, 1)
              return tf.reduce_sum(
                  kullback_leibler.kl_divergence(p, q, name=name),
                  axis=reduce_dims,
              )
  
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 for calling a global function with example usage: _kl_independent(a, b, name) and returns: tf, tf