Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
77c1328f
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
77c1328f
编写于
11月 10, 2018
作者:
D
dengkaipeng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add CPU kernel forward
上级
5d0b568e
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
127 addition
and
148 deletion
+127
-148
paddle/fluid/operators/yolov3_loss_op.cc
paddle/fluid/operators/yolov3_loss_op.cc
+36
-24
paddle/fluid/operators/yolov3_loss_op.h
paddle/fluid/operators/yolov3_loss_op.h
+91
-124
未找到文件。
paddle/fluid/operators/yolov3_loss_op.cc
浏览文件 @
77c1328f
...
...
@@ -27,18 +27,8 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
"Input(X) of Yolov3LossOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"GTBox"
),
"Input(GTBox) of Yolov3LossOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"Out"
),
"Output(Out) of Yolov3LossOp should not be null."
);
// PADDLE_ENFORCE(ctx->HasAttr("img_height"),
// "Attr(img_height) of Yolov3LossOp should not be null. ");
// PADDLE_ENFORCE(ctx->HasAttr("anchors"),
// "Attr(anchor) of Yolov3LossOp should not be null.")
// PADDLE_ENFORCE(ctx->HasAttr("class_num"),
// "Attr(class_num) of Yolov3LossOp should not be null.");
// PADDLE_ENFORCE(ctx->HasAttr(
// "ignore_thresh",
// "Attr(ignore_thresh) of Yolov3LossOp should not be null."));
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"Loss"
),
"Output(Loss) of Yolov3LossOp should not be null."
);
auto
dim_x
=
ctx
->
GetInputDim
(
"X"
);
auto
dim_gt
=
ctx
->
GetInputDim
(
"GTBox"
);
...
...
@@ -46,6 +36,14 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
auto
anchors
=
ctx
->
Attrs
().
Get
<
std
::
vector
<
int
>>
(
"anchors"
);
auto
box_num
=
ctx
->
Attrs
().
Get
<
int
>
(
"box_num"
);
auto
class_num
=
ctx
->
Attrs
().
Get
<
int
>
(
"class_num"
);
PADDLE_ENFORCE_EQ
(
dim_x
.
size
(),
4
,
"Input(X) should be a 4-D tensor."
);
PADDLE_ENFORCE_EQ
(
dim_x
[
2
],
dim_x
[
3
],
"Input(X) dim[3] and dim[4] should be euqal."
);
PADDLE_ENFORCE_EQ
(
dim_x
[
1
],
anchors
.
size
()
/
2
*
(
5
+
class_num
),
"Input(X) dim[1] should be equal to (anchor_number * (5 "
"+ class_num))."
);
PADDLE_ENFORCE_EQ
(
dim_gt
.
size
(),
3
,
"Input(GTBox) should be a 3-D tensor"
);
PADDLE_ENFORCE_EQ
(
dim_gt
[
2
],
5
,
"Input(GTBox) dim[2] should be 5"
);
PADDLE_ENFORCE_GT
(
img_height
,
0
,
"Attr(img_height) value should be greater then 0"
);
PADDLE_ENFORCE_GT
(
anchors
.
size
(),
0
,
...
...
@@ -56,14 +54,9 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
"Attr(box_num) should be an integer greater then 0."
);
PADDLE_ENFORCE_GT
(
class_num
,
0
,
"Attr(class_num) should be an integer greater then 0."
);
PADDLE_ENFORCE_EQ
(
dim_x
[
1
],
anchors
.
size
()
/
2
*
(
5
+
class_num
),
"Input(X) dim[1] should be equal to (anchor_number * (5 "
"+ class_num))."
);
PADDLE_ENFORCE_EQ
(
dim_gt
.
size
(),
3
,
"Input(GTBox) should be a 3-D tensor"
);
PADDLE_ENFORCE_EQ
(
dim_gt
[
2
],
5
,
"Input(GTBox) dim[2] should be 5"
);
std
::
vector
<
int64_t
>
dim_out
({
dim_x
[
0
],
1
});
ctx
->
SetOutputDim
(
"
Out
"
,
framework
::
make_ddim
(
dim_out
));
std
::
vector
<
int64_t
>
dim_out
({
1
});
ctx
->
SetOutputDim
(
"
Loss
"
,
framework
::
make_ddim
(
dim_out
));
}
protected:
...
...
@@ -80,12 +73,31 @@ class Yolov3LossOpMaker : public framework::OpProtoAndCheckerMaker {
AddInput
(
"X"
,
"The input tensor of bilinear interpolation, "
"This is a 4-D tensor with shape of [N, C, H, W]"
);
AddOutput
(
"Out"
,
"The output yolo loss tensor, "
"This is a 2-D tensor with shape of [N, 1]"
);
AddInput
(
"GTBox"
,
"The input tensor of ground truth boxes, "
"This is a 3-D tensor with shape of [N, max_box_num, 5 + class_num], "
"max_box_num is the max number of boxes in each image, "
"class_num is the number of classes in data set. "
"In the third dimention, stores x, y, w, h, confidence, classes "
"one-hot key. "
"x, y is the center cordinate of boxes and w, h is the width and "
"height, "
"and all of them should be divided by input image height to scale to "
"[0, 1]."
);
AddOutput
(
"Loss"
,
"The output yolov3 loss tensor, "
"This is a 1-D tensor with shape of [1]"
);
AddAttr
<
int
>
(
"box_num"
,
"The number of boxes generated in each grid."
);
AddAttr
<
int
>
(
"class_num"
,
"The number of classes to predict."
);
AddAttr
<
std
::
vector
<
int
>>
(
"anchors"
,
"The anchor width and height, "
"it will be parsed pair by pair."
);
AddAttr
<
int
>
(
"img_height"
,
"The input image height after crop of yolov3 network."
);
AddAttr
<
float
>
(
"ignore_thresh"
,
"The ignore threshold to ignore confidence loss."
);
AddComment
(
R"DOC(
This operator generate yolov3 loss by given predict result and ground
truth boxes.
...
...
@@ -100,8 +112,8 @@ class Yolov3LossOpGrad : public framework::OperatorWithKernel {
protected:
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"X"
),
"Input(X) should not be null"
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
framework
::
GradVarName
(
"
Out
"
)),
"Input(
Out
@GRAD) should not be null"
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
framework
::
GradVarName
(
"
Loss
"
)),
"Input(
Loss
@GRAD) should not be null"
);
auto
dim_x
=
ctx
->
GetInputDim
(
"X"
);
if
(
ctx
->
HasOutput
(
framework
::
GradVarName
(
"X"
)))
{
ctx
->
SetOutputDim
(
framework
::
GradVarName
(
"X"
),
dim_x
);
...
...
paddle/fluid/operators/yolov3_loss_op.h
浏览文件 @
77c1328f
...
...
@@ -44,8 +44,16 @@ static inline T CalcMSEWithMask(const Tensor& x, const Tensor& y,
auto
x_t
=
EigenVector
<
T
>::
Flatten
(
x
);
auto
y_t
=
EigenVector
<
T
>::
Flatten
(
y
);
auto
mask_t
=
EigenVector
<
T
>::
Flatten
(
mask
);
auto
result
=
((
x_t
-
y_t
)
*
mask_t
).
pow
(
2
).
sum
().
eval
();
return
result
(
0
);
T
error_sum
=
0.0
;
T
points
=
0.0
;
for
(
int
i
=
0
;
i
<
x_t
.
dimensions
()[
0
];
i
++
)
{
if
(
mask_t
(
i
))
{
error_sum
+=
pow
(
x_t
(
i
)
-
y_t
(
i
),
2
);
points
+=
1
;
}
}
return
(
error_sum
/
points
);
}
template
<
typename
T
>
...
...
@@ -55,27 +63,24 @@ static inline T CalcBCEWithMask(const Tensor& x, const Tensor& y,
auto
y_t
=
EigenVector
<
T
>::
Flatten
(
y
);
auto
mask_t
=
EigenVector
<
T
>::
Flatten
(
mask
);
auto
result
=
((
y_t
*
(
x_t
.
log
())
+
(
1.0
-
y_t
)
*
((
1.0
-
x_t
).
log
()))
*
mask_t
)
.
sum
()
.
eval
();
return
result
;
}
template
<
typename
T
>
static
inline
T
CalcCEWithMask
(
const
Tensor
&
x
,
const
Tensor
&
y
,
const
Tensor
&
mask
)
{
auto
x_t
=
EigenVector
<
T
>::
Flatten
(
x
);
auto
y_t
=
EigenVector
<
T
>::
Flatten
(
y
);
auto
mask_t
=
EigenVector
<
T
>::
Flatten
(
mask
);
T
error_sum
=
0.0
;
T
points
=
0.0
;
for
(
int
i
=
0
;
i
<
x_t
.
dimensions
()[
0
];
i
++
)
{
if
(
mask_t
(
i
))
{
error_sum
+=
-
1.0
*
(
y_t
(
i
)
*
log
(
x_t
(
i
))
+
(
1.0
-
y_t
(
i
))
*
log
(
1.0
-
x_t
(
i
)));
points
+=
1
;
}
}
return
(
error_sum
/
points
);
}
template
<
typename
T
>
static
void
CalcPredResult
(
const
Tensor
&
input
,
Tensor
*
pred_
boxe
s
,
Tensor
*
pred_c
onfs
,
Tensor
*
pred_classes
,
Tensor
*
pred_
x
,
Tensor
*
pred_y
,
Tensor
*
pred_w
,
Tensor
*
pred_h
,
std
::
vector
<
int
>
anchors
,
const
int
class_num
,
const
int
stride
)
{
static
void
CalcPredResult
(
const
Tensor
&
input
,
Tensor
*
pred_
conf
s
,
Tensor
*
pred_c
lasses
,
Tensor
*
pred_x
,
Tensor
*
pred_y
,
Tensor
*
pred_
w
,
Tensor
*
pred_h
,
std
::
vector
<
int
>
anchors
,
const
int
class_num
,
const
int
stride
)
{
const
int
n
=
input
.
dims
()[
0
];
const
int
c
=
input
.
dims
()[
1
];
const
int
h
=
input
.
dims
()[
2
];
...
...
@@ -84,7 +89,7 @@ static void CalcPredResult(const Tensor& input, Tensor* pred_boxes,
const
int
box_attr_num
=
5
+
class_num
;
auto
input_t
=
EigenTensor
<
T
,
4
>::
From
(
input
);
auto
pred_boxes_t
=
EigenTensor
<
T
,
5
>::
From
(
*
pred_boxes
);
//
auto pred_boxes_t = EigenTensor<T, 5>::From(*pred_boxes);
auto
pred_confs_t
=
EigenTensor
<
T
,
4
>::
From
(
*
pred_confs
);
auto
pred_classes_t
=
EigenTensor
<
T
,
5
>::
From
(
*
pred_classes
);
auto
pred_x_t
=
EigenTensor
<
T
,
4
>::
From
(
*
pred_x
);
...
...
@@ -104,16 +109,16 @@ static void CalcPredResult(const Tensor& input, Tensor* pred_boxes,
pred_y_t
(
i
,
an_idx
,
j
,
k
)
=
sigmod
(
input_t
(
i
,
box_attr_num
*
an_idx
+
1
,
j
,
k
));
pred_w_t
(
i
,
an_idx
,
j
,
k
)
=
sigmod
(
input_t
(
i
,
box_attr_num
*
an_idx
+
2
,
j
,
k
)
);
input_t
(
i
,
box_attr_num
*
an_idx
+
2
,
j
,
k
);
pred_h_t
(
i
,
an_idx
,
j
,
k
)
=
sigmod
(
input_t
(
i
,
box_attr_num
*
an_idx
+
3
,
j
,
k
)
);
input_t
(
i
,
box_attr_num
*
an_idx
+
3
,
j
,
k
);
pred_boxes_t
(
i
,
an_idx
,
j
,
k
,
0
)
=
pred_x_t
(
i
,
an_idx
,
j
,
k
)
+
k
;
pred_boxes_t
(
i
,
an_idx
,
j
,
k
,
1
)
=
pred_y_t
(
i
,
an_idx
,
j
,
k
)
+
j
;
pred_boxes_t
(
i
,
an_idx
,
j
,
k
,
2
)
=
exp
(
pred_w_t
(
i
,
an_idx
,
j
,
k
))
*
an_w
;
pred_boxes_t
(
i
,
an_idx
,
j
,
k
,
3
)
=
exp
(
pred_h_t
(
i
,
an_idx
,
j
,
k
))
*
an_h
;
//
pred_boxes_t(i, an_idx, j, k, 0) = pred_x_t(i, an_idx, j, k) + k;
//
pred_boxes_t(i, an_idx, j, k, 1) = pred_y_t(i, an_idx, j, k) + j;
//
pred_boxes_t(i, an_idx, j, k, 2) =
//
exp(pred_w_t(i, an_idx, j, k)) * an_w;
//
pred_boxes_t(i, an_idx, j, k, 3) =
//
exp(pred_h_t(i, an_idx, j, k)) * an_h;
pred_confs_t
(
i
,
an_idx
,
j
,
k
)
=
sigmod
(
input_t
(
i
,
box_attr_num
*
an_idx
+
4
,
j
,
k
));
...
...
@@ -129,40 +134,27 @@ static void CalcPredResult(const Tensor& input, Tensor* pred_boxes,
}
template
<
typename
T
>
static
T
CalcBoxIoU
(
std
::
vector
<
T
>
box1
,
std
::
vector
<
T
>
box2
,
bool
center_mode
)
{
T
b1_x1
,
b1_x2
,
b1_y1
,
b1_y2
;
T
b2_x1
,
b2_x2
,
b2_y1
,
b2_y2
;
if
(
center_mode
)
{
b1_x1
=
box1
[
0
]
-
box1
[
2
]
/
2
;
b1_x2
=
box1
[
0
]
+
box1
[
2
]
/
2
;
b1_y1
=
box1
[
1
]
-
box1
[
3
]
/
2
;
b1_y2
=
box1
[
1
]
+
box1
[
3
]
/
2
;
b2_x1
=
box2
[
0
]
-
box2
[
2
]
/
2
;
b2_x2
=
box2
[
0
]
+
box2
[
2
]
/
2
;
b2_y1
=
box2
[
1
]
-
box2
[
3
]
/
2
;
b2_y2
=
box2
[
1
]
+
box2
[
3
]
/
2
;
}
else
{
b1_x1
=
box1
[
0
];
b1_x2
=
box1
[
1
];
b1_y1
=
box1
[
2
];
b1_y2
=
box1
[
3
];
b2_x1
=
box2
[
0
];
b2_x2
=
box2
[
0
];
b2_y1
=
box2
[
1
];
b2_y2
=
box2
[
1
];
}
T
b1_area
=
(
b1_x2
-
b1_x1
+
1.0
)
*
(
b1_y2
-
b1_y1
+
1.0
);
T
b2_area
=
(
b2_x2
-
b2_x1
+
1.0
)
*
(
b2_y2
-
b2_y1
+
1.0
);
static
T
CalcBoxIoU
(
std
::
vector
<
T
>
box1
,
std
::
vector
<
T
>
box2
)
{
T
b1_x1
=
box1
[
0
]
-
box1
[
2
]
/
2
;
T
b1_x2
=
box1
[
0
]
+
box1
[
2
]
/
2
;
T
b1_y1
=
box1
[
1
]
-
box1
[
3
]
/
2
;
T
b1_y2
=
box1
[
1
]
+
box1
[
3
]
/
2
;
T
b2_x1
=
box2
[
0
]
-
box2
[
2
]
/
2
;
T
b2_x2
=
box2
[
0
]
+
box2
[
2
]
/
2
;
T
b2_y1
=
box2
[
1
]
-
box2
[
3
]
/
2
;
T
b2_y2
=
box2
[
1
]
+
box2
[
3
]
/
2
;
T
b1_area
=
(
b1_x2
-
b1_x1
)
*
(
b1_y2
-
b1_y1
);
T
b2_area
=
(
b2_x2
-
b2_x1
)
*
(
b2_y2
-
b2_y1
);
T
inter_rect_x1
=
std
::
max
(
b1_x1
,
b2_x1
);
T
inter_rect_y1
=
std
::
max
(
b1_y1
,
b2_y1
);
T
inter_rect_x2
=
std
::
min
(
b1_x2
,
b2_x2
);
T
inter_rect_y2
=
std
::
min
(
b1_y2
,
b2_y2
);
T
inter_area
=
std
::
max
(
inter_rect_x2
-
inter_rect_x1
+
1.0
,
0.0
)
*
std
::
max
(
inter_rect_y2
-
inter_rect_y1
+
1.0
,
0.0
);
T
inter_area
=
std
::
max
(
inter_rect_x2
-
inter_rect_x1
,
static_cast
<
T
>
(
0.0
)
)
*
std
::
max
(
inter_rect_y2
-
inter_rect_y1
,
static_cast
<
T
>
(
0.0
)
);
return
inter_area
/
(
b1_area
+
b2_area
-
inter_area
+
1e-16
);
return
inter_area
/
(
b1_area
+
b2_area
-
inter_area
);
}
template
<
typename
T
>
...
...
@@ -181,23 +173,18 @@ static inline int GetPredLabel(const Tensor& pred_classes, int n,
}
template
<
typename
T
>
static
void
CalcPredBoxWithGTBox
(
const
Tensor
&
pred_boxes
,
const
Tensor
&
pred_confs
,
const
Tensor
&
pred_classes
,
const
Tensor
&
gt_boxes
,
std
::
vector
<
int
>
anchors
,
const
float
ignore_thresh
,
const
int
img_height
,
int
*
gt_num
,
int
*
correct_num
,
Tensor
*
mask_true
,
Tensor
*
mask_false
,
Tensor
*
tx
,
Tensor
*
ty
,
Tensor
*
tw
,
Tensor
*
th
,
Tensor
*
tconf
,
Tensor
*
tclass
)
{
static
void
PrePorcessGTBox
(
const
Tensor
&
gt_boxes
,
const
float
ignore_thresh
,
std
::
vector
<
int
>
anchors
,
const
int
img_height
,
const
int
grid_size
,
Tensor
*
obj_mask
,
Tensor
*
noobj_mask
,
Tensor
*
tx
,
Tensor
*
ty
,
Tensor
*
tw
,
Tensor
*
th
,
Tensor
*
tconf
,
Tensor
*
tclass
)
{
const
int
n
=
gt_boxes
.
dims
()[
0
];
const
int
b
=
gt_boxes
.
dims
()[
1
];
const
int
grid_size
=
pred_boxes
.
dims
()[
1
];
const
int
anchor_num
=
anchors
.
size
()
/
2
;
auto
pred_boxes_t
=
EigenTensor
<
T
,
5
>::
From
(
pred_boxes
);
auto
pred_confs_t
=
EigenTensor
<
T
,
4
>::
From
(
pred_confs
);
auto
pred_classes_t
=
EigenTensor
<
T
,
5
>::
From
(
pred_classes
);
auto
gt_boxes_t
=
EigenTensor
<
T
,
3
>::
From
(
gt_boxes
);
auto
mask_true_t
=
EigenTensor
<
int
,
4
>::
From
(
*
mask_true
).
setConstant
(
0.
0
);
auto
mask_false_t
=
EigenTensor
<
int
,
4
>::
From
(
*
mask_false
).
setConstant
(
1.0
);
auto
obj_mask_t
=
EigenTensor
<
int
,
4
>::
From
(
*
obj_mask
).
setConstant
(
0
);
auto
noobj_mask_t
=
EigenTensor
<
int
,
4
>::
From
(
*
noobj_mask
).
setConstant
(
1
);
auto
tx_t
=
EigenTensor
<
T
,
4
>::
From
(
*
tx
).
setConstant
(
0.0
);
auto
ty_t
=
EigenTensor
<
T
,
4
>::
From
(
*
ty
).
setConstant
(
0.0
);
auto
tw_t
=
EigenTensor
<
T
,
4
>::
From
(
*
tw
).
setConstant
(
0.0
);
...
...
@@ -205,8 +192,6 @@ static void CalcPredBoxWithGTBox(
auto
tconf_t
=
EigenTensor
<
T
,
4
>::
From
(
*
tconf
).
setConstant
(
0.0
);
auto
tclass_t
=
EigenTensor
<
T
,
5
>::
From
(
*
tclass
).
setConstant
(
0.0
);
*
gt_num
=
0
;
*
correct_num
=
0
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
j
=
0
;
j
<
b
;
j
++
)
{
if
(
isZero
(
gt_boxes_t
(
i
,
j
,
0
))
&&
isZero
(
gt_boxes_t
(
i
,
j
,
1
))
&&
...
...
@@ -214,12 +199,11 @@ static void CalcPredBoxWithGTBox(
continue
;
}
*
(
gt_num
)
++
;
int
gt_label
=
gt_boxes_t
(
i
,
j
,
0
);
T
gx
=
gt_boxes_t
(
i
,
j
,
1
);
T
gy
=
gt_boxes_t
(
i
,
j
,
2
);
T
gw
=
gt_boxes_t
(
i
,
j
,
3
);
T
gh
=
gt_boxes_t
(
i
,
j
,
4
);
T
gx
=
gt_boxes_t
(
i
,
j
,
1
)
*
grid_size
;
T
gy
=
gt_boxes_t
(
i
,
j
,
2
)
*
grid_size
;
T
gw
=
gt_boxes_t
(
i
,
j
,
3
)
*
grid_size
;
T
gh
=
gt_boxes_t
(
i
,
j
,
4
)
*
grid_size
;
int
gi
=
static_cast
<
int
>
(
gx
);
int
gj
=
static_cast
<
int
>
(
gy
);
...
...
@@ -230,43 +214,26 @@ static void CalcPredBoxWithGTBox(
for
(
int
an_idx
=
0
;
an_idx
<
anchor_num
;
an_idx
++
)
{
std
::
vector
<
T
>
anchor_shape
({
0
,
0
,
static_cast
<
T
>
(
anchors
[
2
*
an_idx
]),
static_cast
<
T
>
(
anchors
[
2
*
an_idx
+
1
])});
iou
=
CalcBoxIoU
(
gt_box
,
anchor_shape
,
fals
e
);
iou
=
CalcBoxIoU
<
T
>
(
gt_box
,
anchor_shap
e
);
if
(
iou
>
max_iou
)
{
max_iou
=
iou
;
best_an_index
=
an_idx
;
}
if
(
iou
>
ignore_thresh
)
{
mask_false
_t
(
b
,
an_idx
,
gj
,
gi
)
=
0
;
noobj_mask
_t
(
b
,
an_idx
,
gj
,
gi
)
=
0
;
}
}
mask_true
_t
(
b
,
best_an_index
,
gj
,
gi
)
=
1
;
mask_false
_t
(
b
,
best_an_index
,
gj
,
gi
)
=
1
;
obj_mask
_t
(
b
,
best_an_index
,
gj
,
gi
)
=
1
;
noobj_mask
_t
(
b
,
best_an_index
,
gj
,
gi
)
=
1
;
tx_t
(
i
,
best_an_index
,
gj
,
gi
)
=
gx
-
gi
;
ty_t
(
i
,
best_an_index
,
gj
,
gi
)
=
gy
-
gj
;
tw_t
(
i
,
best_an_index
,
gj
,
gi
)
=
log
(
gw
/
anchors
[
2
*
best_an_index
]
+
1e-16
);
th_t
(
i
,
best_an_index
,
gj
,
gi
)
=
log
(
gh
/
anchors
[
2
*
best_an_index
+
1
]
+
1e-16
);
tw_t
(
i
,
best_an_index
,
gj
,
gi
)
=
log
(
gw
/
anchors
[
2
*
best_an_index
]);
th_t
(
i
,
best_an_index
,
gj
,
gi
)
=
log
(
gh
/
anchors
[
2
*
best_an_index
+
1
]);
tclass_t
(
b
,
best_an_index
,
gj
,
gi
,
gt_label
)
=
1
;
tconf_t
(
b
,
best_an_index
,
gj
,
gi
)
=
1
;
std
::
vector
<
T
>
pred_box
({
pred_boxes_t
(
i
,
best_an_index
,
gj
,
gi
,
0
),
pred_boxes_t
(
i
,
best_an_index
,
gj
,
gi
,
1
),
pred_boxes_t
(
i
,
best_an_index
,
gj
,
gi
,
2
),
pred_boxes_t
(
i
,
best_an_index
,
gj
,
gi
,
3
),
});
gt_box
[
0
]
=
gx
;
gt_box
[
1
]
=
gy
;
iou
=
CalcBoxIoU
(
gt_box
,
pred_box
,
true
);
int
pred_label
=
GetPredLabel
<
T
>
(
pred_classes
,
i
,
best_an_index
,
gj
,
gi
);
T
score
=
pred_confs_t
(
i
,
best_an_index
,
gj
,
gi
);
if
(
iou
>
0.5
&&
pred_label
==
gt_label
&&
score
>
0.5
)
{
(
*
correct_num
)
++
;
}
}
}
mask_false_t
=
mask_true_t
-
mask_false
_t
;
noobj_mask_t
=
noobj_mask_t
-
obj_mask
_t
;
}
template
<
typename
DeviceContext
,
typename
T
>
...
...
@@ -275,7 +242,7 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
void
Compute
(
const
framework
::
ExecutionContext
&
ctx
)
const
override
{
auto
*
input
=
ctx
.
Input
<
Tensor
>
(
"X"
);
auto
*
gt_boxes
=
ctx
.
Input
<
Tensor
>
(
"GTBox"
);
auto
*
output
=
ctx
.
Output
<
Tensor
>
(
"Out
"
);
auto
*
loss
=
ctx
.
Output
<
Tensor
>
(
"Loss
"
);
int
img_height
=
ctx
.
Attr
<
int
>
(
"img_height"
);
auto
anchors
=
ctx
.
Attr
<
std
::
vector
<
int
>>
(
"anchors"
);
int
class_num
=
ctx
.
Attr
<
int
>
(
"class_num"
);
...
...
@@ -286,44 +253,44 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
const
int
h
=
input
->
dims
()[
2
];
const
int
w
=
input
->
dims
()[
3
];
const
int
an_num
=
anchors
.
size
()
/
2
;
const
float
stride
=
static_cast
<
float
>
(
img_height
)
/
h
;
const
T
stride
=
static_cast
<
T
>
(
img_height
)
/
h
;
Tensor
pred_x
,
pred_y
,
pred_w
,
pred_h
;
Tensor
pred_
boxes
,
pred_
confs
,
pred_classes
;
Tensor
pred_confs
,
pred_classes
;
pred_x
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_y
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_w
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_h
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_boxes
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
4
},
ctx
.
GetPlace
());
pred_confs
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_classes
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
class_num
},
ctx
.
GetPlace
());
CalcPredResult
<
T
>
(
*
input
,
&
pred_
boxes
,
&
pred_confs
,
&
pred_classes
,
&
pred_x
,
&
pred_
y
,
&
pred_
w
,
&
pred_h
,
anchors
,
class_num
,
stride
);
CalcPredResult
<
T
>
(
*
input
,
&
pred_
confs
,
&
pred_classes
,
&
pred_x
,
&
pred_y
,
&
pred_w
,
&
pred_h
,
anchors
,
class_num
,
stride
);
Tensor
mask_true
,
mask_false
;
Tensor
obj_mask
,
noobj_mask
;
Tensor
tx
,
ty
,
tw
,
th
,
tconf
,
tclass
;
mask_true
.
mutable_data
<
int
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
mask_false
.
mutable_data
<
int
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
obj_mask
.
mutable_data
<
int
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
noobj_mask
.
mutable_data
<
int
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
tx
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
ty
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
tw
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
th
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
tconf
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
tclass
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
class_num
},
ctx
.
GetPlace
());
int
gt_num
=
0
;
int
correct_num
=
0
;
CalcPredBoxWithGTBox
<
T
>
(
pred_boxes
,
pred_confs
,
pred_classes
,
*
gt_boxes
,
anchors
,
ignore_thresh
,
img_height
,
&
gt_num
,
&
correct_num
,
&
mask_true
,
&
mask_false
,
&
tx
,
&
ty
,
&
tw
,
&
th
,
&
tconf
,
&
tclass
);
T
loss_x
=
CalcMSEWithMask
<
T
>
(
pred_x
,
tx
,
mask_true
);
T
loss_y
=
CalcMSEWithMask
<
T
>
(
pred_y
,
ty
,
mask_true
);
T
loss_w
=
CalcMSEWithMask
<
T
>
(
pred_w
,
tw
,
mask_true
);
T
loss_h
=
CalcMSEWithMask
<
T
>
(
pred_h
,
th
,
mask_true
);
T
loss_conf_true
=
CalcBCEWithMask
<
T
>
(
pred_confs
,
tconf
,
mask_true
);
T
loss_conf_false
=
CalcBCEWithMask
<
T
>
(
pred_confs
,
tconf
,
mask_false
);
// T loss_class = CalcCEWithMask<T>()
PrePorcessGTBox
<
T
>
(
*
gt_boxes
,
ignore_thresh
,
anchors
,
img_height
,
h
,
&
obj_mask
,
&
noobj_mask
,
&
tx
,
&
ty
,
&
tw
,
&
th
,
&
tconf
,
&
tclass
);
T
loss_x
=
CalcMSEWithMask
<
T
>
(
pred_x
,
tx
,
obj_mask
);
T
loss_y
=
CalcMSEWithMask
<
T
>
(
pred_y
,
ty
,
obj_mask
);
T
loss_w
=
CalcMSEWithMask
<
T
>
(
pred_w
,
tw
,
obj_mask
);
T
loss_h
=
CalcMSEWithMask
<
T
>
(
pred_h
,
th
,
obj_mask
);
T
loss_conf_true
=
CalcBCEWithMask
<
T
>
(
pred_confs
,
tconf
,
obj_mask
);
T
loss_conf_false
=
CalcBCEWithMask
<
T
>
(
pred_confs
,
tconf
,
noobj_mask
);
T
loss_class
=
CalcBCEWithMask
<
T
>
(
pred_classes
,
tclass
,
obj_mask
);
auto
*
loss_data
=
loss
->
mutable_data
<
T
>
({
1
},
ctx
.
GetPlace
());
loss_data
[
0
]
=
loss_x
+
loss_y
+
loss_w
+
loss_h
+
loss_conf_true
+
loss_conf_false
+
loss_class
;
}
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录