Skip to content

Commit 577424e

Browse files
committed
use darknet loss and trick
1 parent 042fece commit 577424e

File tree

5 files changed

+26
-114
lines changed

5 files changed

+26
-114
lines changed

paddle/fluid/API.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ paddle.fluid.layers.generate_mask_labels ArgSpec(args=['im_info', 'gt_classes',
324324
paddle.fluid.layers.iou_similarity ArgSpec(args=['x', 'y', 'name'], varargs=None, keywords=None, defaults=(None,))
325325
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))
326326
paddle.fluid.layers.polygon_box_transform ArgSpec(args=['input', 'name'], varargs=None, keywords=None, defaults=(None,))
327-
paddle.fluid.layers.yolov3_loss ArgSpec(args=['x', 'gtbox', 'gtlabel', 'gtscore', 'anchors', 'anchor_mask', 'class_num', 'ignore_thresh', 'downsample', 'use_label_smooth', 'name'], varargs=None, keywords=None, defaults=(True, None,))
327+
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,))
328328
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))
329329
paddle.fluid.layers.accuracy ArgSpec(args=['input', 'label', 'k', 'correct', 'total'], varargs=None, keywords=None, defaults=(1, None, None))
330330
paddle.fluid.layers.auc ArgSpec(args=['input', 'label', 'curve', 'num_thresholds', 'topk', 'slide_steps'], varargs=None, keywords=None, defaults=('ROC', 4095, 1, 1))

