code: def kl_divergence(
      labels,
      predictions,
      axis=None,
      weights=1.0,
      scope=None,
      loss_collection=tf.compat.v1.GraphKeys.LOSSES,
      reduction=tf.compat.v1.losses.Reduction.SUM_BY_NONZERO_WEIGHTS,
  ):
      """Adds a KL-divergence to the training procedure.
  
      For brevity, let `P = labels` and `Q = predictions`. The
      Kullback-Leibler divergence `KL(P||Q)` is:
  
      ```
      KL(P||Q) = P * log(P) - P * log(Q)
      ```
  
      Note: the function assumes that `predictions` and `labels` are the values of
      a multinomial distribution, i.e., each value is the probability of the
      corresponding class.
  
      For the usage of `weights` and `reduction`, please refer to `tf.losses`.
  
      Args:
        labels: `Tensor` of type `float32` or `float64`, with shape `[d1, ..., dN,
          num_classes]`, represents the target distribution.
        predictions: `Tensor` of the same type and shape as `labels`, represents
          the predicted distribution.
        axis: The dimension along which the KL divergence is computed. The values
          of `labels` and `predictions` along `axis` should meet the requirements
          of a multinomial distribution.
        weights: (optional) `Tensor` whose rank is either 0, or the same as that of
          `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
          be either `1`, or the same as the corresponding `losses` dimension).
        scope: The scope for the operations performed in computing the loss.
        loss_collection: Collection to which the loss will be added.
        reduction: Type of reduction to apply to the loss.
  
      Returns:
        Weighted loss `float` `Tensor`. If `reduction` is `NONE`, this has the same
        shape as `labels`, otherwise, it is a scalar.
      Raises:
        InvalidArgumentError: If `labels` or `predictions` don't meet the
          requirements of a multinomial distribution.
        ValueError: If `axis` is `None`, if the shape of `predictions` doesn't
          match that of `labels`, or if the shape of `weights` is invalid.
      """
      with tf.compat.v1.name_scope(
          scope, "kl_divergence", (predictions, labels, weights)
      ) as scope:
          labels = tf.cast(labels, tf.dtypes.float32)
          predictions = tf.cast(predictions, tf.dtypes.float32)
          predictions.get_shape().assert_is_compatible_with(
              labels.get_shape()
          )
          if axis is None:
              raise ValueError('You must specify "axis".')
          _assert_valid_axis(labels.get_shape().ndims, axis)
          assert_list = _assert_multinomial_distribution(
              labels, axis
          ) + _assert_multinomial_distribution(predictions, axis)
          with tf.control_dependencies(assert_list):
              divergence_tensor = _kl_divergence_fn(labels, predictions)
              divergence = tf.reduce_sum(
                  input_tensor=divergence_tensor,
                  axis=(axis,),
                  keepdims=True,
              )
              return tf.compat.v1.losses.compute_weighted_loss(
                  divergence,
                  weights,
                  scope,
                  loss_collection,
                  reduction=reduction,
              )
  
file_path: neural-structured-learning/neural_structured_learning/lib/distances.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import neural_structured_learning.configs
  import tensorflow
label_desc: Use image node_id 4 for calling a global function with example usage: kl_divergence(labels, predictions, axis, weights, scope, loss_collection, reduction) and returns: tf