Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
3841983a
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看板
提交
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录