Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleDetection
提交
3841983a
P
PaddleDetection
项目概览
PaddlePaddle
/
PaddleDetection
大约 1 年 前同步成功
通知
695
Star
11112
Fork
2696
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
184
列表
看板
标记
里程碑
合并请求
40
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleDetection
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
184
Issue
184
列表
看板
标记
里程碑
合并请求
40
合并请求
40
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3841983a
编写于
12月 07, 2018
作者:
D
dengkaipeng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix division error in mean process. test=develop
上级
192d2938
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
166 addition
and
172 deletion
+166
-172
paddle/fluid/operators/yolov3_loss_op.cc
paddle/fluid/operators/yolov3_loss_op.cc
+2
-2
paddle/fluid/operators/yolov3_loss_op.h
paddle/fluid/operators/yolov3_loss_op.h
+122
-141
python/paddle/fluid/tests/unittests/op_test.py
python/paddle/fluid/tests/unittests/op_test.py
+2
-0
python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py
python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py
+40
-29
未找到文件。
paddle/fluid/operators/yolov3_loss_op.cc
浏览文件 @
3841983a
...
...
@@ -57,7 +57,7 @@ class Yolov3LossOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_GT
(
class_num
,
0
,
"Attr(class_num) should be an integer greater then 0."
);
std
::
vector
<
int64_t
>
dim_out
({
1
});
std
::
vector
<
int64_t
>
dim_out
({
dim_x
[
0
]
});
ctx
->
SetOutputDim
(
"Loss"
,
framework
::
make_ddim
(
dim_out
));
}
...
...
@@ -93,7 +93,7 @@ class Yolov3LossOpMaker : public framework::OpProtoAndCheckerMaker {
"box class id."
);
AddOutput
(
"Loss"
,
"The output yolov3 loss tensor, "
"This is a 1-D tensor with shape of [
1
]"
);
"This is a 1-D tensor with shape of [
N
]"
);
AddAttr
<
int
>
(
"class_num"
,
"The number of classes to predict."
);
AddAttr
<
std
::
vector
<
int
>>
(
"anchors"
,
...
...
paddle/fluid/operators/yolov3_loss_op.h
浏览文件 @
3841983a
...
...
@@ -33,99 +33,102 @@ static inline bool isZero(T x) {
}
template
<
typename
T
>
static
inline
T
CalcMSEWithWeight
(
const
Tensor
&
x
,
const
Tensor
&
y
,
const
Tensor
&
weight
,
const
T
mf
)
{
int
numel
=
static_cast
<
int
>
(
x
.
numel
());
static
inline
void
CalcMSEWithWeight
(
const
Tensor
&
x
,
const
Tensor
&
y
,
const
Tensor
&
weight
,
const
T
loss_weight
,
T
*
loss
)
{
int
n
=
x
.
dims
()[
0
];
int
stride
=
x
.
numel
()
/
n
;
const
T
*
x_data
=
x
.
data
<
T
>
();
const
T
*
y_data
=
y
.
data
<
T
>
();
const
T
*
weight_data
=
weight
.
data
<
T
>
();
T
error_sum
=
0.0
;
for
(
int
i
=
0
;
i
<
numel
;
i
++
)
{
T
xi
=
x_data
[
i
];
T
yi
=
y_data
[
i
];
T
weighti
=
weight_data
[
i
];
error_sum
+=
pow
(
yi
-
xi
,
2
)
*
weighti
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
j
=
0
;
j
<
stride
;
j
++
)
{
loss
[
i
]
+=
pow
(
y_data
[
j
]
-
x_data
[
j
],
2
)
*
weight_data
[
j
]
*
loss_weight
;
}
x_data
+=
stride
;
y_data
+=
stride
;
weight_data
+=
stride
;
}
return
error_sum
/
mf
;
}
template
<
typename
T
>
static
void
CalcMSEGradWithWeight
(
Tensor
*
grad
,
const
Tensor
&
x
,
const
Tensor
&
y
,
const
Tensor
&
weight
,
const
T
mf
)
{
int
numel
=
static_cast
<
int
>
(
grad
->
numel
());
static
void
CalcMSEGradWithWeight
(
const
T
*
loss_grad
,
Tensor
*
grad
,
const
Tensor
&
x
,
const
Tensor
&
y
,
const
Tensor
&
weight
)
{
int
n
=
x
.
dims
()[
0
];
int
stride
=
x
.
numel
()
/
n
;
T
*
grad_data
=
grad
->
data
<
T
>
();
const
T
*
x_data
=
x
.
data
<
T
>
();
const
T
*
y_data
=
y
.
data
<
T
>
();
const
T
*
weight_data
=
weight
.
data
<
T
>
();
for
(
int
i
=
0
;
i
<
numel
;
i
++
)
{
grad_data
[
i
]
=
2.0
*
weight_data
[
i
]
*
(
x_data
[
i
]
-
y_data
[
i
])
/
mf
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
j
=
0
;
j
<
stride
;
j
++
)
{
grad_data
[
j
]
=
2.0
*
weight_data
[
j
]
*
(
x_data
[
j
]
-
y_data
[
j
])
*
loss_grad
[
i
];
}
grad_data
+=
stride
;
x_data
+=
stride
;
y_data
+=
stride
;
weight_data
+=
stride
;
}
}
template
<
typename
T
>
struct
SigmoidCrossEntropyForward
{
T
operator
()(
const
T
&
x
,
const
T
&
label
)
const
{
T
term1
=
(
x
>
0
)
?
x
:
0
;
T
term2
=
x
*
label
;
T
term3
=
std
::
log
(
static_cast
<
T
>
(
1.0
)
+
std
::
exp
(
-
(
std
::
abs
(
x
))));
return
term1
-
term2
+
term3
;
}
};
template
<
typename
T
>
struct
SigmoidCrossEntropyBackward
{
T
operator
()(
const
T
&
x
,
const
T
&
label
)
const
{
T
sigmoid_x
=
static_cast
<
T
>
(
1.0
)
/
(
static_cast
<
T
>
(
1.0
)
+
std
::
exp
(
-
1.0
*
x
));
return
sigmoid_x
-
label
;
}
};
template
<
typename
T
>
static
inline
T
CalcSCEWithWeight
(
const
Tensor
&
x
,
const
Tensor
&
labels
,
const
Tensor
&
weight
,
const
T
mf
)
{
int
numel
=
x
.
numel
();
static
inline
void
CalcSCEWithWeight
(
const
Tensor
&
x
,
const
Tensor
&
label
,
const
Tensor
&
weight
,
const
T
loss_weight
,
T
*
loss
)
{
int
n
=
x
.
dims
()[
0
];
int
stride
=
x
.
numel
()
/
n
;
const
T
*
x_data
=
x
.
data
<
T
>
();
const
T
*
label
s_data
=
labels
.
data
<
T
>
();
const
T
*
label
_data
=
label
.
data
<
T
>
();
const
T
*
weight_data
=
weight
.
data
<
T
>
();
T
loss
=
0.0
;
for
(
int
i
=
0
;
i
<
numel
;
i
++
)
{
T
xi
=
x_data
[
i
];
T
labeli
=
labels_data
[
i
];
T
weighti
=
weight_data
[
i
];
loss
+=
((
xi
>
0.0
?
xi
:
0.0
)
-
xi
*
labeli
+
std
::
log
(
1.0
+
std
::
exp
(
-
1.0
*
std
::
abs
(
xi
))))
*
weighti
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
j
=
0
;
j
<
stride
;
j
++
)
{
T
term1
=
(
x_data
[
j
]
>
0
)
?
x_data
[
j
]
:
0
;
T
term2
=
x_data
[
j
]
*
label_data
[
j
];
T
term3
=
std
::
log
(
1.0
+
std
::
exp
(
-
std
::
abs
(
x_data
[
j
])));
loss
[
i
]
+=
(
term1
-
term2
+
term3
)
*
weight_data
[
j
]
*
loss_weight
;
}
x_data
+=
stride
;
label_data
+=
stride
;
weight_data
+=
stride
;
}
return
loss
/
mf
;
}
template
<
typename
T
>
static
inline
void
CalcSCEGradWithWeight
(
Tensor
*
grad
,
const
Tensor
&
x
,
const
Tensor
&
labels
,
const
Tensor
&
weight
,
const
T
mf
)
{
int
numel
=
grad
->
numel
();
static
inline
void
CalcSCEGradWithWeight
(
const
T
*
loss_grad
,
Tensor
*
grad
,
const
Tensor
&
x
,
const
Tensor
&
label
,
const
Tensor
&
weight
)
{
int
n
=
x
.
dims
()[
0
];
int
stride
=
x
.
numel
()
/
n
;
T
*
grad_data
=
grad
->
data
<
T
>
();
const
T
*
x_data
=
x
.
data
<
T
>
();
const
T
*
label
s_data
=
labels
.
data
<
T
>
();
const
T
*
label
_data
=
label
.
data
<
T
>
();
const
T
*
weight_data
=
weight
.
data
<
T
>
();
for
(
int
i
=
0
;
i
<
numel
;
i
++
)
{
grad_data
[
i
]
=
(
1.0
/
(
1.0
+
std
::
exp
(
-
1.0
*
x_data
[
i
]))
-
labels_data
[
i
])
*
weight_data
[
i
]
/
mf
;
// LOG(ERROR) << "SCE grad start";
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
for
(
int
j
=
0
;
j
<
stride
;
j
++
)
{
grad_data
[
j
]
=
(
1.0
/
(
1.0
+
std
::
exp
(
-
x_data
[
j
]))
-
label_data
[
j
])
*
weight_data
[
j
]
*
loss_grad
[
i
];
// if (j == 18) LOG(ERROR) << x_data[j] << " " << label_data[j] << " " <<
// weight_data[j] << " " << loss_grad[i];
}
grad_data
+=
stride
;
x_data
+=
stride
;
label_data
+=
stride
;
weight_data
+=
stride
;
}
}
template
<
typename
T
>
static
void
Calc
PredResult
(
const
Tensor
&
input
,
Tensor
*
pred_conf
,
Tensor
*
pred_class
,
Tensor
*
pred_x
,
Tensor
*
pred_y
,
Tensor
*
pred_w
,
Tensor
*
pred_h
,
const
int
anchor_num
,
const
int
class_num
)
{
static
void
Split
PredResult
(
const
Tensor
&
input
,
Tensor
*
pred_conf
,
Tensor
*
pred_class
,
Tensor
*
pred_x
,
Tensor
*
pred_y
,
Tensor
*
pred_w
,
Tensor
*
pred_h
,
const
int
anchor_num
,
const
int
class_num
)
{
const
int
n
=
input
.
dims
()[
0
];
const
int
h
=
input
.
dims
()[
2
];
const
int
w
=
input
.
dims
()[
3
];
...
...
@@ -255,39 +258,20 @@ static void PreProcessGTBox(const Tensor& gt_box, const Tensor& gt_label,
}
}
static
void
ExpandObjMaskByClassNum
(
Tensor
*
obj_mask_expand
,
const
Tensor
&
obj_mask
)
{
const
int
n
=
obj_mask_expand
->
dims
()[
0
];
const
int
an_num
=
obj_mask_expand
->
dims
()[
1
];
const
int
h
=
obj_mask_expand
->
dims
()[
2
];
const
int
w
=
obj_mask_expand
->
dims
()[
3
];
const
int
class_num
=
obj_mask_expand
->
dims
()[
4
];
auto
obj_mask_expand_t
=
EigenTensor
<
int
,
5
>::
From
(
*
obj_mask_expand
);
auto
obj_mask_t
=
EigenTensor
<
int
,
4
>::
From
(
obj_mask
);
obj_mask_expand_t
=
obj_mask_t
.
reshape
(
Array5
(
n
,
an_num
,
h
,
w
,
1
))
.
broadcast
(
Array5
(
1
,
1
,
1
,
1
,
class_num
));
}
template
<
typename
T
>
static
void
AddAllGradToInputGrad
(
Tensor
*
grad
,
T
loss
,
const
Tensor
&
pred_x
,
const
Tensor
&
pred_y
,
const
Tensor
&
pred_conf
,
const
Tensor
&
pred_class
,
const
Tensor
&
grad_x
,
const
Tensor
&
grad_y
,
const
Tensor
&
grad_w
,
const
Tensor
&
grad_h
,
const
Tensor
&
grad_conf_target
,
const
Tensor
&
grad_conf_notarget
,
const
Tensor
&
grad_class
,
const
int
class_num
,
const
float
loss_weight_xy
,
const
float
loss_weight_wh
,
const
float
loss_weight_conf_target
,
const
float
loss_weight_conf_notarget
,
const
float
loss_weight_class
)
{
const
int
n
=
pred_x
.
dims
()[
0
];
const
int
an_num
=
pred_x
.
dims
()[
1
];
const
int
h
=
pred_x
.
dims
()[
2
];
const
int
w
=
pred_x
.
dims
()[
3
];
Tensor
*
grad
,
const
Tensor
&
grad_x
,
const
Tensor
&
grad_y
,
const
Tensor
&
grad_w
,
const
Tensor
&
grad_h
,
const
Tensor
&
grad_conf_target
,
const
Tensor
&
grad_conf_notarget
,
const
Tensor
&
grad_class
,
const
int
class_num
,
const
float
loss_weight_xy
,
const
float
loss_weight_wh
,
const
float
loss_weight_conf_target
,
const
float
loss_weight_conf_notarget
,
const
float
loss_weight_class
)
{
const
int
n
=
grad_x
.
dims
()[
0
];
const
int
an_num
=
grad_x
.
dims
()[
1
];
const
int
h
=
grad_x
.
dims
()[
2
];
const
int
w
=
grad_x
.
dims
()[
3
];
const
int
attr_num
=
class_num
+
5
;
auto
grad_t
=
EigenTensor
<
T
,
4
>::
From
(
*
grad
).
setConstant
(
0.0
);
auto
pred_x_t
=
EigenTensor
<
T
,
4
>::
From
(
pred_x
);
auto
pred_y_t
=
EigenTensor
<
T
,
4
>::
From
(
pred_y
);
auto
pred_conf_t
=
EigenTensor
<
T
,
4
>::
From
(
pred_conf
);
auto
pred_class_t
=
EigenTensor
<
T
,
5
>::
From
(
pred_class
);
auto
grad_x_t
=
EigenTensor
<
T
,
4
>::
From
(
grad_x
);
auto
grad_y_t
=
EigenTensor
<
T
,
4
>::
From
(
grad_y
);
auto
grad_w_t
=
EigenTensor
<
T
,
4
>::
From
(
grad_w
);
...
...
@@ -300,23 +284,21 @@ static void AddAllGradToInputGrad(
for
(
int
j
=
0
;
j
<
an_num
;
j
++
)
{
for
(
int
k
=
0
;
k
<
h
;
k
++
)
{
for
(
int
l
=
0
;
l
<
w
;
l
++
)
{
grad_t
(
i
,
j
*
attr_num
,
k
,
l
)
=
grad_x_t
(
i
,
j
,
k
,
l
)
*
loss
*
loss_weight_xy
;
grad_t
(
i
,
j
*
attr_num
,
k
,
l
)
=
grad_x_t
(
i
,
j
,
k
,
l
)
*
loss_weight_xy
;
grad_t
(
i
,
j
*
attr_num
+
1
,
k
,
l
)
=
grad_y_t
(
i
,
j
,
k
,
l
)
*
loss
*
loss
_weight_xy
;
grad_y_t
(
i
,
j
,
k
,
l
)
*
loss_weight_xy
;
grad_t
(
i
,
j
*
attr_num
+
2
,
k
,
l
)
=
grad_w_t
(
i
,
j
,
k
,
l
)
*
loss
*
loss
_weight_wh
;
grad_w_t
(
i
,
j
,
k
,
l
)
*
loss_weight_wh
;
grad_t
(
i
,
j
*
attr_num
+
3
,
k
,
l
)
=
grad_h_t
(
i
,
j
,
k
,
l
)
*
loss
*
loss
_weight_wh
;
grad_h_t
(
i
,
j
,
k
,
l
)
*
loss_weight_wh
;
grad_t
(
i
,
j
*
attr_num
+
4
,
k
,
l
)
=
grad_conf_target_t
(
i
,
j
,
k
,
l
)
*
loss
*
loss
_weight_conf_target
;
grad_conf_target_t
(
i
,
j
,
k
,
l
)
*
loss_weight_conf_target
;
grad_t
(
i
,
j
*
attr_num
+
4
,
k
,
l
)
+=
grad_conf_notarget_t
(
i
,
j
,
k
,
l
)
*
loss
*
loss_weight_conf_notarget
;
grad_conf_notarget_t
(
i
,
j
,
k
,
l
)
*
loss_weight_conf_notarget
;
for
(
int
c
=
0
;
c
<
class_num
;
c
++
)
{
grad_t
(
i
,
j
*
attr_num
+
5
+
c
,
k
,
l
)
=
grad_class_t
(
i
,
j
,
k
,
l
,
c
)
*
loss
*
loss
_weight_class
;
grad_class_t
(
i
,
j
,
k
,
l
,
c
)
*
loss_weight_class
;
}
}
}
...
...
@@ -356,8 +338,8 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
pred_h
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_conf
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_class
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
class_num
},
ctx
.
GetPlace
());
Calc
PredResult
<
T
>
(
*
input
,
&
pred_conf
,
&
pred_class
,
&
pred_x
,
&
pred_y
,
&
pred_w
,
&
pred_h
,
an_num
,
class_num
);
Split
PredResult
<
T
>
(
*
input
,
&
pred_conf
,
&
pred_class
,
&
pred_x
,
&
pred_y
,
&
pred_w
,
&
pred_h
,
an_num
,
class_num
);
Tensor
obj_mask
,
noobj_mask
;
Tensor
tx
,
ty
,
tw
,
th
,
tweight
,
tconf
,
tclass
;
...
...
@@ -388,25 +370,24 @@ class Yolov3LossKernel : public framework::OpKernel<T> {
obj_mask_expand_t
=
obj_mask_t
.
reshape
(
Array5
(
n
,
an_num
,
h
,
w
,
1
))
.
broadcast
(
Array5
(
1
,
1
,
1
,
1
,
class_num
));
T
box_f
=
static_cast
<
T
>
(
an_num
*
h
*
w
);
T
class_f
=
static_cast
<
T
>
(
an_num
*
h
*
w
*
class_num
);
T
loss_x
=
CalcSCEWithWeight
<
T
>
(
pred_x
,
tx
,
obj_weight
,
box_f
);
T
loss_y
=
CalcSCEWithWeight
<
T
>
(
pred_y
,
ty
,
obj_weight
,
box_f
);
T
loss_w
=
CalcMSEWithWeight
<
T
>
(
pred_w
,
tw
,
obj_weight
,
box_f
);
T
loss_h
=
CalcMSEWithWeight
<
T
>
(
pred_h
,
th
,
obj_weight
,
box_f
);
T
loss_conf_target
=
CalcSCEWithWeight
<
T
>
(
pred_conf
,
tconf
,
obj_mask
,
box_f
);
T
loss_conf_notarget
=
CalcSCEWithWeight
<
T
>
(
pred_conf
,
tconf
,
noobj_mask
,
box_f
);
T
loss_class
=
CalcSCEWithWeight
<
T
>
(
pred_class
,
tclass
,
obj_mask_expand
,
class_f
);
auto
*
loss_data
=
loss
->
mutable_data
<
T
>
({
1
},
ctx
.
GetPlace
());
loss_data
[
0
]
=
loss_weight_xy
*
(
loss_x
+
loss_y
)
+
loss_weight_wh
*
(
loss_w
+
loss_h
)
+
loss_weight_conf_target
*
loss_conf_target
+
loss_weight_conf_notarget
*
loss_conf_notarget
+
loss_weight_class
*
loss_class
;
T
*
loss_data
=
loss
->
mutable_data
<
T
>
({
n
},
ctx
.
GetPlace
());
memset
(
loss_data
,
0
,
n
*
sizeof
(
T
));
CalcSCEWithWeight
<
T
>
(
pred_x
,
tx
,
obj_weight
,
loss_weight_xy
,
loss_data
);
CalcSCEWithWeight
<
T
>
(
pred_y
,
ty
,
obj_weight
,
loss_weight_xy
,
loss_data
);
CalcMSEWithWeight
<
T
>
(
pred_w
,
tw
,
obj_weight
,
loss_weight_wh
,
loss_data
);
CalcMSEWithWeight
<
T
>
(
pred_h
,
th
,
obj_weight
,
loss_weight_wh
,
loss_data
);
CalcSCEWithWeight
<
T
>
(
pred_conf
,
tconf
,
obj_mask
,
loss_weight_conf_target
,
loss_data
);
CalcSCEWithWeight
<
T
>
(
pred_conf
,
tconf
,
noobj_mask
,
loss_weight_conf_notarget
,
loss_data
);
CalcSCEWithWeight
<
T
>
(
pred_class
,
tclass
,
obj_mask_expand
,
loss_weight_class
,
loss_data
);
// loss_data[0] = (loss_weight_xy * (loss_x + loss_y) +
// loss_weight_wh * (loss_w + loss_h) +
// loss_weight_conf_target * loss_conf_target +
// loss_weight_conf_notarget * loss_conf_notarget +
// loss_weight_class * loss_class) / n;
}
};
...
...
@@ -421,8 +402,8 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
int
class_num
=
ctx
.
Attr
<
int
>
(
"class_num"
);
float
ignore_thresh
=
ctx
.
Attr
<
float
>
(
"ignore_thresh"
);
auto
*
input_grad
=
ctx
.
Output
<
Tensor
>
(
framework
::
GradVarName
(
"X"
));
auto
*
output
_grad
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Loss"
));
const
T
loss
=
output_grad
->
data
<
T
>
()[
0
]
;
auto
*
loss
_grad
=
ctx
.
Input
<
Tensor
>
(
framework
::
GradVarName
(
"Loss"
));
const
T
*
loss_grad_data
=
loss_grad
->
data
<
T
>
()
;
int
input_size
=
ctx
.
Attr
<
int
>
(
"input_size"
);
float
loss_weight_xy
=
ctx
.
Attr
<
float
>
(
"loss_weight_xy"
);
float
loss_weight_wh
=
ctx
.
Attr
<
float
>
(
"loss_weight_wh"
);
...
...
@@ -445,8 +426,8 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
pred_h
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_conf
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
pred_class
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
class_num
},
ctx
.
GetPlace
());
Calc
PredResult
<
T
>
(
*
input
,
&
pred_conf
,
&
pred_class
,
&
pred_x
,
&
pred_y
,
&
pred_w
,
&
pred_h
,
an_num
,
class_num
);
Split
PredResult
<
T
>
(
*
input
,
&
pred_conf
,
&
pred_class
,
&
pred_x
,
&
pred_y
,
&
pred_w
,
&
pred_h
,
an_num
,
class_num
);
Tensor
obj_mask
,
noobj_mask
;
Tensor
tx
,
ty
,
tw
,
th
,
tweight
,
tconf
,
tclass
;
...
...
@@ -470,6 +451,8 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
auto
tweight_t
=
EigenTensor
<
T
,
4
>::
From
(
tweight
);
obj_weight_t
=
obj_mask_t
*
tweight_t
;
// LOG(ERROR) << obj_mask_t;
Tensor
obj_mask_expand
;
obj_mask_expand
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
class_num
},
ctx
.
GetPlace
());
...
...
@@ -486,25 +469,23 @@ class Yolov3LossGradKernel : public framework::OpKernel<T> {
grad_conf_target
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
grad_conf_notarget
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
},
ctx
.
GetPlace
());
grad_class
.
mutable_data
<
T
>
({
n
,
an_num
,
h
,
w
,
class_num
},
ctx
.
GetPlace
());
T
box_f
=
static_cast
<
T
>
(
an_num
*
h
*
w
);
T
class_f
=
static_cast
<
T
>
(
an_num
*
h
*
w
*
class_num
);
CalcSCEGradWithWeight
<
T
>
(
&
grad_x
,
pred_x
,
tx
,
obj_weight
,
box_f
);
CalcSCEGradWithWeight
<
T
>
(
&
grad_y
,
pred_y
,
ty
,
obj_weight
,
box_f
);
CalcMSEGradWithWeight
<
T
>
(
&
grad_w
,
pred_w
,
tw
,
obj_weight
,
box_f
);
CalcMSEGradWithWeight
<
T
>
(
&
grad_h
,
pred_h
,
th
,
obj_weight
,
box_f
);
CalcSCEGradWithWeight
<
T
>
(
&
grad_conf_target
,
pred_conf
,
tconf
,
obj_mask
,
box_f
);
CalcSCEGradWithWeight
<
T
>
(
&
grad_conf_notarget
,
pred_conf
,
tconf
,
noobj_mask
,
box_f
);
CalcSCEGradWithWeight
<
T
>
(
&
grad_class
,
pred_class
,
tclass
,
obj_mask_expand
,
class_f
);
CalcSCEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_x
,
pred_x
,
tx
,
obj_weight
);
CalcSCEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_y
,
pred_y
,
ty
,
obj_weight
);
CalcMSEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_w
,
pred_w
,
tw
,
obj_weight
);
CalcMSEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_h
,
pred_h
,
th
,
obj_weight
);
CalcSCEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_conf_target
,
pred_conf
,
tconf
,
obj_mask
);
CalcSCEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_conf_notarget
,
pred_conf
,
tconf
,
noobj_mask
);
CalcSCEGradWithWeight
<
T
>
(
loss_grad_data
,
&
grad_class
,
pred_class
,
tclass
,
obj_mask_expand
);
input_grad
->
mutable_data
<
T
>
({
n
,
c
,
h
,
w
},
ctx
.
GetPlace
());
AddAllGradToInputGrad
<
T
>
(
input_grad
,
loss
,
pred_x
,
pred_y
,
pred_conf
,
pred_class
,
grad_x
,
grad_y
,
grad_w
,
grad_h
,
grad_conf_target
,
grad_conf_notarget
,
grad_class
,
class_num
,
loss_weight_xy
,
loss_weight_wh
,
loss_weight_conf_
target
,
loss_weight_conf_notarget
,
loss_weight_class
);
AddAllGradToInputGrad
<
T
>
(
input_grad
,
grad_x
,
grad_y
,
grad_w
,
grad_h
,
grad_conf_target
,
grad_conf_notarget
,
grad_class
,
class_num
,
loss_weight_xy
,
loss_weight_wh
,
loss_weight_conf_target
,
loss_weight_conf_no
target
,
loss_weight_class
);
}
};
...
...
python/paddle/fluid/tests/unittests/op_test.py
浏览文件 @
3841983a
...
...
@@ -470,6 +470,8 @@ class OpTest(unittest.TestCase):
]
analytic_grads
=
self
.
_get_gradient
(
inputs_to_check
,
place
,
output_names
,
no_grad_set
)
# print(numeric_grads[0][0, 4, :, :])
# print(analytic_grads[0][0, 4, :, :])
self
.
_assert_is_close
(
numeric_grads
,
analytic_grads
,
inputs_to_check
,
max_relative_error
,
...
...
python/paddle/fluid/tests/unittests/test_yolov3_loss_op.py
浏览文件 @
3841983a
...
...
@@ -23,15 +23,23 @@ from op_test import OpTest
from
paddle.fluid
import
core
def
mse
(
x
,
y
,
weight
,
num
):
return
((
y
-
x
)
**
2
*
weight
).
sum
()
/
num
def
sce
(
x
,
label
,
weight
,
num
):
def
mse
(
x
,
y
,
weight
):
n
=
x
.
shape
[
0
]
x
=
x
.
reshape
((
n
,
-
1
))
y
=
y
.
reshape
((
n
,
-
1
))
weight
=
weight
.
reshape
((
n
,
-
1
))
return
((
y
-
x
)
**
2
*
weight
).
sum
(
axis
=
1
)
def
sce
(
x
,
label
,
weight
):
n
=
x
.
shape
[
0
]
x
=
x
.
reshape
((
n
,
-
1
))
label
=
label
.
reshape
((
n
,
-
1
))
weight
=
weight
.
reshape
((
n
,
-
1
))
sigmoid_x
=
expit
(
x
)
term1
=
label
*
np
.
log
(
sigmoid_x
)
term2
=
(
1.0
-
label
)
*
np
.
log
(
1.0
-
sigmoid_x
)
return
((
-
term1
-
term2
)
*
weight
).
sum
(
)
/
num
return
((
-
term1
-
term2
)
*
weight
).
sum
(
axis
=
1
)
def
box_iou
(
box1
,
box2
):
...
...
@@ -131,18 +139,24 @@ def YoloV3Loss(x, gtbox, gtlabel, attrs):
tx
,
ty
,
tw
,
th
,
tweight
,
tconf
,
tcls
,
obj_mask
,
noobj_mask
=
build_target
(
gtbox
,
gtlabel
,
attrs
,
x
.
shape
[
2
])
# print("obj_mask: ", obj_mask[0, 0, :, :])
# print("noobj_mask: ", noobj_mask[0, 0, :, :])
obj_weight
=
obj_mask
*
tweight
obj_mask_expand
=
np
.
tile
(
np
.
expand_dims
(
obj_mask
,
4
),
(
1
,
1
,
1
,
1
,
int
(
attrs
[
'class_num'
])))
box_f
=
an_num
*
h
*
w
class_f
=
an_num
*
h
*
w
*
class_num
loss_x
=
sce
(
pred_x
,
tx
,
obj_weight
,
box_f
)
loss_y
=
sce
(
pred_y
,
ty
,
obj_weight
,
box_f
)
loss_w
=
mse
(
pred_w
,
tw
,
obj_weight
,
box_f
)
loss_h
=
mse
(
pred_h
,
th
,
obj_weight
,
box_f
)
loss_conf_target
=
sce
(
pred_conf
,
tconf
,
obj_mask
,
box_f
)
loss_conf_notarget
=
sce
(
pred_conf
,
tconf
,
noobj_mask
,
box_f
)
loss_class
=
sce
(
pred_cls
,
tcls
,
obj_mask_expand
,
class_f
)
loss_x
=
sce
(
pred_x
,
tx
,
obj_weight
)
loss_y
=
sce
(
pred_y
,
ty
,
obj_weight
)
loss_w
=
mse
(
pred_w
,
tw
,
obj_weight
)
loss_h
=
mse
(
pred_h
,
th
,
obj_weight
)
loss_conf_target
=
sce
(
pred_conf
,
tconf
,
obj_mask
)
loss_conf_notarget
=
sce
(
pred_conf
,
tconf
,
noobj_mask
)
loss_class
=
sce
(
pred_cls
,
tcls
,
obj_mask_expand
)
# print("loss_xy: ", loss_x + loss_y)
# print("loss_wh: ", loss_w + loss_h)
# print("loss_conf_target: ", loss_conf_target)
# print("loss_conf_notarget: ", loss_conf_notarget)
# print("loss_class: ", loss_class)
return
attrs
[
'loss_weight_xy'
]
*
(
loss_x
+
loss_y
)
\
+
attrs
[
'loss_weight_wh'
]
*
(
loss_w
+
loss_h
)
\
...
...
@@ -178,10 +192,7 @@ class TestYolov3LossOp(OpTest):
}
self
.
inputs
=
{
'X'
:
x
,
'GTBox'
:
gtbox
,
'GTLabel'
:
gtlabel
}
self
.
outputs
=
{
'Loss'
:
np
.
array
(
[
YoloV3Loss
(
x
,
gtbox
,
gtlabel
,
self
.
attrs
)]).
astype
(
'float32'
)
}
self
.
outputs
=
{
'Loss'
:
YoloV3Loss
(
x
,
gtbox
,
gtlabel
,
self
.
attrs
)}
def
test_check_output
(
self
):
place
=
core
.
CPUPlace
()
...
...
@@ -193,20 +204,20 @@ class TestYolov3LossOp(OpTest):
place
,
[
'X'
],
'Loss'
,
no_grad_set
=
set
([
"GTBox"
,
"GTLabel"
]),
max_relative_error
=
0.3
)
max_relative_error
=
0.3
1
)
def
initTestCase
(
self
):
self
.
anchors
=
[
1
0
,
13
,
1
2
,
12
]
self
.
class_num
=
10
self
.
ignore_thresh
=
0.
7
self
.
anchors
=
[
12
,
12
]
self
.
class_num
=
5
self
.
ignore_thresh
=
0.
3
self
.
input_size
=
416
self
.
x_shape
=
(
5
,
len
(
self
.
anchors
)
//
2
*
(
5
+
self
.
class_num
),
7
,
7
)
self
.
gtbox_shape
=
(
5
,
10
,
4
)
self
.
loss_weight_xy
=
1.
4
self
.
x_shape
=
(
3
,
len
(
self
.
anchors
)
//
2
*
(
5
+
self
.
class_num
),
5
,
5
)
self
.
gtbox_shape
=
(
3
,
5
,
4
)
self
.
loss_weight_xy
=
1.
2
self
.
loss_weight_wh
=
0.8
self
.
loss_weight_conf_target
=
1.1
self
.
loss_weight_conf_notarget
=
0.9
self
.
loss_weight_class
=
1.
2
self
.
loss_weight_conf_target
=
2.0
self
.
loss_weight_conf_notarget
=
1.0
self
.
loss_weight_class
=
1.
5
if
__name__
==
"__main__"
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录