From bdf3b39200f1c73788a3bc4874101055bb34ed3b Mon Sep 17 00:00:00 2001 From: longxiang Date: Wed, 8 Jul 2020 10:53:30 +0800 Subject: [PATCH] fix scalexy bug --- ppdet/modeling/losses/iou_aware_loss.py | 5 +-- ppdet/modeling/losses/iou_loss.py | 12 +++++--- ppdet/modeling/losses/yolo_loss.py | 41 ++++++++++++++++--------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/ppdet/modeling/losses/iou_aware_loss.py b/ppdet/modeling/losses/iou_aware_loss.py index afb91b414..c68c7a707 100644 --- a/ppdet/modeling/losses/iou_aware_loss.py +++ b/ppdet/modeling/losses/iou_aware_loss.py @@ -54,6 +54,7 @@ class IouAwareLoss(IouLoss): anchors, downsample_ratio, batch_size, + scale_x_y, eps=1.e-10): ''' Args: @@ -67,9 +68,9 @@ class IouAwareLoss(IouLoss): ''' pred = self._bbox_transform(x, y, w, h, anchors, downsample_ratio, - batch_size, False) + batch_size, False, scale_x_y, eps) gt = self._bbox_transform(tx, ty, tw, th, anchors, downsample_ratio, - batch_size, True) + batch_size, True, scale_x_y, eps) iouk = self._iou(pred, gt, ioup, eps) iouk.stop_gradient = True diff --git a/ppdet/modeling/losses/iou_loss.py b/ppdet/modeling/losses/iou_loss.py index 5cd8aaccf..15a5f229c 100644 --- a/ppdet/modeling/losses/iou_loss.py +++ b/ppdet/modeling/losses/iou_loss.py @@ -63,6 +63,7 @@ class IouLoss(object): anchors, downsample_ratio, batch_size, + scale_x_y=1., ioup=None, eps=1.e-10): ''' @@ -75,9 +76,9 @@ class IouLoss(object): eps (float): the decimal to prevent the denominator eqaul zero ''' pred = self._bbox_transform(x, y, w, h, anchors, downsample_ratio, - batch_size, False) + batch_size, False, scale_x_y, eps) gt = self._bbox_transform(tx, ty, tw, th, anchors, downsample_ratio, - batch_size, True) + batch_size, True, scale_x_y, eps) iouk = self._iou(pred, gt, ioup, eps) if self.loss_square: loss_iou = 1. - iouk * iouk @@ -145,7 +146,7 @@ class IouLoss(object): return diou_term + ciou_term def _bbox_transform(self, dcx, dcy, dw, dh, anchors, downsample_ratio, - batch_size, is_gt): + batch_size, is_gt, scale_x_y, eps): grid_x = int(self._MAX_WI / downsample_ratio) grid_y = int(self._MAX_HI / downsample_ratio) an_num = len(anchors) // 2 @@ -179,8 +180,11 @@ class IouLoss(object): cy.gradient = True else: dcx_sig = fluid.layers.sigmoid(dcx) - cx = fluid.layers.elementwise_add(dcx_sig, gi) / grid_x_act dcy_sig = fluid.layers.sigmoid(dcy) + if (abs(scale_x_y - 1.0) > eps): + dcx_sig = scale_x_y * dcx_sig - 0.5 * (scale_x_y - 1) + dcy_sig = scale_x_y * dcy_sig - 0.5 * (scale_x_y - 1) + cx = fluid.layers.elementwise_add(dcx_sig, gi) / grid_x_act cy = fluid.layers.elementwise_add(dcy_sig, gj) / grid_y_act anchor_w_ = [anchors[i] for i in range(0, len(anchors)) if i % 2 == 0] diff --git a/ppdet/modeling/losses/yolo_loss.py b/ppdet/modeling/losses/yolo_loss.py index 732edb39d..e97198fbc 100644 --- a/ppdet/modeling/losses/yolo_loss.py +++ b/ppdet/modeling/losses/yolo_loss.py @@ -92,7 +92,7 @@ class YOLOv3Loss(object): return {'loss': sum(losses)} def _get_fine_grained_loss(self, outputs, targets, gt_box, batch_size, - num_classes, mask_anchors, ignore_thresh): + num_classes, mask_anchors, ignore_thresh, eps=1.e-10): """ Calculate fine grained YOLOv3 loss @@ -136,12 +136,25 @@ class YOLOv3Loss(object): tx, ty, tw, th, tscale, tobj, tcls = self._split_target(target) tscale_tobj = tscale * tobj - loss_x = fluid.layers.sigmoid_cross_entropy_with_logits( - x, tx) * tscale_tobj - loss_x = fluid.layers.reduce_sum(loss_x, dim=[1, 2, 3]) - loss_y = fluid.layers.sigmoid_cross_entropy_with_logits( - y, ty) * tscale_tobj - loss_y = fluid.layers.reduce_sum(loss_y, dim=[1, 2, 3]) + + scale_x_y = self.scale_x_y if not isinstance( + self.scale_x_y, Sequence) else self.scale_x_y[i] + + if (abs(scale_x_y - 1.0) < eps): + loss_x = fluid.layers.sigmoid_cross_entropy_with_logits( + x, tx) * tscale_tobj + loss_x = fluid.layers.reduce_sum(loss_x, dim=[1, 2, 3]) + loss_y = fluid.layers.sigmoid_cross_entropy_with_logits( + y, ty) * tscale_tobj + loss_y = fluid.layers.reduce_sum(loss_y, dim=[1, 2, 3]) + else: + dx = scale_x_y * fluid.layers.sigmoid(x) - 0.5 * (scale_x_y - 1.0) + dy = scale_x_y * fluid.layers.sigmoid(y) - 0.5 * (scale_x_y - 1.0) + loss_x = fluid.layers.abs(dx - tx) * tscale_tobj + loss_x = fluid.layers.reduce_sum(loss_x, dim=[1, 2, 3]) + loss_y = fluid.layers.abs(dy - ty) * tscale_tobj + loss_y = fluid.layers.reduce_sum(loss_y, dim=[1, 2, 3]) + # NOTE: we refined loss function of (w, h) as L1Loss loss_w = fluid.layers.abs(w - tw) * tscale_tobj loss_w = fluid.layers.reduce_sum(loss_w, dim=[1, 2, 3]) @@ -149,7 +162,7 @@ class YOLOv3Loss(object): loss_h = fluid.layers.reduce_sum(loss_h, dim=[1, 2, 3]) if self._iou_loss is not None: loss_iou = self._iou_loss(x, y, w, h, tx, ty, tw, th, anchors, - downsample, self._batch_size) + downsample, self._batch_size, scale_x_y) loss_iou = loss_iou * tscale_tobj loss_iou = fluid.layers.reduce_sum(loss_iou, dim=[1, 2, 3]) loss_ious.append(fluid.layers.reduce_mean(loss_iou)) @@ -157,14 +170,12 @@ class YOLOv3Loss(object): if self._iou_aware_loss is not None: loss_iou_aware = self._iou_aware_loss( ioup, x, y, w, h, tx, ty, tw, th, anchors, downsample, - self._batch_size) + self._batch_size, scale_x_y) loss_iou_aware = loss_iou_aware * tobj loss_iou_aware = fluid.layers.reduce_sum( loss_iou_aware, dim=[1, 2, 3]) loss_iou_awares.append(fluid.layers.reduce_mean(loss_iou_aware)) - scale_x_y = self.scale_x_y if not isinstance( - self.scale_x_y, Sequence) else self.scale_x_y[i] loss_obj_pos, loss_obj_neg = self._calc_obj_loss( output, obj, tobj, gt_box, self._batch_size, anchors, num_classes, downsample, self._ignore_thresh, scale_x_y) @@ -293,7 +304,7 @@ class YOLOv3Loss(object): downsample_ratio=downsample, clip_bbox=False, scale_x_y=scale_x_y) - + # 2. split pred bbox and gt bbox by sample, calculate IoU between pred bbox # and gt bbox in each sample if batch_size > 1: @@ -322,17 +333,17 @@ class YOLOv3Loss(object): pred = fluid.layers.squeeze(pred, axes=[0]) gt = box_xywh2xyxy(fluid.layers.squeeze(gt, axes=[0])) ious.append(fluid.layers.iou_similarity(pred, gt)) - + iou = fluid.layers.stack(ious, axis=0) # 3. Get iou_mask by IoU between gt bbox and prediction bbox, # Get obj_mask by tobj(holds gt_score), calculate objectness loss - + max_iou = fluid.layers.reduce_max(iou, dim=-1) iou_mask = fluid.layers.cast(max_iou <= ignore_thresh, dtype="float32") if self.match_score: max_prob = fluid.layers.reduce_max(prob, dim=-1) iou_mask = iou_mask * fluid.layers.cast( - max_prob <= 0.25, dtype="float32") + max_prob <= 0.25, dtype="float32") output_shape = fluid.layers.shape(output) an_num = len(anchors) // 2 iou_mask = fluid.layers.reshape(iou_mask, (-1, an_num, output_shape[2], -- GitLab