diff --git a/paddle/fluid/operators/yolov3_loss_op.h b/paddle/fluid/operators/yolov3_loss_op.h index de01a01a4fb859e5bd3c5213f86290e6071629f0..2131289860eb9f59253aaf218451b466fcebb3ba 100644 --- a/paddle/fluid/operators/yolov3_loss_op.h +++ b/paddle/fluid/operators/yolov3_loss_op.h @@ -41,6 +41,11 @@ static T L1Loss(T x, T y) { return std::abs(y - x); } +template +static T L2Loss(T x, T y) { + return 0.5 * (y - x) * (y - x); +} + template static T SCEGrad(T x, T label) { return 1.0 / (1.0 + std::exp(-x)) - label; @@ -51,6 +56,11 @@ static T L1LossGrad(T x, T y) { return x > y ? 1.0 : -1.0; } +template +static T L2LossGrad(T x, T y) { + return x - y; +} + static int GetMaskIndex(std::vector mask, int val) { for (size_t i = 0; i < mask.size(); i++) { if (mask[i] == val) { @@ -130,8 +140,8 @@ static void CalcBoxLocationLoss(T* loss, const T* input, Box gt, T scale = (2.0 - gt.w * gt.h) * score; loss[0] += SCE(input[box_idx], tx) * scale; loss[0] += SCE(input[box_idx + stride], ty) * scale; - loss[0] += L1Loss(input[box_idx + 2 * stride], tw) * scale; - loss[0] += L1Loss(input[box_idx + 3 * stride], th) * scale; + loss[0] += L2Loss(input[box_idx + 2 * stride], tw) * scale; + loss[0] += L2Loss(input[box_idx + 3 * stride], th) * scale; } template @@ -150,9 +160,9 @@ static void CalcBoxLocationLossGrad(T* input_grad, const T loss, const T* input, input_grad[box_idx + stride] = SCEGrad(input[box_idx + stride], ty) * scale * loss; input_grad[box_idx + 2 * stride] = - L1LossGrad(input[box_idx + 2 * stride], tw) * scale * loss; + L2LossGrad(input[box_idx + 2 * stride], tw) * scale * loss; input_grad[box_idx + 3 * stride] = - L1LossGrad(input[box_idx + 3 * stride], th) * scale * loss; + L2LossGrad(input[box_idx + 3 * stride], th) * scale * loss; } template diff --git a/python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py b/python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py index ff76b763663ab598758ab52d7ef64460271919d1..0e17eb31305839e7a0ca02c4332956a0b256ed50 100644 --- a/python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py +++ b/python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py @@ -27,6 +27,10 @@ def l1loss(x, y): return abs(x - y) +def l2loss(x, y): + return 0.5 * (y - x) * (y - x) + + def sce(x, label): sigmoid_x = expit(x) term1 = label * np.log(sigmoid_x) @@ -145,8 +149,8 @@ def YOLOv3Loss(x, gtbox, gtlabel, gtscore, attrs): scale = (2.0 - gtbox[i, j, 2] * gtbox[i, j, 3]) * gtscore[i, j] loss[i] += sce(x[i, an_idx, gj, gi, 0], tx) * scale loss[i] += sce(x[i, an_idx, gj, gi, 1], ty) * scale - loss[i] += l1loss(x[i, an_idx, gj, gi, 2], tw) * scale - loss[i] += l1loss(x[i, an_idx, gj, gi, 3], th) * scale + loss[i] += l2loss(x[i, an_idx, gj, gi, 2], tw) * scale + loss[i] += l2loss(x[i, an_idx, gj, gi, 3], th) * scale objness[i, an_idx * h * w + gj * w + gi] = gtscore[i, j] @@ -202,7 +206,7 @@ class TestYolov3LossOp(OpTest): def test_check_output(self): place = core.CPUPlace() - self.check_output_with_place(place, atol=2e-3) + self.check_output_with_place(place, atol=1e-3) def test_check_grad_ignore_gtbox(self): place = core.CPUPlace() @@ -210,19 +214,16 @@ class TestYolov3LossOp(OpTest): place, ['X'], 'Loss', no_grad_set=set(["GTBox", "GTLabel", "GTScore"]), - max_relative_error=0.2) + max_relative_error=0.3) def initTestCase(self): - self.anchors = [ - 10, 13, 16, 30, 33, 23, 30, 61, 62, 45, 59, 119, 116, 90, 156, 198, - 373, 326 - ] - self.anchor_mask = [0, 1, 2] - self.class_num = 10 - self.ignore_thresh = 0.7 + self.anchors = [10, 13, 16, 30, 33, 23] + self.anchor_mask = [1, 2] + self.class_num = 5 + self.ignore_thresh = 0.5 self.downsample = 32 self.x_shape = (3, len(self.anchor_mask) * (5 + self.class_num), 5, 5) - self.gtbox_shape = (3, 10, 4) + self.gtbox_shape = (3, 5, 4) self.use_label_smooth = True