def ComputeLoss(self, theta, predictions, targets):
    """Computes loss metrics and per-sequence losses.

    Args:
      theta: A NestedMap object containing weights' values of this
        layer and its children layers.
      predictions: A NestedMap containing logits (and possibly other fields).
      targets: A dict of string to tensors representing the targets one is
          trying to predict. Each tensor in targets is of shape [batch, time].

    Returns:
      (metrics, per_sequence_loss), where metrics is a dictionary containing
      metrics for the xent loss and prediction accuracy. per_sequence is a
      dictionary containing 'loss', a (-log(p)) vector of size [bs].
    """
    p = self.params
    with tf.name_scope(p.name):
      if 'probs' in targets:
        target_probs = targets.probs
      elif p.label_smoothing is not None:
        target_probs = self.smoother.FProp(theta.smoother, targets.paddings,
                                           targets.labels, targets.ids)
      else:
        target_probs = None
      merged_metrics = {}
      merged_per_sequence_loss = 0.

      def AddToMetric(acc, scale, metric):
        assert len(acc) == 2
        assert len(metric) == 2
        return (acc[0] + scale * tf.cast(metric[0], py_utils.FPropDtype(p)),
                acc[1] + scale * tf.cast(metric[1], py_utils.FPropDtype(p)))

      for logit_name, loss_weight in six.iteritems(p.logit_types):
        metrics, per_sequence_loss = self._ComputeMetrics(
            getattr(predictions, logit_name), targets.labels, targets.weights,
            target_probs)
        for k, v in six.iteritems(metrics):
          tf.logging.info('Merging metric %s: %s', k, v)
          merged_metrics[k + '/' + logit_name] = v
          if k not in merged_metrics:
            merged_metrics[k] = (tf.zeros(
                shape=[], dtype=py_utils.FPropDtype(p)),
                                 tf.zeros(
                                     shape=[], dtype=py_utils.FPropDtype(p)))
          merged_metrics[k] = AddToMetric(merged_metrics[k], loss_weight, v)
        merged_per_sequence_loss += loss_weight * per_sequence_loss
      return merged_metrics, {'loss': merged_per_sequence_loss}
Computes loss metrics and per-sequence losses.

    Args:
      theta: A NestedMap object containing weights' values of this
        layer and its children layers.
      predictions: A NestedMap containing logits (and possibly other fields).
      targets: A dict of string to tensors representing the targets one is
          trying to predict. Each tensor in targets is of shape [batch, time].

    Returns:
      (metrics, per_sequence_loss), where metrics is a dictionary containing
      metrics for the xent loss and prediction accuracy. per_sequence is a
      dictionary containing 'loss', a (-log(p)) vector of size [bs].
    
contrib/lingvo-patched-decoder.py