Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
91a21883
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看板
提交
91a21883
编写于
2月 12, 2018
作者:
W
wanghaox
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update detection_map
上级
006ef1fd
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
87 addition
and
69 deletion
+87
-69
paddle/fluid/operators/detection_map_op.cc
paddle/fluid/operators/detection_map_op.cc
+62
-36
paddle/fluid/operators/detection_map_op.h
paddle/fluid/operators/detection_map_op.h
+19
-25
python/paddle/v2/fluid/tests/test_detection_map_op.py
python/paddle/v2/fluid/tests/test_detection_map_op.py
+6
-8
未找到文件。
paddle/fluid/operators/detection_map_op.cc
浏览文件 @
91a21883
...
@@ -24,25 +24,28 @@ class DetectionMAPOp : public framework::OperatorWithKernel {
...
@@ -24,25 +24,28 @@ class DetectionMAPOp : public framework::OperatorWithKernel {
using
framework
::
OperatorWithKernel
::
OperatorWithKernel
;
using
framework
::
OperatorWithKernel
::
OperatorWithKernel
;
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
void
InferShape
(
framework
::
InferShapeContext
*
ctx
)
const
override
{
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"Detect
ion
"
),
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"Detect
Res
"
),
"Input(Detect
ion
) of DetectionMAPOp should not be null."
);
"Input(Detect
Res
) of DetectionMAPOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"Label"
),
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"Label"
),
"Input(Label) of DetectionMAPOp should not be null."
);
"Input(Label) of DetectionMAPOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"OutPosCount"
),
PADDLE_ENFORCE
(
"Output(OutPosCount) of DetectionMAPOp should not be null."
);
ctx
->
HasOutput
(
"AccumPosCount"
),
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"OutTruePos"
),
"Output(AccumPosCount) of DetectionMAPOp should not be null."
);
"Output(OutTruePos) of DetectionMAPOp should not be null."
);
PADDLE_ENFORCE
(
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"OutFalsePos"
),
ctx
->
HasOutput
(
"AccumTruePos"
),
"Output(OutFalsePos) of DetectionMAPOp should not be null."
);
"Output(AccumTruePos) of DetectionMAPOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"AccumFalsePos"
),
"Output(AccumFalsePos) of DetectionMAPOp should not be null."
);
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"MAP"
),
PADDLE_ENFORCE
(
ctx
->
HasOutput
(
"MAP"
),
"Output(MAP) of DetectionMAPOp should not be null."
);
"Output(MAP) of DetectionMAPOp should not be null."
);
auto
det_dims
=
ctx
->
GetInputDim
(
"Detect
ion
"
);
auto
det_dims
=
ctx
->
GetInputDim
(
"Detect
Res
"
);
PADDLE_ENFORCE_EQ
(
det_dims
.
size
(),
2UL
,
PADDLE_ENFORCE_EQ
(
det_dims
.
size
(),
2UL
,
"The rank of Input(Detect
ion
) must be 2, "
"The rank of Input(Detect
Res
) must be 2, "
"the shape is [N, 6]."
);
"the shape is [N, 6]."
);
PADDLE_ENFORCE_EQ
(
det_dims
[
1
],
6UL
,
PADDLE_ENFORCE_EQ
(
det_dims
[
1
],
6UL
,
"The shape is of Input(Detect
ion
) [N, 6]."
);
"The shape is of Input(Detect
Res
) [N, 6]."
);
auto
label_dims
=
ctx
->
GetInputDim
(
"Label"
);
auto
label_dims
=
ctx
->
GetInputDim
(
"Label"
);
PADDLE_ENFORCE_EQ
(
label_dims
.
size
(),
2UL
,
PADDLE_ENFORCE_EQ
(
label_dims
.
size
(),
2UL
,
"The rank of Input(Label) must be 2, "
"The rank of Input(Label) must be 2, "
...
@@ -50,8 +53,17 @@ class DetectionMAPOp : public framework::OperatorWithKernel {
...
@@ -50,8 +53,17 @@ class DetectionMAPOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
label_dims
[
1
],
6UL
,
PADDLE_ENFORCE_EQ
(
label_dims
[
1
],
6UL
,
"The shape is of Input(Label) [N, 6]."
);
"The shape is of Input(Label) [N, 6]."
);
auto
map_dim
=
framework
::
make_ddim
({
1
});
if
(
ctx
->
HasInput
(
"PosCount"
))
{
ctx
->
SetOutputDim
(
"MAP"
,
map_dim
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"TruePos"
),
"Input(TruePos) of DetectionMAPOp should not be null when "
"Input(TruePos) is not null."
);
PADDLE_ENFORCE
(
ctx
->
HasInput
(
"FalsePos"
),
"Input(FalsePos) of DetectionMAPOp should not be null when "
"Input(FalsePos) is not null."
);
}
ctx
->
SetOutputDim
(
"MAP"
,
framework
::
make_ddim
({
1
}));
}
}
protected:
protected:
...
@@ -59,7 +71,7 @@ class DetectionMAPOp : public framework::OperatorWithKernel {
...
@@ -59,7 +71,7 @@ class DetectionMAPOp : public framework::OperatorWithKernel {
const
framework
::
ExecutionContext
&
ctx
)
const
override
{
const
framework
::
ExecutionContext
&
ctx
)
const
override
{
return
framework
::
OpKernelType
(
return
framework
::
OpKernelType
(
framework
::
ToDataType
(
framework
::
ToDataType
(
ctx
.
Input
<
framework
::
Tensor
>
(
"Detect
ion
"
)
->
type
()),
ctx
.
Input
<
framework
::
Tensor
>
(
"Detect
Res
"
)
->
type
()),
ctx
.
device_context
());
ctx
.
device_context
());
}
}
};
};
...
@@ -68,6 +80,14 @@ class DetectionMAPOpMaker : public framework::OpProtoAndCheckerMaker {
...
@@ -68,6 +80,14 @@ class DetectionMAPOpMaker : public framework::OpProtoAndCheckerMaker {
public:
public:
DetectionMAPOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
DetectionMAPOpMaker
(
OpProto
*
proto
,
OpAttrChecker
*
op_checker
)
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
:
OpProtoAndCheckerMaker
(
proto
,
op_checker
)
{
AddInput
(
"DetectRes"
,
"(LoDTensor) A 2-D LoDTensor with shape [M, 6] represents the "
"detections. Each row has 6 values: "
"[label, confidence, xmin, ymin, xmax, ymax], M is the total "
"number of detect results in this mini-batch. For each instance, "
"the offsets in first dimension are called LoD, the number of "
"offset is N + 1, if LoD[i + 1] - LoD[i] == 0, means there is "
"no detected data."
);
AddInput
(
"Label"
,
AddInput
(
"Label"
,
"(LoDTensor) A 2-D LoDTensor with shape[N, 6] represents the"
"(LoDTensor) A 2-D LoDTensor with shape[N, 6] represents the"
"Labeled ground-truth data. Each row has 6 values: "
"Labeled ground-truth data. Each row has 6 values: "
...
@@ -76,38 +96,43 @@ class DetectionMAPOpMaker : public framework::OpProtoAndCheckerMaker {
...
@@ -76,38 +96,43 @@ class DetectionMAPOpMaker : public framework::OpProtoAndCheckerMaker {
"instance, the offsets in first dimension are called LoD, "
"instance, the offsets in first dimension are called LoD, "
"the number of offset is N + 1, if LoD[i + 1] - LoD[i] == 0, "
"the number of offset is N + 1, if LoD[i + 1] - LoD[i] == 0, "
"means there is no ground-truth data."
);
"means there is no ground-truth data."
);
AddInput
(
"Detection"
,
"(LoDTensor) A 2-D LoDTensor with shape [M, 6] represents the "
"detections. Each row has 6 values: "
"[label, confidence, xmin, ymin, xmax, ymax], M is the total "
"number of detections in this mini-batch. For each instance, "
"the offsets in first dimension are called LoD, the number of "
"offset is N + 1, if LoD[i + 1] - LoD[i] == 0, means there is "
"no detected data."
);
AddInput
(
"PosCount"
,
AddInput
(
"PosCount"
,
"(Tensor) A tensor with shape [Ncls, 1], store the "
"(Tensor) A tensor with shape [Ncls, 1], store the "
"input positive example count of each class."
)
"input positive example count of each class, Ncls is the count of "
"input classification. "
"This input is used to pass the AccumPosCount generated by the "
"previous mini-batch when the multi mini-batches cumulative "
"calculation carried out. "
"When the input(PosCount) is empty, the cumulative "
"calculation is not carried out, and only the results of the "
"current mini-batch are calculated."
)
.
AsDispensable
();
.
AsDispensable
();
AddInput
(
"TruePos"
,
AddInput
(
"TruePos"
,
"(LodTensor) A 2-D LodTensor with shape [Ntp, 2], store the "
"(LoDTensor) A 2-D LoDTensor with shape [Ntp, 2], store the "
"input true positive example of each class."
)
"input true positive example of each class."
"This input is used to pass the AccumTruePos generated by the "
"previous mini-batch when the multi mini-batches cumulative "
"calculation carried out. "
)
.
AsDispensable
();
.
AsDispensable
();
AddInput
(
"FalsePos"
,
AddInput
(
"FalsePos"
,
"(LodTensor) A 2-D LodTensor with shape [Nfp, 2], store the "
"(LoDTensor) A 2-D LoDTensor with shape [Nfp, 2], store the "
"input false positive example of each class."
)
"input false positive example of each class."
"This input is used to pass the AccumFalsePos generated by the "
"previous mini-batch when the multi mini-batches cumulative "
"calculation carried out. "
)
.
AsDispensable
();
.
AsDispensable
();
AddOutput
(
"
Out
PosCount"
,
AddOutput
(
"
Accum
PosCount"
,
"(Tensor) A tensor with shape [Ncls, 1], store the "
"(Tensor) A tensor with shape [Ncls, 1], store the "
"positive example count of each class. It combines the input "
"positive example count of each class. It combines the input "
"input(PosCount) and the positive example count computed from "
"input(PosCount) and the positive example count computed from "
"input(Detection) and input(Label)."
);
"input(Detection) and input(Label)."
);
AddOutput
(
"
Out
TruePos"
,
AddOutput
(
"
Accum
TruePos"
,
"(Lo
dTensor) A Lod
Tensor with shape [Ntp', 2], store the "
"(Lo
DTensor) A LoD
Tensor with shape [Ntp', 2], store the "
"true positive example of each class. It combines the "
"true positive example of each class. It combines the "
"input(TruePos) and the true positive examples computed from "
"input(TruePos) and the true positive examples computed from "
"input(Detection) and input(Label)."
);
"input(Detection) and input(Label)."
);
AddOutput
(
"
Out
FalsePos"
,
AddOutput
(
"
Accum
FalsePos"
,
"(Lo
dTensor) A Lod
Tensor with shape [Nfp', 2], store the "
"(Lo
DTensor) A LoD
Tensor with shape [Nfp', 2], store the "
"false positive example of each class. It combines the "
"false positive example of each class. It combines the "
"input(FalsePos) and the false positive examples computed from "
"input(FalsePos) and the false positive examples computed from "
"input(Detection) and input(Label)."
);
"input(Detection) and input(Label)."
);
...
@@ -115,10 +140,11 @@ class DetectionMAPOpMaker : public framework::OpProtoAndCheckerMaker {
...
@@ -115,10 +140,11 @@ class DetectionMAPOpMaker : public framework::OpProtoAndCheckerMaker {
"(Tensor) A tensor with shape [1], store the mAP evaluate "
"(Tensor) A tensor with shape [1], store the mAP evaluate "
"result of the detection."
);
"result of the detection."
);
AddAttr
<
float
>
(
"overlap_threshold"
,
AddAttr
<
float
>
(
"(float) "
"overlap_threshold"
,
"The jaccard overlap threshold of detection output and "
"(float) "
"ground-truth data."
)
"The lower bound jaccard overlap threshold of detection output and "
"ground-truth data."
)
.
SetDefault
(
.3
f
);
.
SetDefault
(
.3
f
);
AddAttr
<
bool
>
(
"evaluate_difficult"
,
AddAttr
<
bool
>
(
"evaluate_difficult"
,
"(bool, default true) "
"(bool, default true) "
...
...
paddle/fluid/operators/detection_map_op.h
浏览文件 @
91a21883
...
@@ -54,7 +54,7 @@ template <typename Place, typename T>
...
@@ -54,7 +54,7 @@ template <typename Place, typename T>
class
DetectionMAPOpKernel
:
public
framework
::
OpKernel
<
T
>
{
class
DetectionMAPOpKernel
:
public
framework
::
OpKernel
<
T
>
{
public:
public:
void
Compute
(
const
framework
::
ExecutionContext
&
ctx
)
const
override
{
void
Compute
(
const
framework
::
ExecutionContext
&
ctx
)
const
override
{
auto
*
in_detect
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"Detect
ion
"
);
auto
*
in_detect
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"Detect
Res
"
);
auto
*
in_label
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"Label"
);
auto
*
in_label
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"Label"
);
auto
*
out_map
=
ctx
.
Output
<
framework
::
Tensor
>
(
"MAP"
);
auto
*
out_map
=
ctx
.
Output
<
framework
::
Tensor
>
(
"MAP"
);
...
@@ -62,9 +62,9 @@ class DetectionMAPOpKernel : public framework::OpKernel<T> {
...
@@ -62,9 +62,9 @@ class DetectionMAPOpKernel : public framework::OpKernel<T> {
auto
*
in_true_pos
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"TruePos"
);
auto
*
in_true_pos
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"TruePos"
);
auto
*
in_false_pos
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"FalsePos"
);
auto
*
in_false_pos
=
ctx
.
Input
<
framework
::
LoDTensor
>
(
"FalsePos"
);
auto
*
out_pos_count
=
ctx
.
Output
<
framework
::
Tensor
>
(
"
Out
PosCount"
);
auto
*
out_pos_count
=
ctx
.
Output
<
framework
::
Tensor
>
(
"
Accum
PosCount"
);
auto
*
out_true_pos
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
"
Out
TruePos"
);
auto
*
out_true_pos
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
"
Accum
TruePos"
);
auto
*
out_false_pos
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
"
Out
FalsePos"
);
auto
*
out_false_pos
=
ctx
.
Output
<
framework
::
LoDTensor
>
(
"
Accum
FalsePos"
);
float
overlap_threshold
=
ctx
.
Attr
<
float
>
(
"overlap_threshold"
);
float
overlap_threshold
=
ctx
.
Attr
<
float
>
(
"overlap_threshold"
);
float
evaluate_difficult
=
ctx
.
Attr
<
bool
>
(
"evaluate_difficult"
);
float
evaluate_difficult
=
ctx
.
Attr
<
bool
>
(
"evaluate_difficult"
);
...
@@ -265,28 +265,22 @@ class DetectionMAPOpKernel : public framework::OpKernel<T> {
...
@@ -265,28 +265,22 @@ class DetectionMAPOpKernel : public framework::OpKernel<T> {
label_pos_count
[
i
]
=
pos_count_data
[
i
];
label_pos_count
[
i
]
=
pos_count_data
[
i
];
}
}
const
T
*
true_pos_data
=
input_true_pos
.
data
<
T
>
();
auto
SetData
=
[](
const
framework
::
LoDTensor
&
pos_tensor
,
auto
true_pos_data_lod
=
input_true_pos
.
lod
();
std
::
map
<
int
,
std
::
vector
<
std
::
pair
<
T
,
int
>>>&
pos
)
{
for
(
int
i
=
0
;
i
<
true_pos_data_lod
.
size
();
++
i
)
{
const
T
*
pos_data
=
pos_tensor
.
data
<
T
>
();
for
(
int
j
=
true_pos_data_lod
[
0
][
i
];
j
<
true_pos_data_lod
[
0
][
i
+
1
];
auto
pos_data_lod
=
pos_tensor
.
lod
();
++
j
)
{
for
(
int
i
=
0
;
i
<
pos_data_lod
.
size
();
++
i
)
{
T
score
=
true_pos_data
[
j
*
2
];
for
(
int
j
=
pos_data_lod
[
0
][
i
];
j
<
pos_data_lod
[
0
][
i
+
1
];
++
j
)
{
int
flag
=
1
;
T
score
=
pos_data
[
j
*
2
];
if
(
true_pos_data
[
j
*
2
+
1
]
<
kEPS
)
flag
=
0
;
int
flag
=
1
;
true_pos
[
i
].
push_back
(
std
::
make_pair
(
score
,
flag
));
if
(
pos_data
[
j
*
2
+
1
]
<
kEPS
)
flag
=
0
;
}
pos
[
i
].
push_back
(
std
::
make_pair
(
score
,
flag
));
}
}
const
T
*
false_pos_data
=
input_false_pos
.
data
<
T
>
();
auto
false_pos_data_lod
=
input_false_pos
.
lod
();
for
(
int
i
=
0
;
i
<
false_pos_data_lod
.
size
();
++
i
)
{
for
(
int
j
=
false_pos_data_lod
[
0
][
i
];
j
<
false_pos_data_lod
[
0
][
i
+
1
];
++
j
)
{
T
score
=
false_pos_data
[
j
*
2
];
int
flag
=
1
;
if
(
false_pos_data
[
j
*
2
+
1
]
<
kEPS
)
flag
=
0
;
false_pos
[
i
].
push_back
(
std
::
make_pair
(
score
,
flag
));
}
}
}
};
SetData
(
input_true_pos
,
true_pos
);
SetData
(
input_false_pos
,
false_pos
);
return
;
return
;
}
}
...
...
python/paddle/v2/fluid/tests/test_detection_map_op.py
浏览文件 @
91a21883
...
@@ -37,7 +37,7 @@ class TestDetectionMAPOp(OpTest):
...
@@ -37,7 +37,7 @@ class TestDetectionMAPOp(OpTest):
self
.
inputs
=
{
self
.
inputs
=
{
'Label'
:
(
self
.
label
,
self
.
label_lod
),
'Label'
:
(
self
.
label
,
self
.
label_lod
),
'Detect
ion
'
:
(
self
.
detect
,
self
.
detect_lod
),
'Detect
Res
'
:
(
self
.
detect
,
self
.
detect_lod
),
'PosCount'
:
self
.
class_pos_count
,
'PosCount'
:
self
.
class_pos_count
,
'TruePos'
:
(
self
.
true_pos
,
self
.
true_pos_lod
),
'TruePos'
:
(
self
.
true_pos
,
self
.
true_pos_lod
),
'FalsePos'
:
(
self
.
false_pos
,
self
.
false_pos_lod
)
'FalsePos'
:
(
self
.
false_pos
,
self
.
false_pos_lod
)
...
@@ -45,7 +45,7 @@ class TestDetectionMAPOp(OpTest):
...
@@ -45,7 +45,7 @@ class TestDetectionMAPOp(OpTest):
else
:
else
:
self
.
inputs
=
{
self
.
inputs
=
{
'Label'
:
(
self
.
label
,
self
.
label_lod
),
'Label'
:
(
self
.
label
,
self
.
label_lod
),
'Detect
ion
'
:
(
self
.
detect
,
self
.
detect_lod
),
'Detect
Res
'
:
(
self
.
detect
,
self
.
detect_lod
),
}
}
self
.
attrs
=
{
self
.
attrs
=
{
...
@@ -61,9 +61,9 @@ class TestDetectionMAPOp(OpTest):
...
@@ -61,9 +61,9 @@ class TestDetectionMAPOp(OpTest):
self
.
outputs
=
{
self
.
outputs
=
{
'MAP'
:
self
.
mAP
,
'MAP'
:
self
.
mAP
,
'
Out
PosCount'
:
self
.
out_class_pos_count
,
'
Accum
PosCount'
:
self
.
out_class_pos_count
,
'
Out
TruePos'
:
(
self
.
out_true_pos
,
self
.
out_true_pos_lod
),
'
Accum
TruePos'
:
(
self
.
out_true_pos
,
self
.
out_true_pos_lod
),
'
Out
FalsePos'
:
(
self
.
out_false_pos
,
self
.
out_false_pos_lod
)
'
Accum
FalsePos'
:
(
self
.
out_false_pos
,
self
.
out_false_pos_lod
)
}
}
def
init_test_case
(
self
):
def
init_test_case
(
self
):
...
@@ -175,9 +175,7 @@ class TestDetectionMAPOp(OpTest):
...
@@ -175,9 +175,7 @@ class TestDetectionMAPOp(OpTest):
false_pos
[
label
].
append
([
score
,
fp
])
false_pos
[
label
].
append
([
score
,
fp
])
for
(
label
,
label_pos_num
)
in
label_count
.
items
():
for
(
label
,
label_pos_num
)
in
label_count
.
items
():
if
label_pos_num
==
0
or
label
not
in
true_pos
:
if
label_pos_num
==
0
or
label
not
in
true_pos
:
continue
continue
label_true_pos
=
true_pos
[
label
]
label_true_pos
=
true_pos
[
label
]
label_false_pos
=
false_pos
[
label
]
label_false_pos
=
false_pos
[
label
]
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录