code: def _soft_log_loss(true_probs, predicted_probs):
      """Both args must be 2D pandas/numpy arrays"""
      true_probs = np.array(true_probs)
      predicted_probs = np.array(predicted_probs)
      if len(true_probs.shape) != 2 or len(predicted_probs.shape) != 2:
          raise ValueError(
              "both truth and prediction must be 2D numpy arrays"
          )
      if true_probs.shape != predicted_probs.shape:
          raise ValueError(
              "truth and prediction must be 2D numpy arrays with the same shape"
          )
  
      # true_probs = np.clip(true_probs, a_min=EPS, a_max=None)
      predicted_probs = np.clip(
          predicted_probs, a_min=EPS, a_max=None
      )  # clip 0s to avoid NaN
      true_probs = true_probs / true_probs.sum(
          axis=1, keepdims=1
      )  # renormalize
      predicted_probs = predicted_probs / predicted_probs.sum(
          axis=1, keepdims=1
      )
      loss = -(np.log(predicted_probs) * true_probs).sum(axis=1).mean()
      return loss
  
imports: import logging
  import numpy
  from .None import make_scorer
label_desc: Use image node_id 1 for calling a global function with example usage: _soft_log_loss(true_probs, predicted_probs) and returns: loss