paddle/fluid/operators/yolov3_loss_op.cc

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
2727
"Input(GTBox) of Yolov3LossOp should not be null.");
2828
PADDLE_ENFORCE(ctx->HasInput("GTLabel"),
2929
"Input(GTLabel) of Yolov3LossOp should not be null.");
30-
PADDLE_ENFORCE(ctx->HasInput("GTScore"),
31-
"Input(GTScore) of Yolov3LossOp should not be null.");
3230
PADDLE_ENFORCE(ctx->HasOutput("Loss"),
3331
"Output(Loss) of Yolov3LossOp should not be null.");
3432
PADDLE_ENFORCE(
@@ -40,7 +38,6 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
4038
auto dim_x = ctx->GetInputDim("X");
4139
auto dim_gtbox = ctx->GetInputDim("GTBox");
4240
auto dim_gtlabel = ctx->GetInputDim("GTLabel");
43-
auto dim_gtscore = ctx->GetInputDim("GTScore");
4441
auto anchors = ctx->Attrs().Get<std::vector<int>>("anchors");
4542
int anchor_num = anchors.size() / 2;
4643
auto anchor_mask = ctx->Attrs().Get<std::vector<int>>("anchor_mask");
@@ -63,12 +60,6 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
6360
"Input(GTBox) and Input(GTLabel) dim[0] should be same");
6461
PADDLE_ENFORCE_EQ(dim_gtlabel[1], dim_gtbox[1],
6562
"Input(GTBox) and Input(GTLabel) dim[1] should be same");
66-
PADDLE_ENFORCE_EQ(dim_gtscore.size(), 2,
67-
"Input(GTScore) should be a 2-D tensor");
68-
PADDLE_ENFORCE_EQ(dim_gtscore[0], dim_gtbox[0],
69-
"Input(GTBox) and Input(GTScore) dim[0] should be same");
70-
PADDLE_ENFORCE_EQ(dim_gtscore[1], dim_gtbox[1],
71-
"Input(GTBox) and Input(GTScore) dim[1] should be same");
7263
PADDLE_ENFORCE_GT(anchors.size(), 0,
7364
"Attr(anchors) length should be greater then 0.");
7465
PADDLE_ENFORCE_EQ(anchors.size() % 2, 0,
@@ -121,11 +112,6 @@ class Yolov3LossOpMaker : public framework::OpProtoAndCheckerMaker {
121112
"This is a 2-D tensor with shape of [N, max_box_num], "
122113
"and each element should be an integer to indicate the "
123114
"box class id.");
124-
AddInput("GTScore",
125-
"The score of GTLabel, This is a 2-D tensor in same shape "
126-
"GTLabel, and score values should in range (0, 1). This "
127-
"input is for GTLabel score can be not 1.0 in image mixup "
128-
"augmentation.");
129115
AddOutput("Loss",
130116
"The output yolov3 loss tensor, "
131117
"This is a 1-D tensor with shape of [N]");
@@ -157,8 +143,6 @@ class Yolov3LossOpMaker : public framework::OpProtoAndCheckerMaker {
157143
AddAttr<float>("ignore_thresh",
158144
"The ignore threshold to ignore confidence loss.")
159145
.SetDefault(0.7);
160-
AddAttr<bool>("use_label_smooth", "bool,default True", "use label smooth")
161-
.SetDefault(true);
162146
AddComment(R"DOC(
163147
This operator generate yolov3 loss by given predict result and ground
164148
truth boxes.
@@ -245,7 +229,6 @@ class Yolov3LossGradMaker : public framework::SingleGradOpDescMaker {
245229
op->SetInput("X", Input("X"));
246230
op->SetInput("GTBox", Input("GTBox"));
247231
op->SetInput("GTLabel", Input("GTLabel"));
248-
op->SetInput("GTScore", Input("GTScore"));
249232
op->SetInput(framework::GradVarName("Loss"), OutputGrad("Loss"));
250233
op->SetInput("ObjectnessMask", Output("ObjectnessMask"));
251234
op->SetInput("GTMatchMask", Output("GTMatchMask"));
@@ -255,7 +238,6 @@ class Yolov3LossGradMaker : public framework::SingleGradOpDescMaker {
255238
op->SetOutput(framework::GradVarName("X"), InputGrad("X"));
256239
op->SetOutput(framework::GradVarName("GTBox"), {});
257240
op->SetOutput(framework::GradVarName("GTLabel"), {});
258-
op->SetOutput(framework::GradVarName("GTScore"), {});
259241
return std::unique_ptr<framework::OpDesc>(op);
260242
}
261243
};

paddle/fluid/operators/yolov3_loss_op.h

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ static T SCE(T x, T label) {
3636
return (x > 0 ? x : 0.0) - x * label + std::log(1.0 + std::exp(-std::abs(x)));
3737
}
3838

39-
template <typename T>
40-
static T L1Loss(T x, T y) {
41-
return std::abs(y - x);
42-
}
43-
4439
template <typename T>
4540
static T L2Loss(T x, T y) {
4641
return 0.5 * (y - x) * (y - x);
@@ -51,11 +46,6 @@ static T SCEGrad(T x, T label) {
5146
return 1.0 / (1.0 + std::exp(-x)) - label;
5247
}
5348

54-
template <typename T>
55-
static T L1LossGrad(T x, T y) {
56-
return x > y ? 1.0 : -1.0;
57-
}
58-
5949
template <typename T>
6050
static T L2LossGrad(T x, T y) {
6151
return x - y;
@@ -131,13 +121,13 @@ template <typename T>
131121
static void CalcBoxLocationLoss(T* loss, const T* input, Box<T> gt,
132122
std::vector<int> anchors, int an_idx,
133123
int box_idx, int gi, int gj, int grid_size,
134-
int input_size, int stride, T score) {
124+
int input_size, int stride) {
135125
T tx = gt.x * grid_size - gi;
136126
T ty = gt.y * grid_size - gj;
137127
T tw = std::log(gt.w * input_size / anchors[2 * an_idx]);
138128
T th = std::log(gt.h * input_size / anchors[2 * an_idx + 1]);
139129

140-
T scale = (2.0 - gt.w * gt.h) * score;
130+
T scale = (2.0 - gt.w * gt.h);
141131
loss[0] += SCE<T>(input[box_idx], tx) * scale;
142132
loss[0] += SCE<T>(input[box_idx + stride], ty) * scale;
143133
loss[0] += L2Loss<T>(input[box_idx + 2 * stride], tw) * scale;
@@ -148,14 +138,13 @@ template <typename T>
148138
static void CalcBoxLocationLossGrad(T* input_grad, const T loss, const T* input,
149139
Box<T> gt, std::vector<int> anchors,
150140
int an_idx, int box_idx, int gi, int gj,
151-
int grid_size, int input_size, int stride,
152-
T score) {
141+
int grid_size, int input_size, int stride) {
153142
T tx = gt.x * grid_size - gi;
154143
T ty = gt.y * grid_size - gj;
155144
T tw = std::log(gt.w * input_size / anchors[2 * an_idx]);
156145
T th = std::log(gt.h * input_size / anchors[2 * an_idx + 1]);
157146

158-
T scale = (2.0 - gt.w * gt.h) * score;
147+
T scale = (2.0 - gt.w * gt.h);
159148
input_grad[box_idx] = SCEGrad<T>(input[box_idx], tx) * scale * loss;
160149
input_grad[box_idx + stride] =
161150
SCEGrad<T>(input[box_idx + stride], ty) * scale * loss;
@@ -168,24 +157,22 @@ static void CalcBoxLocationLossGrad(T* input_grad, const T loss, const T* input,
168157
template <typename T>
169158
static inline void CalcLabelLoss(T* loss, const T* input, const int index,
170159
const int label, const int class_num,
171-
const int stride, const T pos, const T neg,
172-
T score) {
160+
const int stride) {
173161
for (int i = 0; i < class_num; i++) {
174162
T pred = input[index + i * stride];
175-
loss[0] += SCE<T>(pred, (i == label) ? pos : neg) * score;
163+
loss[0] += SCE<T>(pred, (i == label) ? 1.0 : 0.0);
176164
}
177165
}
178166

179167
template <typename T>
180168
static inline void CalcLabelLossGrad(T* input_grad, const T loss,
181169
const T* input, const int index,
182170
const int label, const int class_num,
183-
const int stride, const T pos, const T neg,
184-
T score) {
171+
const int stride) {
185172
for (int i = 0; i < class_num; i++) {
186173
T pred = input[index + i * stride];
187174
input_grad[index + i * stride] =
188-
SCEGrad<T>(pred, (i == label) ? pos : neg) * score * loss;
175+
SCEGrad<T>(pred, (i == label) ? 1.0 : 0.0) * loss;
189176
}
190177
}
191178

@@ -201,7 +188,7 @@ static inline void CalcObjnessLoss(T* loss, const T* input, const T* objness,
201188
T obj = objness[k * w + l];
202189
if (obj > 1e-5) {
203190
// positive sample: obj = mixup score
204-
loss[i] += SCE<T>(input[k * w + l], 1.0) * obj;
191+
loss[i] += SCE<T>(input[k * w + l], 1.0);
205192
} else if (obj > -0.5) {
206193
// negetive sample: obj = 0
207194
loss[i] += SCE<T>(input[k * w + l], 0.0);
@@ -226,8 +213,7 @@ static inline void CalcObjnessLossGrad(T* input_grad, const T* loss,
226213
for (int l = 0; l < w; l++) {
227214
T obj = objness[k * w + l];
228215
if (obj > 1e-5) {
229-
input_grad[k * w + l] =
230-
SCEGrad<T>(input[k * w + l], 1.0) * obj * loss[i];
216+
input_grad[k * w + l] = SCEGrad<T>(input[k * w + l], 1.0) * loss[i];
231217
} else if (obj > -0.5) {
232218
input_grad[k * w + l] = SCEGrad<T>(input[k * w + l], 0.0) * loss[i];
233219
}
@@ -263,7 +249,6 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
263249
auto* input = ctx.Input<Tensor>("X");
264250
auto* gt_box = ctx.Input<Tensor>("GTBox");
265251
auto* gt_label = ctx.Input<Tensor>("GTLabel");
266-
auto* gt_score = ctx.Input<Tensor>("GTScore");
267252
auto* loss = ctx.Output<Tensor>("Loss");
268253
auto* objness_mask = ctx.Output<Tensor>("ObjectnessMask");
269254
auto* gt_match_mask = ctx.Output<Tensor>("GTMatchMask");
@@ -272,7 +257,6 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
272257
int class_num = ctx.Attr<int>("class_num");
273258
float ignore_thresh = ctx.Attr<float>("ignore_thresh");
274259
int downsample = ctx.Attr<int>("downsample");
275-
bool use_label_smooth = ctx.Attr<bool>("use_label_smooth");
276260

277261
const int n = input->dims()[0];
278262
const int h = input->dims()[2];
@@ -285,17 +269,9 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
285269
const int stride = h * w;
286270
const int an_stride = (class_num + 5) * stride;
287271

288-
T label_pos = 1.0;
289-
T label_neg = 0.0;
290-
if (use_label_smooth) {
291-
label_pos = 1.0 - 1.0 / static_cast<T>(class_num);
292-
label_neg = 1.0 / static_cast<T>(class_num);
293-
}
294-
295272
const T* input_data = input->data<T>();
296273
const T* gt_box_data = gt_box->data<T>();
297274
const int* gt_label_data = gt_label->data<int>();
298-
const T* gt_score_data = gt_score->data<T>();
299275
T* loss_data = loss->mutable_data<T>({n}, ctx.GetPlace());
300276
memset(loss_data, 0, loss->numel() * sizeof(T));
301277
T* obj_mask_data =
@@ -376,20 +352,19 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
376352
int mask_idx = GetMaskIndex(anchor_mask, best_n);
377353
gt_match_mask_data[i * b + t] = mask_idx;
378354
if (mask_idx >= 0) {
379-
T score = gt_score_data[i * b + t];
380355
int box_idx = GetEntryIndex(i, mask_idx, gj * w + gi, mask_num,
381356
an_stride, stride, 0);
382357
CalcBoxLocationLoss<T>(loss_data + i, input_data, gt, anchors, best_n,
383-
box_idx, gi, gj, h, input_size, stride, score);
358+
box_idx, gi, gj, h, input_size, stride);
384359

385360
int obj_idx = (i * mask_num + mask_idx) * stride + gj * w + gi;
386-
obj_mask_data[obj_idx] = score;
361+
obj_mask_data[obj_idx] = 1.0;
387362

388363
int label = gt_label_data[i * b + t];
389364
int label_idx = GetEntryIndex(i, mask_idx, gj * w + gi, mask_num,
390365
an_stride, stride, 5);
391366
CalcLabelLoss<T>(loss_data + i, input_data, label_idx, label,
392-
class_num, stride, label_pos, label_neg, score);
367+
class_num, stride);
393368
}
394369
}
395370
}
@@ -406,7 +381,6 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
406381
auto* input = ctx.Input<Tensor>("X");
407382
auto* gt_box = ctx.Input<Tensor>("GTBox");
408383
auto* gt_label = ctx.Input<Tensor>("GTLabel");
409-
auto* gt_score = ctx.Input<Tensor>("GTScore");
410384
auto* input_grad = ctx.Output<Tensor>(framework::GradVarName("X"));
411385
auto* loss_grad = ctx.Input<Tensor>(framework::GradVarName("Loss"));
412386
auto* objness_mask = ctx.Input<Tensor>("ObjectnessMask");
@@ -415,7 +389,6 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
415389
auto anchor_mask = ctx.Attr<std::vector<int>>("anchor_mask");
416390
int class_num = ctx.Attr<int>("class_num");
417391
int downsample = ctx.Attr<int>("downsample");
418-
bool use_label_smooth = ctx.Attr<bool>("use_label_smooth");
419392

420393
const int n = input_grad->dims()[0];
421394
const int c = input_grad->dims()[1];
@@ -428,17 +401,9 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
428401
const int stride = h * w;
429402
const int an_stride = (class_num + 5) * stride;
430403

431-
T label_pos = 1.0;
432-
T label_neg = 0.0;
433-
if (use_label_smooth) {
434-
label_pos = 1.0 - 1.0 / static_cast<T>(class_num);
435-
label_neg = 1.0 / static_cast<T>(class_num);
436-
}
437-
438404
const T* input_data = input->data<T>();
439405
const T* gt_box_data = gt_box->data<T>();
440406
const int* gt_label_data = gt_label->data<int>();
441-
const T* gt_score_data = gt_score->data<T>();
442407
const T* loss_grad_data = loss_grad->data<T>();
443408
const T* obj_mask_data = objness_mask->data<T>();
444409
const int* gt_match_mask_data = gt_match_mask->data<int>();
@@ -450,24 +415,21 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
450415
for (int t = 0; t < b; t++) {
451416
int mask_idx = gt_match_mask_data[i * b + t];
452417
if (mask_idx >= 0) {
453-
T score = gt_score_data[i * b + t];
454418
Box<T> gt = GetGtBox(gt_box_data, i, b, t);
455419
int gi = static_cast<int>(gt.x * w);
456420
int gj = static_cast<int>(gt.y * h);
457421

458422
int box_idx = GetEntryIndex(i, mask_idx, gj * w + gi, mask_num,
459423
an_stride, stride, 0);
460-
CalcBoxLocationLossGrad<T>(input_grad_data, loss_grad_data[i],
461-
input_data, gt, anchors,
462-
anchor_mask[mask_idx], box_idx, gi, gj, h,
463-
input_size, stride, score);
424+
CalcBoxLocationLossGrad<T>(
425+
input_grad_data, loss_grad_data[i], input_data, gt, anchors,
426+
anchor_mask[mask_idx], box_idx, gi, gj, h, input_size, stride);
464427

465428
int label = gt_label_data[i * b + t];
466429
int label_idx = GetEntryIndex(i, mask_idx, gj * w + gi, mask_num,
467430
an_stride, stride, 5);
468431
CalcLabelLossGrad<T>(input_grad_data, loss_grad_data[i], input_data,
469-
label_idx, label, class_num, stride, label_pos,
470-
label_neg, score);
432+
label_idx, label, class_num, stride);
471433
}
472434
}
473435
}

python/paddle/fluid/layers/detection.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,11 @@ def polygon_box_transform(input, name=None):
412412
def yolov3_loss(x,
413413
gtbox,
414414
gtlabel,
415-
gtscore,
416415
anchors,
417416
anchor_mask,
418417
class_num,
419418
ignore_thresh,
420419
downsample,
421-
use_label_smooth=True,
422420
name=None):
423421
"""
424422
${comment}
@@ -432,14 +430,11 @@ def yolov3_loss(x,
432430
an image.
433431
gtlabel (Variable): class id of ground truth boxes, shoud be in shape
434432
of [N, B].
435-
gtscore (Variable): score of gtlabel, should be in same shape with gtlabel
436-
and score value in range (0, 1).
437433
anchors (list|tuple): ${anchors_comment}
438434
anchor_mask (list|tuple): ${anchor_mask_comment}
439435
class_num (int): ${class_num_comment}
440436
ignore_thresh (float): ${ignore_thresh_comment}
441437
downsample (int): ${downsample_comment}
442-
use_label_smooth(bool): ${use_label_smooth_comment}
443438
name (string): the name of yolov3 loss
444439
445440
Returns:
@@ -449,11 +444,9 @@ def yolov3_loss(x,
449444
TypeError: Input x of yolov3_loss must be Variable
450445
TypeError: Input gtbox of yolov3_loss must be Variable"
451446
TypeError: Input gtlabel of yolov3_loss must be Variable"
452-
TypeError: Input gtscore of yolov3_loss must be Variable"
453447
TypeError: Attr anchors of yolov3_loss must be list or tuple
454448
TypeError: Attr class_num of yolov3_loss must be an integer
455449
TypeError: Attr ignore_thresh of yolov3_loss must be a float number
456-
TypeError: Attr use_label_smooth of yolov3_loss must be a bool value
457450
458451
Examples:
459452
.. code-block:: python
@@ -474,16 +467,12 @@ def yolov3_loss(x,
474467
raise TypeError("Input gtbox of yolov3_loss must be Variable")
475468
if not isinstance(gtlabel, Variable):
476469
raise TypeError("Input gtlabel of yolov3_loss must be Variable")
477-
if not isinstance(gtscore, Variable):
478-
raise TypeError("Input gtscore of yolov3_loss must be Variable")
479470
if not isinstance(anchors, list) and not isinstance(anchors, tuple):
480471
raise TypeError("Attr anchors of yolov3_loss must be list or tuple")
481472
if not isinstance(anchor_mask, list) and not isinstance(anchor_mask, tuple):
482473
raise TypeError("Attr anchor_mask of yolov3_loss must be list or tuple")
483474
if not isinstance(class_num, int):
484475
raise TypeError("Attr class_num of yolov3_loss must be an integer")
485-
if not isinstance(use_label_smooth, bool):
486-
raise TypeError("Attr ues_label_smooth of yolov3 must be a bool value")
487476
if not isinstance(ignore_thresh, float):
488477
raise TypeError(
489478
"Attr ignore_thresh of yolov3_loss must be a float number")
@@ -503,7 +492,6 @@ def yolov3_loss(x,
503492
"class_num": class_num,
504493
"ignore_thresh": ignore_thresh,
505494
"downsample": downsample,
506-
"use_label_smooth": use_label_smooth
507495
}
508496

509497
helper.append_op(
@@ -512,7 +500,6 @@ def yolov3_loss(x,
512500
"X": x,
513501
"GTBox": gtbox,
514502
"GTLabel": gtlabel,
515-
"GTScore": gtscore
516503
},
517504
outputs={
518505
'Loss': loss,

0 commit comments

Comments
 (0)