code: def brier_decomposition(labels, logits, name=None):
      r"""Decompose the Brier score into uncertainty, resolution, and reliability.
  
      [Proper scoring rules][1] measure the quality of probabilistic predictions;
      any proper scoring rule admits a [unique decomposition][2] as
      `Score = Uncertainty - Resolution + Reliability`, where:
  
      * `Uncertainty`, is a generalized entropy of the average predictive
        distribution; it can both be positive or negative.
      * `Resolution`, is a generalized variance of individual predictive
        distributions; it is always non-negative.  Difference in predictions reveal
        information, that is why a larger resolution improves the predictive score.
      * `Reliability`, a measure of calibration of predictions against the true
        frequency of events.  It is always non-negative and a lower value here
        indicates better calibration.
  
      This method estimates the above decomposition for the case of the Brier
      scoring rule for discrete outcomes.  For this, we need to discretize the space
      of probability distributions; we choose a simple partition of the space into
      `nlabels` events: given a distribution `p` over `nlabels` outcomes, the index
      `k` for which `p_k > p_i` for all `i != k` determines the discretization
      outcome; that is, `p in M_k`, where `M_k` is the set of all distributions for
      which `p_k` is the largest value among all probabilities.
  
      The estimation error of each component is O(k/n), where n is the number
      of instances and k is the number of labels.  There may be an error of this
      order when compared to `brier_score`.
  
      #### References
      [1]: Tilmann Gneiting, Adrian E. Raftery.
           Strictly Proper Scoring Rules, Prediction, and Estimation.
           Journal of the American Statistical Association, Vol. 102, 2007.
           https://www.stat.washington.edu/raftery/Research/PDF/Gneiting2007jasa.pdf
      [2]: Jochen Broecker.  Reliability, sufficiency, and the decomposition of
           proper scores.
           Quarterly Journal of the Royal Meteorological Society, Vol. 135, 2009.
           https://rmets.onlinelibrary.wiley.com/doi/epdf/10.1002/qj.456
  
      Args:
        labels: Tensor, (n,), with tf.int32 or tf.int64 elements containing ground
          truth class labels in the range [0,nlabels-1].
        logits: Tensor, (n, nlabels), with logits for n instances and nlabels.
        name: Python `str` name prefixed to Ops created by this function.
  
      Returns:
        uncertainty: Tensor, scalar, the uncertainty component of the
          decomposition.
        resolution: Tensor, scalar, the resolution component of the decomposition.
        reliability: Tensor, scalar, the reliability component of the
          decomposition.
      """
      with tf.name_scope(name or "brier_decomposition"):
          labels = tf.convert_to_tensor(labels)
          logits = tf.convert_to_tensor(logits)
          num_classes = logits.shape[-1]
  
          # Compute pbar, the average distribution
          pred_class = tf.argmax(
              logits, axis=-1, output_type=labels.dtype
          )
  
          if tensorshape_util.rank(logits.shape) > 2:
              shape_as_list = tensorshape_util.as_list(logits.shape)
              flatten, unflatten = _make_flatten_unflatten_fns(
                  shape_as_list[:-2]
              )
  
              def fn_to_map(args):
                  yhat, y = args
                  return tf.math.confusion_matrix(
                      yhat,
                      y,
                      num_classes=num_classes,
                      dtype=logits.dtype,
                  )
  
              confusion_matrix = tf.map_fn(
                  fn_to_map,
                  [flatten(pred_class), flatten(labels)],
                  fn_output_signature=logits.dtype,
              )
              confusion_matrix = unflatten(confusion_matrix)
          else:
              confusion_matrix = tf.math.confusion_matrix(
                  pred_class,
                  labels,
                  num_classes=num_classes,
                  dtype=logits.dtype,
              )
  
          dist_weights = tf.reduce_sum(confusion_matrix, axis=-1)
          dist_weights /= tf.reduce_sum(
              dist_weights, axis=-1, keepdims=True
          )
          pbar = tf.reduce_sum(confusion_matrix, axis=-2)
          pbar /= tf.reduce_sum(pbar, axis=-1, keepdims=True)
  
          eps = np.finfo(
              dtype_util.as_numpy_dtype(confusion_matrix.dtype)
          ).eps
          # dist_mean[k,:] contains the empirical distribution for the set M_k
          # Some outcomes may not realize, corresponding to dist_weights[k] = 0
          dist_mean = confusion_matrix / (
              eps
              + tf.reduce_sum(confusion_matrix, axis=-1, keepdims=True)
          )
  
          # Uncertainty: quadratic entropy of the average label distribution
          uncertainty = -tf.reduce_sum(tf.square(pbar), axis=-1)
  
          # Resolution: expected quadratic divergence of predictive to mean
          resolution = tf.square(tf.expand_dims(pbar, -1) - dist_mean)
          resolution = tf.reduce_sum(
              dist_weights * tf.reduce_sum(resolution, axis=-1), axis=-1
          )
  
          # Reliability: expected quadratic divergence of predictive to true
          if tensorshape_util.rank(logits.shape) > 2:
              # TODO(b/139094519): Avoid using tf.map_fn here.
              prob_true = tf.map_fn(
                  lambda args: tf.gather(args[0], args[1]),
                  [flatten(dist_mean), flatten(pred_class)],
                  fn_output_signature=dist_mean.dtype,
              )
              prob_true = unflatten(prob_true)
          else:
              prob_true = tf.gather(dist_mean, pred_class, axis=0)
          log_prob_true = tf.math.log(prob_true)
  
          log_prob_pred = logits - tf.math.reduce_logsumexp(
              logits, axis=-1, keepdims=True
          )
  
          log_reliability = _reduce_log_l2_exp(
              log_prob_pred, log_prob_true, axis=-1
          )
          log_reliability = tf.math.reduce_logsumexp(
              log_reliability,
              axis=-1,
          )
  
          num_samples = tf.cast(tf.shape(logits)[-2], logits.dtype)
          reliability = tf.exp(
              log_reliability - tf.math.log(num_samples)
          )
  
          return uncertainty, resolution, reliability
  
file_path: probability/tensorflow_probability/python/stats/calibration.py
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.math import generic
  from tensorflow_probability.python.stats import quantiles
label_desc: Use image node_id 1 for calling a global function with example usage: brier_decomposition(labels, logits, name) and returns: uncertainty,  resolution,  reliability, tf