code: def log_loss(
      labels: np.ndarray,
      pred: np.ndarray,
      sample_weight: Optional[np.ndarray] = None,
      from_logits=False,
      small_value=1e-8,
  ) -> np.ndarray:
      """Computes the per-example cross entropy loss.
  
      Args:
        labels: numpy array of shape (num_samples,). labels[i] is the true label
          (scalar) of the i-th sample and is one of {0, 1, ..., num_classes-1}.
        pred: numpy array of shape (num_samples, num_classes) or (num_samples,). For
          categorical cross entropy loss, the shape should be (num_samples,
          num_classes) and pred[i] is the logits or probability vector of the i-th
          sample. For binary logistic loss, the shape should be (num_samples,) and
          pred[i] is the probability of the positive class.
        sample_weight: a vector of weights of shape (num_samples, ) that are
          assigned to individual samples. If not provided, then each sample is
          given unit weight. Only the LogisticRegressionAttacker and the
          RandomForestAttacker support sample weights.
        from_logits: whether `pred` is logits or probability vector.
        small_value: a scalar. np.log can become -inf if the probability is too
          close to 0, so the probability is clipped below by small_value.
  
      Returns:
        the cross-entropy loss of each sample
      """
      if labels.shape[0] != pred.shape[0]:
          raise ValueError(
              "labels and pred should have the same number of examples,",
              f"but got {labels.shape[0]} and {pred.shape[0]}.",
          )
      classes = np.unique(labels)
      if sample_weight is None:
          # If sample weights are not provided, set them to 1.0.
          sample_weight = 1.0
      else:
          if np.shape(sample_weight)[0] != np.shape(labels)[0]:
              # Number of elements should be the same.
              raise ValueError(
                  "Expected sample weights to have the same length as the labels, "
                  f"received {np.shape(sample_weight)[0]} and {np.shape(labels)[0]}."
              )
  
      # Binary logistic loss
      if pred.size == pred.shape[0]:
          pred = pred.flatten()
          if classes.min() < 0 or classes.max() > 1:
              raise ValueError(
                  "Each value in pred is a scalar, so labels are expected",
                  f"to be {0, 1}. But got {classes}.",
              )
          if from_logits:
              pred = special.expit(pred)
  
          indices_class0 = labels == 0
          prob_correct = np.copy(pred)
          prob_correct[indices_class0] = (
              1 - prob_correct[indices_class0]
          )
          return (
              -np.log(np.maximum(prob_correct, small_value))
              * sample_weight
          )
  
      # Multi-class categorical cross entropy loss
      if classes.min() < 0 or classes.max() >= pred.shape[1]:
          raise ValueError(
              "labels should be in the range [0, num_classes-1]."
          )
      if from_logits:
          pred = special.softmax(pred, axis=-1)
      return (
          -np.log(
              np.maximum(pred[range(labels.size), labels], small_value)
          )
          * sample_weight
      )
  
file_path: privacy/tensorflow_privacy/privacy/privacy_tests/utils.py
imports: import enum
  import logging
  import numbers
  from typing import Callable, Iterable, Optional, Union
  import numpy
  from scipy import special
label_desc: Use image node_id 1 for calling a global function with example usage: log_loss(labels, pred, sample_weight, from_logits, small_value) and returns: unknown, unknown