diff --git a/paddle/fluid/operators/yolov3_loss_op.cc b/paddle/fluid/operators/yolov3_loss_op.cc index 495a8f6c01d57ba18fe9232f9c327659205d5cda..aa4ba3b62eb342ffc3c5e49a38664960c7372341 100644 --- a/paddle/fluid/operators/yolov3_loss_op.cc +++ b/paddle/fluid/operators/yolov3_loss_op.cc @@ -138,17 +138,23 @@ class Yolov3LossOpMaker : public framework::OpProtoAndCheckerMaker { thresh, the confidence score loss of this anchor box will be ignored. Therefore, the yolov3 loss consist of three major parts, box location loss, - confidence score loss, and classification loss. The MSE loss is used for - box location, and binary cross entropy loss is used for confidence score - loss and classification loss. + confidence score loss, and classification loss. The L1 loss is used for + box coordinates (w, h), and sigmoid cross entropy loss is used for box + coordinates (x, y), confidence score loss and classification loss. + + In order to trade off box coordinate losses between big boxes and small + boxes, box coordinate losses will be mutiplied by scale weight, which is + calculated as follow. + + $$ + weight_{box} = 2.0 - t_w * t_h + $$ Final loss will be represented as follow. $$ - loss = \loss_weight_{xy} * loss_{xy} + \loss_weight_{wh} * loss_{wh} - + \loss_weight_{conf_target} * loss_{conf_target} - + \loss_weight_{conf_notarget} * loss_{conf_notarget} - + \loss_weight_{class} * loss_{class} + loss = (loss_{xy} + loss_{wh}) * weight_{box} + + loss_{conf} + loss_{class} $$ )DOC"); } @@ -204,11 +210,7 @@ namespace ops = paddle::operators; REGISTER_OPERATOR(yolov3_loss, ops::Yolov3LossOp, ops::Yolov3LossOpMaker, ops::Yolov3LossGradMaker); REGISTER_OPERATOR(yolov3_loss_grad, ops::Yolov3LossOpGrad); -REGISTER_OP_CPU_KERNEL( - yolov3_loss, - ops::Yolov3LossKernel, - ops::Yolov3LossKernel); -REGISTER_OP_CPU_KERNEL( - yolov3_loss_grad, - ops::Yolov3LossGradKernel, - ops::Yolov3LossGradKernel); +REGISTER_OP_CPU_KERNEL(yolov3_loss, ops::Yolov3LossKernel, + ops::Yolov3LossKernel); +REGISTER_OP_CPU_KERNEL(yolov3_loss_grad, ops::Yolov3LossGradKernel, + ops::Yolov3LossGradKernel); diff --git a/paddle/fluid/operators/yolov3_loss_op.h b/paddle/fluid/operators/yolov3_loss_op.h index f086e89a99512a1521d17f8712a6ae1774f043fc..e32cd309674c71a2d6c88d34adcea69ccb84ce5b 100644 --- a/paddle/fluid/operators/yolov3_loss_op.h +++ b/paddle/fluid/operators/yolov3_loss_op.h @@ -260,26 +260,18 @@ static void CalcYolov3Loss(T* loss_data, const Tensor& input, const Tensor& tx, const int class_num = tclass.dims()[4]; const int grid_num = h * w; - // T l = 0.0; CalcSCE(loss_data, input_data, tx_data, tweight_data, obj_mask_data, n, an_num, grid_num, class_num, 1); CalcSCE(loss_data, input_data + grid_num, ty_data, tweight_data, obj_mask_data, n, an_num, grid_num, class_num, 1); - // LOG(ERROR) << "C++ xy: " << loss_data[0] - l; - // l = loss_data[0]; CalcL1Loss(loss_data, input_data + 2 * grid_num, tw_data, tweight_data, obj_mask_data, n, an_num, grid_num, class_num); CalcL1Loss(loss_data, input_data + 3 * grid_num, th_data, tweight_data, obj_mask_data, n, an_num, grid_num, class_num); - // LOG(ERROR) << "C++ wh: " << loss_data[0] - l; - // l = loss_data[0]; CalcSCE(loss_data, input_data + 4 * grid_num, tconf_data, conf_mask_data, conf_mask_data, n, an_num, grid_num, class_num, 1); - // LOG(ERROR) << "C++ conf: " << loss_data[0] - l; - // l = loss_data[0]; CalcSCE(loss_data, input_data + 5 * grid_num, tclass_data, obj_mask_data, obj_mask_data, n, an_num, grid_num, class_num, class_num); - // LOG(ERROR) << "C++ class: " << loss_data[0] - l; } template @@ -329,7 +321,7 @@ static void CalcYolov3LossGrad(T* input_grad_data, const Tensor& loss_grad, obj_mask_data, n, an_num, grid_num, class_num, class_num); } -template +template class Yolov3LossKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& ctx) const override { @@ -359,24 +351,24 @@ class Yolov3LossKernel : public framework::OpKernel { tconf.mutable_data({n, an_num, h, w}, ctx.GetPlace()); tclass.mutable_data({n, an_num, h, w, class_num}, ctx.GetPlace()); - math::SetConstant constant; - constant(ctx.template device_context(), &conf_mask, - static_cast(1.0)); - constant(ctx.template device_context(), &obj_mask, - static_cast(0.0)); - constant(ctx.template device_context(), &tx, - static_cast(0.0)); - constant(ctx.template device_context(), &ty, + math::SetConstant constant; + constant(ctx.template device_context(), + &conf_mask, static_cast(1.0)); + constant(ctx.template device_context(), + &obj_mask, static_cast(0.0)); + constant(ctx.template device_context(), &tx, static_cast(0.0)); - constant(ctx.template device_context(), &tw, + constant(ctx.template device_context(), &ty, static_cast(0.0)); - constant(ctx.template device_context(), &th, + constant(ctx.template device_context(), &tw, static_cast(0.0)); - constant(ctx.template device_context(), &tweight, + constant(ctx.template device_context(), &th, static_cast(0.0)); - constant(ctx.template device_context(), &tconf, + constant(ctx.template device_context(), + &tweight, static_cast(0.0)); + constant(ctx.template device_context(), &tconf, static_cast(0.0)); - constant(ctx.template device_context(), &tclass, + constant(ctx.template device_context(), &tclass, static_cast(0.0)); PreProcessGTBox(*gt_box, *gt_label, ignore_thresh, anchors, input_size, @@ -390,7 +382,7 @@ class Yolov3LossKernel : public framework::OpKernel { } }; -template +template class Yolov3LossGradKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& ctx) const override { @@ -422,24 +414,24 @@ class Yolov3LossGradKernel : public framework::OpKernel { tconf.mutable_data({n, an_num, h, w}, ctx.GetPlace()); tclass.mutable_data({n, an_num, h, w, class_num}, ctx.GetPlace()); - math::SetConstant constant; - constant(ctx.template device_context(), &conf_mask, - static_cast(1.0)); - constant(ctx.template device_context(), &obj_mask, - static_cast(0.0)); - constant(ctx.template device_context(), &tx, - static_cast(0.0)); - constant(ctx.template device_context(), &ty, + math::SetConstant constant; + constant(ctx.template device_context(), + &conf_mask, static_cast(1.0)); + constant(ctx.template device_context(), + &obj_mask, static_cast(0.0)); + constant(ctx.template device_context(), &tx, static_cast(0.0)); - constant(ctx.template device_context(), &tw, + constant(ctx.template device_context(), &ty, static_cast(0.0)); - constant(ctx.template device_context(), &th, + constant(ctx.template device_context(), &tw, static_cast(0.0)); - constant(ctx.template device_context(), &tweight, + constant(ctx.template device_context(), &th, static_cast(0.0)); - constant(ctx.template device_context(), &tconf, + constant(ctx.template device_context(), + &tweight, static_cast(0.0)); + constant(ctx.template device_context(), &tconf, static_cast(0.0)); - constant(ctx.template device_context(), &tclass, + constant(ctx.template device_context(), &tclass, static_cast(0.0)); PreProcessGTBox(*gt_box, *gt_label, ignore_thresh, anchors, input_size, diff --git a/python/paddle/fluid/layers/detection.py b/python/paddle/fluid/layers/detection.py index caa9b1c3d4723cfab690e42221c3437e70705ef2..92823af1e02087e6dada07e829111eb515b3caf7 100644 --- a/python/paddle/fluid/layers/detection.py +++ b/python/paddle/fluid/layers/detection.py @@ -485,19 +485,6 @@ def yolov3_loss(x, "input_size": input_size, } - # if loss_weight_xy is not None and isinstance(loss_weight_xy, float): - # self.attrs['loss_weight_xy'] = loss_weight_xy - # if loss_weight_wh is not None and isinstance(loss_weight_wh, float): - # self.attrs['loss_weight_wh'] = loss_weight_wh - # if loss_weight_conf_target is not None and isinstance( - # loss_weight_conf_target, float): - # self.attrs['loss_weight_conf_target'] = loss_weight_conf_target - # if loss_weight_conf_notarget is not None and isinstance( - # loss_weight_conf_notarget, float): - # self.attrs['loss_weight_conf_notarget'] = loss_weight_conf_notarget - # if loss_weight_class is not None and isinstance(loss_weight_class, float): - # self.attrs['loss_weight_class'] = loss_weight_class - helper.append_op( type='yolov3_loss', inputs={"X": x, 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 862e77e6639b8a84413d7f6cc9ffc49f2c44cd4f..e52047b0ad651774145b589217156a6501547cee 100644 --- a/python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py +++ b/python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py @@ -157,11 +157,6 @@ def YoloV3Loss(x, gtbox, gtlabel, attrs): loss_obj = sce(pred_conf, tconf, conf_mask) loss_class = sce(pred_cls, tcls, obj_mask_expand) - # print("python loss_xy: ", loss_x + loss_y) - # print("python loss_wh: ", loss_w + loss_h) - # print("python loss_obj: ", loss_obj) - # print("python loss_class: ", loss_class) - return loss_x + loss_y + loss_w + loss_h + loss_obj + loss_class