def box_iou(self, true_box, pred_box): # based on the type of loss, compute the iou loss for a box # compute_<name> indicated the type of iou to use if self.iou_type == 'giou': _, iou = box_ops.compute_giou(true_box, pred_box) elif self.iou_type == 'ciou': _, iou = box_ops.compute_ciou(true_box, pred_box) else: iou = box_ops.compute_iou(true_box, pred_box) return iou
def box_loss(self, true_box, pred_box, darknet=False): """Call iou function and use it to compute the loss for the box maps.""" if self._loss_type == 'giou': iou, liou = box_ops.compute_giou(true_box, pred_box) elif self._loss_type == 'ciou': iou, liou = box_ops.compute_ciou(true_box, pred_box, darknet=darknet) else: liou = iou = box_ops.compute_iou(true_box, pred_box) loss_box = 1 - liou return iou, liou, loss_box
def test_ious(self, num_boxes): boxes = tf.convert_to_tensor(np.random.rand(num_boxes, 4)) expected_shape = np.array([ num_boxes, ]) expected_iou = np.ones([ num_boxes, ]) iou = box_ops.compute_iou(boxes, boxes) _, giou = box_ops.compute_giou(boxes, boxes) _, ciou = box_ops.compute_ciou(boxes, boxes) _, diou = box_ops.compute_diou(boxes, boxes) self.assertAllEqual(tf.shape(iou).numpy(), expected_shape) self.assertArrayNear(iou, expected_iou, 0.001) self.assertArrayNear(giou, expected_iou, 0.001) self.assertArrayNear(ciou, expected_iou, 0.001) self.assertArrayNear(diou, expected_iou, 0.001)
def aggregated_comparative_iou(boxes1, boxes2=None, iou_type=0): k = tf.shape(boxes1)[-2] boxes1 = tf.expand_dims(boxes1, axis=-2) boxes1 = tf.tile(boxes1, [1, 1, k, 1]) if boxes2 is not None: boxes2 = tf.expand_dims(boxes2, axis=-2) boxes2 = tf.tile(boxes2, [1, 1, k, 1]) boxes2 = tf.transpose(boxes2, perm=(0, 2, 1, 3)) else: boxes2 = tf.transpose(boxes1, perm=(0, 2, 1, 3)) if iou_type == 0: # diou _, iou = box_ops.compute_diou(boxes1, boxes2) elif iou_type == 1: # giou _, iou = box_ops.compute_giou(boxes1, boxes2) else: iou = box_ops.compute_iou(boxes1, boxes2, yxyx=True) return iou
def __call__(self, pred: tf.Tensor, conv: tf.Tensor, label: tf.Tensor, bboxes: tf.Tensor): """Invokes the `YoloLoss`. Args: pred: `tf.Tensor` of shape [batch, height, width, num_anchors, 5 + classes] denoting actual predictions for each scale conv: `tf.Tensor` of shape [batch, height, width, num_anchors, 5 + classes] denoting raw logits from final convolution label: `tf.Tensor` of shape [batch, height, width, num_anchors, 5 + classes] denoting groundtruth labels scaled according to feature size bboxes: `tf.Tensor` of shape [batch, max_num_bboxes, 5 + classes] denoting ground truth bounding boxes scaled according to feature size Returns: giou_loss: Summed loss float `Tensor`, conf_loss: Summed loss float `Tensor`, prob_loss: Summed loss float `Tensor` """ conv_shape = tf.shape(conv) batch_size = conv_shape[0] output_size = conv_shape[1] conv = tf.reshape( conv, (batch_size, output_size, output_size, 3, 5 + self.num_classes)) conv_raw_conf = conv[:, :, :, :, 4:5] conv_raw_prob = conv[:, :, :, :, 5:] pred_xywh = pred[:, :, :, :, 0: 4] # bbox prediction in center x, center y, width, height pred_conf = pred[:, :, :, :, 4:5] # confidence label_xywh = label[:, :, :, :, 0:4] # bbox in center x, center y, width, height respond_bbox = label[:, :, :, :, 4:5] # confidence label_prob = label[:, :, :, :, 5:] # one-hot labels giou, iou = box_ops.compute_giou(pred_xywh, label_xywh) giou = tf.expand_dims(giou, axis=-1) giou = tf.expand_dims(box_ops.compute_giou(pred_xywh, label_xywh)[1], axis=-1) bbox_loss_scale = 2.0 - 1.0 * label_xywh[:, :, :, :, 2: 3] * label_xywh[:, :, :, :, 3:4] / ( self. input_size * self. input_size ) giou_loss = respond_bbox * bbox_loss_scale * (1 - giou) # iou = yolo_ops.bbox_iou(pred_xywh[:, :, :, :, tf.newaxis, :], bboxes[:, tf.newaxis, tf.newaxis, tf.newaxis, :, :]) # max_iou = tf.expand_dims(tf.reduce_max(iou, axis=-1), axis=-1) max_iou = tf.expand_dims(iou, axis=-1) respond_bgd = (1.0 - respond_bbox) * tf.cast( max_iou < self.iou_loss_thres, tf.float32) conf_focal = tf.pow(respond_bbox - pred_conf, 2) # focal weight conf_loss = conf_focal * ( respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits( labels=respond_bbox, logits=conv_raw_conf) + respond_bgd * tf.nn.sigmoid_cross_entropy_with_logits( labels=respond_bbox, logits=conv_raw_conf)) prob_loss = respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits( labels=label_prob, logits=conv_raw_prob) giou_loss = tf.reduce_mean(tf.reduce_sum(giou_loss, axis=[1, 2, 3, 4])) conf_loss = tf.reduce_mean(tf.reduce_sum(conf_loss, axis=[1, 2, 3, 4])) prob_loss = tf.reduce_mean(tf.reduce_sum(prob_loss, axis=[1, 2, 3, 4])) return giou_loss, conf_loss, prob_loss