From 733bb82ec0d7ba4bbe9f0ed2aa5c36bc81829fa0 Mon Sep 17 00:00:00 2001 From: dengkaipeng Date: Tue, 29 Jan 2019 14:38:47 +0800 Subject: [PATCH] downsample -> downsample_ratio. test=develop --- paddle/fluid/API.spec | 2 +- paddle/fluid/operators/yolov3_loss_op.cc | 2 +- paddle/fluid/operators/yolov3_loss_op.h | 41 +++++++++++++----------- python/paddle/fluid/layers/detection.py | 10 +++--- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/paddle/fluid/API.spec b/paddle/fluid/API.spec index 6c6ac9c7ea..5fdab448cb 100644 --- a/paddle/fluid/API.spec +++ b/paddle/fluid/API.spec @@ -324,7 +324,7 @@ paddle.fluid.layers.generate_mask_labels ArgSpec(args=['im_info', 'gt_classes', paddle.fluid.layers.iou_similarity ArgSpec(args=['x', 'y', 'name'], varargs=None, keywords=None, defaults=(None,)) paddle.fluid.layers.box_coder ArgSpec(args=['prior_box', 'prior_box_var', 'target_box', 'code_type', 'box_normalized', 'name'], varargs=None, keywords=None, defaults=('encode_center_size', True, None)) paddle.fluid.layers.polygon_box_transform ArgSpec(args=['input', 'name'], varargs=None, keywords=None, defaults=(None,)) -paddle.fluid.layers.yolov3_loss ArgSpec(args=['x', 'gtbox', 'gtlabel', 'anchors', 'anchor_mask', 'class_num', 'ignore_thresh', 'downsample', 'name'], varargs=None, keywords=None, defaults=(None,)) +paddle.fluid.layers.yolov3_loss ArgSpec(args=['x', 'gtbox', 'gtlabel', 'anchors', 'anchor_mask', 'class_num', 'ignore_thresh', 'downsample_ratio', 'name'], varargs=None, keywords=None, defaults=(None,)) paddle.fluid.layers.multiclass_nms ArgSpec(args=['bboxes', 'scores', 'score_threshold', 'nms_top_k', 'keep_top_k', 'nms_threshold', 'normalized', 'nms_eta', 'background_label', 'name'], varargs=None, keywords=None, defaults=(0.3, True, 1.0, 0, None)) paddle.fluid.layers.accuracy ArgSpec(args=['input', 'label', 'k', 'correct', 'total'], varargs=None, keywords=None, defaults=(1, None, None)) paddle.fluid.layers.auc ArgSpec(args=['input', 'label', 'curve', 'num_thresholds', 'topk', 'slide_steps'], varargs=None, keywords=None, defaults=('ROC', 4095, 1, 1)) diff --git a/paddle/fluid/operators/yolov3_loss_op.cc b/paddle/fluid/operators/yolov3_loss_op.cc index 30f0c08463..81fd87b4ac 100644 --- a/paddle/fluid/operators/yolov3_loss_op.cc +++ b/paddle/fluid/operators/yolov3_loss_op.cc @@ -135,7 +135,7 @@ class Yolov3LossOpMaker : public framework::OpProtoAndCheckerMaker { "The mask index of anchors used in " "current YOLOv3 loss calculation.") .SetDefault(std::vector{}); - AddAttr("downsample", + AddAttr("downsample_ratio", "The downsample ratio from network input to YOLOv3 loss " "input, so 32, 16, 8 should be set for the first, second, " "and thrid YOLOv3 loss operators.") diff --git a/paddle/fluid/operators/yolov3_loss_op.h b/paddle/fluid/operators/yolov3_loss_op.h index fce8195668..8407d4e6e8 100644 --- a/paddle/fluid/operators/yolov3_loss_op.h +++ b/paddle/fluid/operators/yolov3_loss_op.h @@ -32,7 +32,7 @@ static inline bool LessEqualZero(T x) { } template -static T SCE(T x, T label) { +static T SigmoidCrossEntropy(T x, T label) { return (x > 0 ? x : 0.0) - x * label + std::log(1.0 + std::exp(-std::abs(x))); } @@ -42,7 +42,7 @@ static T L2Loss(T x, T y) { } template -static T SCEGrad(T x, T label) { +static T SigmoidCrossEntropyGrad(T x, T label) { return 1.0 / (1.0 + std::exp(-x)) - label; } @@ -62,7 +62,7 @@ static int GetMaskIndex(std::vector mask, int val) { template struct Box { - float x, y, w, h; + T x, y, w, h; }; template @@ -128,8 +128,8 @@ static void CalcBoxLocationLoss(T* loss, const T* input, Box gt, T th = std::log(gt.h * input_size / anchors[2 * an_idx + 1]); T scale = (2.0 - gt.w * gt.h); - loss[0] += SCE(input[box_idx], tx) * scale; - loss[0] += SCE(input[box_idx + stride], ty) * scale; + loss[0] += SigmoidCrossEntropy(input[box_idx], tx) * scale; + loss[0] += SigmoidCrossEntropy(input[box_idx + stride], ty) * scale; loss[0] += L2Loss(input[box_idx + 2 * stride], tw) * scale; loss[0] += L2Loss(input[box_idx + 3 * stride], th) * scale; } @@ -145,9 +145,10 @@ static void CalcBoxLocationLossGrad(T* input_grad, const T loss, const T* input, T th = std::log(gt.h * input_size / anchors[2 * an_idx + 1]); T scale = (2.0 - gt.w * gt.h); - input_grad[box_idx] = SCEGrad(input[box_idx], tx) * scale * loss; + input_grad[box_idx] = + SigmoidCrossEntropyGrad(input[box_idx], tx) * scale * loss; input_grad[box_idx + stride] = - SCEGrad(input[box_idx + stride], ty) * scale * loss; + SigmoidCrossEntropyGrad(input[box_idx + stride], ty) * scale * loss; input_grad[box_idx + 2 * stride] = L2LossGrad(input[box_idx + 2 * stride], tw) * scale * loss; input_grad[box_idx + 3 * stride] = @@ -160,7 +161,7 @@ static inline void CalcLabelLoss(T* loss, const T* input, const int index, const int stride) { for (int i = 0; i < class_num; i++) { T pred = input[index + i * stride]; - loss[0] += SCE(pred, (i == label) ? 1.0 : 0.0); + loss[0] += SigmoidCrossEntropy(pred, (i == label) ? 1.0 : 0.0); } } @@ -172,7 +173,7 @@ static inline void CalcLabelLossGrad(T* input_grad, const T loss, for (int i = 0; i < class_num; i++) { T pred = input[index + i * stride]; input_grad[index + i * stride] = - SCEGrad(pred, (i == label) ? 1.0 : 0.0) * loss; + SigmoidCrossEntropyGrad(pred, (i == label) ? 1.0 : 0.0) * loss; } } @@ -187,11 +188,11 @@ static inline void CalcObjnessLoss(T* loss, const T* input, const T* objness, for (int l = 0; l < w; l++) { T obj = objness[k * w + l]; if (obj > 1e-5) { - // positive sample: obj = mixup score - loss[i] += SCE(input[k * w + l], 1.0); + // positive sample: obj = 1 + loss[i] += SigmoidCrossEntropy(input[k * w + l], 1.0); } else if (obj > -0.5) { // negetive sample: obj = 0 - loss[i] += SCE(input[k * w + l], 0.0); + loss[i] += SigmoidCrossEntropy(input[k * w + l], 0.0); } } } @@ -213,9 +214,11 @@ static inline void CalcObjnessLossGrad(T* input_grad, const T* loss, for (int l = 0; l < w; l++) { T obj = objness[k * w + l]; if (obj > 1e-5) { - input_grad[k * w + l] = SCEGrad(input[k * w + l], 1.0) * loss[i]; + input_grad[k * w + l] = + SigmoidCrossEntropyGrad(input[k * w + l], 1.0) * loss[i]; } else if (obj > -0.5) { - input_grad[k * w + l] = SCEGrad(input[k * w + l], 0.0) * loss[i]; + input_grad[k * w + l] = + SigmoidCrossEntropyGrad(input[k * w + l], 0.0) * loss[i]; } } } @@ -256,7 +259,7 @@ class Yolov3LossKernel : public framework::OpKernel { auto anchor_mask = ctx.Attr>("anchor_mask"); int class_num = ctx.Attr("class_num"); float ignore_thresh = ctx.Attr("ignore_thresh"); - int downsample = ctx.Attr("downsample"); + int downsample_ratio = ctx.Attr("downsample_ratio"); const int n = input->dims()[0]; const int h = input->dims()[2]; @@ -264,7 +267,7 @@ class Yolov3LossKernel : public framework::OpKernel { const int an_num = anchors.size() / 2; const int mask_num = anchor_mask.size(); const int b = gt_box->dims()[1]; - int input_size = downsample * h; + int input_size = downsample_ratio * h; const int stride = h * w; const int an_stride = (class_num + 5) * stride; @@ -308,7 +311,7 @@ class Yolov3LossKernel : public framework::OpKernel { } } - // If best IoU is greater then ignore_thresh, + // If best IoU is bigger then ignore_thresh, // ignore the objectness loss. if (best_iou > ignore_thresh) { int obj_idx = (i * mask_num + j) * stride + k * w + l; @@ -388,7 +391,7 @@ class Yolov3LossGradKernel : public framework::OpKernel { auto anchors = ctx.Attr>("anchors"); auto anchor_mask = ctx.Attr>("anchor_mask"); int class_num = ctx.Attr("class_num"); - int downsample = ctx.Attr("downsample"); + int downsample_ratio = ctx.Attr("downsample_ratio"); const int n = input_grad->dims()[0]; const int c = input_grad->dims()[1]; @@ -396,7 +399,7 @@ class Yolov3LossGradKernel : public framework::OpKernel { const int w = input_grad->dims()[3]; const int mask_num = anchor_mask.size(); const int b = gt_match_mask->dims()[1]; - int input_size = downsample * h; + int input_size = downsample_ratio * h; const int stride = h * w; const int an_stride = (class_num + 5) * stride; diff --git a/python/paddle/fluid/layers/detection.py b/python/paddle/fluid/layers/detection.py index ea130bb279..486503c871 100644 --- a/python/paddle/fluid/layers/detection.py +++ b/python/paddle/fluid/layers/detection.py @@ -416,7 +416,7 @@ def yolov3_loss(x, anchor_mask, class_num, ignore_thresh, - downsample, + downsample_ratio, name=None): """ ${comment} @@ -434,7 +434,7 @@ def yolov3_loss(x, anchor_mask (list|tuple): ${anchor_mask_comment} class_num (int): ${class_num_comment} ignore_thresh (float): ${ignore_thresh_comment} - downsample (int): ${downsample_comment} + downsample_ratio (int): ${downsample_ratio_comment} name (string): the name of yolov3 loss Returns: @@ -456,8 +456,8 @@ def yolov3_loss(x, gtlabel = fluid.layers.data(name='gtlabel', shape=[6, 1], dtype='int32') anchors = [10, 13, 16, 30, 33, 23, 30, 61, 62, 45, 59, 119, 116, 90, 156, 198, 373, 326] anchors = [0, 1, 2] - loss = fluid.layers.yolov3_loss(x=x, gtbox=gtbox, class_num=80 - anchors=anchors, ignore_thresh=0.5) + loss = fluid.layers.yolov3_loss(x=x, gtbox=gtbox, class_num=80, anchors=anchors, + ignore_thresh=0.5, downsample_ratio=32) """ helper = LayerHelper('yolov3_loss', **locals()) @@ -491,7 +491,7 @@ def yolov3_loss(x, "anchor_mask": anchor_mask, "class_num": class_num, "ignore_thresh": ignore_thresh, - "downsample": downsample, + "downsample_ratio": downsample_ratio, } helper.append_op( -- GitLab