docstr: Define loss layer
  
  Parameters
  ----------
  predict: TensorFlow Tensor
      The predicted values for the batch of data
  labels: TensorFlow Tensor
      Ground truth labels for the batch of data
  
  Returns
  -------
  loss: TensorFlow Tensor
      Loss (combination of regression and classification losses)
docstr_tok: ["Define","loss","layer","Parameters","--","--","--","--","--","predict",":","TensorFlow","Tensor","The","predicted","values","for","the","batch","of","data","labels",":","TensorFlow","Tensor","Ground","truth","labels","for","the","batch","of","data","Returns","--","--","--","-","loss",":","TensorFlow","Tensor","Loss","(","combination","of","regression","and","classification","losses",")"]
code: def loss_layer(self, predict, labels):
      """
      Define loss layer
  
      Parameters
      ----------
      predict: TensorFlow Tensor
          The predicted values for the batch of data
      labels: TensorFlow Tensor
          Ground truth labels for the batch of data
  
      Returns
      -------
      loss: TensorFlow Tensor
          Loss (combination of regression and classification losses)
      """
      _tf = _lazy_import_tensorflow()
  
      POS_IOU = 0.7
      NEG_IOU = 0.3
  
      rescore = int(
          _utils.convert_shared_float_array_to_numpy(
              self.config.get("od_rescore")
          )
      )
      lmb_coord_xy = _utils.convert_shared_float_array_to_numpy(
          self.config.get("lmb_coord_xy")
      )
      lmb_coord_wh = _utils.convert_shared_float_array_to_numpy(
          self.config.get("lmb_coord_wh")
      )
      lmb_obj = _utils.convert_shared_float_array_to_numpy(
          self.config.get("lmb_obj")
      )
      lmb_noobj = _utils.convert_shared_float_array_to_numpy(
          self.config.get("lmb_noobj")
      )
      lmb_class = _utils.convert_shared_float_array_to_numpy(
          self.config.get("lmb_class")
      )
  
      # Prediction values from model on the images
      ypred = _tf.reshape(
          predict,
          [-1]
          + list(self.grid_shape)
          + [self.num_anchors, 5 + self.num_classes],
      )
      raw_xy = ypred[..., 0:2]
      raw_wh = ypred[..., 2:4]
      raw_conf = ypred[..., 4]
      class_scores = ypred[..., 5:]
  
      tf_anchors = _tf.constant(self.anchors)
  
      # Ground Truth info derived from ymap/labels
      gt_xy = labels[..., 0:2]
      gt_wh = labels[..., 2:4]
      gt_raw_wh = _tf.math.log(gt_wh / tf_anchors + 1e-5)
      gt_conf = labels[..., 4]
      gt_class = labels[..., 5:]
  
      # Calculations on predicted confidences
      xy = _tf.sigmoid(raw_xy)
      wh = _tf.exp(raw_wh) * tf_anchors
      wh_anchors = _tf.exp(raw_wh * 0.0) * tf_anchors
      lo = xy - wh / 2
      hi = xy + wh / 2
  
      gt_area = gt_wh[..., 0] * gt_wh[..., 1]
      gt_lo = gt_xy - gt_wh / 2
      gt_hi = gt_xy + gt_wh / 2
  
      c_inter = _tf.maximum(
          2 * _tf.minimum(wh_anchors / 2, gt_wh / 2), 0
      )
      c_area = wh_anchors[..., 0] * wh_anchors[..., 1]
      c_inter_area = c_inter[..., 0] * c_inter[..., 1]
      c_iou = c_inter_area / (c_area + gt_area - c_inter_area)
  
      inter = _tf.maximum(
          _tf.minimum(hi, gt_hi) - _tf.maximum(lo, gt_lo), 0
      )
      area = wh[..., 0] * wh[..., 1]
      inter_area = inter[..., 0] * inter[..., 1]
      iou = inter_area / (area + gt_area - inter_area)
      active_iou = c_iou
  
      cond_gt = _tf.cast(
          _tf.equal(gt_conf, _tf.constant(1.0)), dtype=_tf.float32
      )
      max_iou = _tf.reduce_max(active_iou, 3, keepdims=True)
      cond_max = _tf.cast(
          _tf.equal(active_iou, max_iou), dtype=_tf.float32
      )
  
      cond_above = c_iou > POS_IOU
  
      cond_logical_or = _tf.cast(
          _tf.math.logical_or(
              _tf.cast(cond_max, dtype=_tf.bool),
              _tf.cast(cond_above, dtype=_tf.bool),
          ),
          dtype=_tf.float32,
      )
      cond_obj = _tf.cast(
          _tf.math.logical_and(
              _tf.cast(cond_gt, dtype=_tf.bool),
              _tf.cast(cond_logical_or, dtype=_tf.bool),
          ),
          dtype=_tf.float32,
      )
  
      kr_obj_ij = _tf.stop_gradient(cond_obj)
  
      cond_below = c_iou < NEG_IOU
  
      cond_logical_not = _tf.cast(
          _tf.math.logical_not(_tf.cast(cond_obj, dtype=_tf.bool)),
          dtype=_tf.float32,
      )
      cond_noobj = _tf.cast(
          _tf.math.logical_and(
              _tf.cast(cond_below, dtype=_tf.bool),
              _tf.cast(cond_logical_not, dtype=_tf.bool),
          ),
          dtype=_tf.float32,
      )
  
      kr_noobj_ij = _tf.stop_gradient(cond_noobj)
  
      count = _tf.reduce_sum(kr_obj_ij)
      eps_count = _tf.math.add(count, _tf.constant(1e-4))
  
      scale_conf = 1 / (
          self.batch_size * self.grid_shape[0] * self.grid_shape[1]
      )
  
      kr_obj_ij_plus1 = _tf.expand_dims(kr_obj_ij, -1)
      if rescore:
          obj_gt_conf = kr_obj_ij * _tf.stop_gradient(iou)
      else:
          obj_gt_conf = kr_obj_ij
  
      obj_w_obj = kr_obj_ij * lmb_obj
      obj_w_noobj = kr_noobj_ij * lmb_noobj
  
      obj_w = _tf.math.add(obj_w_obj, obj_w_noobj)
  
      loss_xy = (
          lmb_coord_xy
          * _tf.reduce_sum(kr_obj_ij_plus1 * _tf.square(gt_xy - xy))
          / eps_count
      )
      loss_wh = _tf.losses.huber_loss(
          labels=gt_raw_wh,
          predictions=raw_wh,
          weights=lmb_coord_wh * kr_obj_ij_plus1,
          delta=1.0,
      )
      loss_conf = scale_conf * _tf.reduce_sum(
          obj_w
          * _tf.nn.sigmoid_cross_entropy_with_logits(
              labels=obj_gt_conf, logits=raw_conf
          )
      )
      loss_cls = (
          lmb_class
          * _tf.reduce_sum(
              kr_obj_ij
              * _tf.nn.softmax_cross_entropy_with_logits_v2(
                  labels=gt_class, logits=class_scores
              )
          )
          / eps_count
      )
  
      losses = [loss_xy, loss_wh, loss_conf, loss_cls]
      loss = _tf.add_n(losses)
  
      return loss
  
imports: from __future__ import print_function
  from __future__ import division
  from __future__ import absolute_import
  import numpy
  from .._tf_model import TensorFlowModel
  from turicreate._deps.minimal_package import _minimal_package_import_check
  import turicreate.toolkits._tf_utils
label_desc: Use image node_id 8 for calling the ODTensorFlowModel obj's underlying member method code with example usage: obj.loss_layer(predict, labels) and returns: loss