'Compute scalar loss tensors with respect to provided groundtruth.
Calling this function requires that groundtruth tensors have been
provided via the provide_groundtruth function.
Args:
prediction_dict: a dictionary holding prediction tensors with
1) box_encodings: 4-D float tensor of shape [batch_size, num_anchors,
box_code_dimension] containing predicted boxes.
2) class_predictions_with_background: 2-D float tensor of shape
[batch_size, num_anchors, num_classes+1] containing class predictions
(logits) for each of the anchors.  Note that this tensor *includes*
background class predictions.
scope: Optional scope name.
Returns:
a dictionary mapping loss keys (`localization_loss` and
`classification_loss`) to scalar tensors representing corresponding loss
values.'

def loss(self, prediction_dict, scope=None):

    with tf.name_scope(scope, 'Loss', prediction_dict.values()):
        (batch_cls_targets, batch_cls_weights, batch_reg_targets, batch_reg_weights, match_list) = self._assign_targets(self.groundtruth_lists(fields.BoxListFields.boxes), self.groundtruth_lists(fields.BoxListFields.classes))
        if self._add_summaries:
            self._summarize_input(self.groundtruth_lists(fields.BoxListFields.boxes), match_list)
        num_matches = tf.stack([match.num_matched_columns() for match in match_list])
        location_losses = self._localization_loss(prediction_dict['box_encodings'], batch_reg_targets, weights=batch_reg_weights)
        cls_losses = self._classification_loss(prediction_dict['class_predictions_with_background'], batch_cls_targets, weights=batch_cls_weights)
        localization_loss = tf.reduce_sum(location_losses)
        classification_loss = tf.reduce_sum(cls_losses)
        if self._hard_example_miner:
            (localization_loss, classification_loss) = self._apply_hard_mining(location_losses, cls_losses, prediction_dict, match_list)
            if self._add_summaries:
                self._hard_example_miner.summarize()
        normalizer = tf.constant(1.0, dtype=tf.float32)
        if self._normalize_loss_by_num_matches:
            normalizer = tf.maximum(tf.to_float(tf.reduce_sum(num_matches)), 1.0)
        loss_dict = {'localization_loss': ((self._localization_loss_weight / normalizer) * localization_loss), 'classification_loss': ((self._classification_loss_weight / normalizer) * classification_loss)}
    return loss_dict
