class_docstr: SSD: Single Shot MultiBox Detector
      
class_docstr_tok: ["SSD",":","Single","Shot","MultiBox","Detector"]
docstr: Compute the loss for SSD.
  
  Args:
      prediction_dict: The output dictionary of the _build method from
          which we use different main keys:
  
          cls_pred: A dictionary with the classes classification.
          loc_pred: A dictionary with the localization predictions
          target: A dictionary with the targets for both classes and
              localizations.
  
  Returns:
      A tensor for the total loss.
docstr_tok: ["Compute","the","loss","for","SSD",".","Args",":","prediction_dict",":","The","output","dictionary","of","the","_build","method","from","which","we","use","different","main","keys",":","cls_pred",":","A","dictionary","with","the","classes","classification",".","loc_pred",":","A","dictionary","with","the","localization","predictions","target",":","A","dictionary","with","the","targets","for","both","classes","and","localizations",".","Returns",":","A","tensor","for","the","total","loss","."]
code: def loss(self, prediction_dict, return_all=False):
      """Compute the loss for SSD.
  
      Args:
          prediction_dict: The output dictionary of the _build method from
              which we use different main keys:
  
              cls_pred: A dictionary with the classes classification.
              loc_pred: A dictionary with the localization predictions
              target: A dictionary with the targets for both classes and
                  localizations.
  
      Returns:
          A tensor for the total loss.
      """
  
      with tf.name_scope("losses"):
          cls_pred = prediction_dict["cls_pred"]
          cls_target = tf.cast(
              prediction_dict["target"]["cls"], tf.int32
          )
          # Transform to one-hot vector
          cls_target_one_hot = tf.one_hot(
              cls_target,
              depth=self._num_classes + 1,
              name="cls_target_one_hot",
          )
  
          # We get cross entropy loss of each proposal.
          # TODO: Optimization opportunity: We calculate the probabilities
          #       earlier in the program, so if we used those instead of the
          #       logits we would not have the need to do softmax here too.
          cross_entropy_per_proposal = (
              tf.nn.softmax_cross_entropy_with_logits(
                  labels=cls_target_one_hot, logits=cls_pred
              )
          )
          # Second we need to calculate the smooth l1 loss between
          # `bbox_offsets` and `bbox_offsets_targets`.
          bbox_offsets = prediction_dict["loc_pred"]
          bbox_offsets_targets = prediction_dict["target"][
              "bbox_offsets"
          ]
  
          # We only want the non-background labels bounding boxes.
          not_ignored = tf.reshape(tf.greater(cls_target, 0), [-1])
          bbox_offsets_positives = tf.boolean_mask(
              bbox_offsets, not_ignored, name="bbox_offsets_positives"
          )
          bbox_offsets_target_positives = tf.boolean_mask(
              bbox_offsets_targets,
              not_ignored,
              name="bbox_offsets_target_positives",
          )
  
          # Calculate the smooth l1 regression loss between the flatten
          # bboxes offsets  and the labeled targets.
          reg_loss_per_proposal = smooth_l1_loss(
              bbox_offsets_positives, bbox_offsets_target_positives
          )
  
          cls_loss = tf.reduce_sum(cross_entropy_per_proposal)
          bbox_loss = tf.reduce_sum(reg_loss_per_proposal)
  
          # Following the paper, set loss to 0 if there are 0 bboxes
          # assigned as foreground targets.
          safety_condition = tf.not_equal(
              tf.shape(bbox_offsets_positives)[0], 0
          )
          final_loss = tf.cond(
              safety_condition,
              true_fn=lambda: (
                  (cls_loss + bbox_loss * self._loc_loss_weight)
                  / tf.cast(
                      tf.shape(bbox_offsets_positives)[0], tf.float32
                  )
              ),
              false_fn=lambda: 0.0,
          )
          tf.losses.add_loss(final_loss)
          total_loss = tf.losses.get_total_loss()
  
          prediction_dict[
              "reg_loss_per_proposal"
          ] = reg_loss_per_proposal
          prediction_dict[
              "cls_loss_per_proposal"
          ] = cross_entropy_per_proposal
  
          tf.summary.scalar(
              "cls_loss", cls_loss, collections=self._losses_collections
          )
  
          tf.summary.scalar(
              "bbox_loss",
              bbox_loss,
              collections=self._losses_collections,
          )
  
          tf.summary.scalar(
              "total_loss",
              total_loss,
              collections=self._losses_collections,
          )
          if return_all:
              return {
                  "total_loss": total_loss,
                  "cls_loss": cls_loss,
                  "bbox_loss": bbox_loss,
              }
          else:
              return total_loss
  
file_path: luminoth/luminoth/models/ssd/ssd.py
imports: import numpy
  import sonnet
  import tensorflow
  from sonnet.python.modules.conv import Conv2D
  from luminoth.models.ssd.feature_extractor import SSDFeatureExtractor
  from luminoth.models.ssd.proposal import SSDProposal
  from luminoth.models.ssd.target import SSDTarget
  from luminoth.models.ssd.utils import generate_raw_anchors, adjust_bboxes
  from luminoth.utils.losses import smooth_l1_loss
  from luminoth.utils.bbox_transform import clip_boxes
label_desc: Use image node_id 3 for calling the SSD obj's underlying member method code with example usage: obj.loss(prediction_dict, return_all) and returns: dict, total_loss