Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
89e511f4
P
Paddle
项目概览
Crayon鑫
/
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看板
提交
89e511f4
编写于
7月 16, 2018
作者:
L
Luo Tao
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop' into demo
上级
2a672d24
c5619bbc
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
75 addition
and
23 deletion
+75
-23
paddle/fluid/operators/auc_op.cc
paddle/fluid/operators/auc_op.cc
+15
-0
paddle/fluid/operators/auc_op.h
paddle/fluid/operators/auc_op.h
+14
-17
python/paddle/fluid/layers/metric_op.py
python/paddle/fluid/layers/metric_op.py
+25
-4
python/paddle/fluid/tests/unittests/test_auc_op.py
python/paddle/fluid/tests/unittests/test_auc_op.py
+21
-2
未找到文件。
paddle/fluid/operators/auc_op.cc
浏览文件 @
89e511f4
...
...
@@ -35,7 +35,14 @@ class AucOp : public framework::OperatorWithKernel {
PADDLE_ENFORCE_EQ
(
inference_height
,
label_height
,
"Out and Label should have same height."
);
int
num_thres
=
ctx
->
Attrs
().
Get
<
int
>
(
"num_thresholds"
);
ctx
->
SetOutputDim
(
"AUC"
,
{
1
});
ctx
->
SetOutputDim
(
"TPOut"
,
{
num_thres
});
ctx
->
SetOutputDim
(
"TNOut"
,
{
num_thres
});
ctx
->
SetOutputDim
(
"FPOut"
,
{
num_thres
});
ctx
->
SetOutputDim
(
"FNOut"
,
{
num_thres
});
ctx
->
ShareLoD
(
"Out"
,
/*->*/
"AUC"
);
}
...
...
@@ -63,10 +70,18 @@ class AucOpMaker : public framework::OpProtoAndCheckerMaker {
AddInput
(
"Label"
,
"A 2D int tensor indicating the label of the training data."
"The height is batch size and width is always 1."
);
AddInput
(
"TP"
,
"True-Positive value."
);
AddInput
(
"FP"
,
"False-Positive value."
);
AddInput
(
"TN"
,
"True-Negative value."
);
AddInput
(
"FN"
,
"False-Negative value."
);
// TODO(typhoonzero): support weight input
AddOutput
(
"AUC"
,
"A scalar representing the "
"current area-under-the-curve."
);
AddOutput
(
"TPOut"
,
"True-Positive value."
);
AddOutput
(
"FPOut"
,
"False-Positive value."
);
AddOutput
(
"TNOut"
,
"True-Negative value."
);
AddOutput
(
"FNOut"
,
"False-Negative value."
);
AddAttr
<
std
::
string
>
(
"curve"
,
"Curve type, can be 'ROC' or 'PR'."
)
.
SetDefault
(
"ROC"
);
...
...
paddle/fluid/operators/auc_op.h
浏览文件 @
89e511f4
...
...
@@ -34,6 +34,12 @@ class AucKernel : public framework::OpKernel<T> {
auto
*
inference
=
ctx
.
Input
<
Tensor
>
(
"Out"
);
auto
*
label
=
ctx
.
Input
<
Tensor
>
(
"Label"
);
auto
*
auc
=
ctx
.
Output
<
Tensor
>
(
"AUC"
);
// Only use output var for now, make sure it's persistable and
// not cleaned up for each batch.
auto
*
true_positive
=
ctx
.
Output
<
Tensor
>
(
"TPOut"
);
auto
*
false_positive
=
ctx
.
Output
<
Tensor
>
(
"FPOut"
);
auto
*
true_negative
=
ctx
.
Output
<
Tensor
>
(
"TNOut"
);
auto
*
false_negative
=
ctx
.
Output
<
Tensor
>
(
"FNOut"
);
float
*
auc_data
=
auc
->
mutable_data
<
float
>
(
ctx
.
GetPlace
());
...
...
@@ -54,19 +60,10 @@ class AucKernel : public framework::OpKernel<T> {
const
T
*
inference_data
=
inference
->
data
<
T
>
();
const
int64_t
*
label_data
=
label
->
data
<
int64_t
>
();
// Create local tensor for storing the curve: TP, FN, TN, FP
// TODO(typhoonzero): use eigen op to caculate these values.
Tensor
true_positive
,
false_positive
,
true_negative
,
false_negative
;
true_positive
.
Resize
({
num_thresholds
});
false_negative
.
Resize
({
num_thresholds
});
true_negative
.
Resize
({
num_thresholds
});
false_positive
.
Resize
({
num_thresholds
});
int64_t
*
tp_data
=
true_positive
.
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
int64_t
*
fn_data
=
false_negative
.
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
int64_t
*
tn_data
=
true_negative
.
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
int64_t
*
fp_data
=
false_positive
.
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
auto
*
tp_data
=
true_positive
->
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
auto
*
fn_data
=
false_negative
->
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
auto
*
tn_data
=
true_negative
->
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
auto
*
fp_data
=
false_positive
->
mutable_data
<
int64_t
>
(
ctx
.
GetPlace
());
for
(
int
idx_thresh
=
0
;
idx_thresh
<
num_thresholds
;
idx_thresh
++
)
{
// caculate TP, FN, TN, FP for current thresh
...
...
@@ -91,10 +88,10 @@ class AucKernel : public framework::OpKernel<T> {
}
}
// store rates
tp_data
[
idx_thresh
]
=
tp
;
fn_data
[
idx_thresh
]
=
fn
;
tn_data
[
idx_thresh
]
=
tn
;
fp_data
[
idx_thresh
]
=
fp
;
tp_data
[
idx_thresh
]
+
=
tp
;
fn_data
[
idx_thresh
]
+
=
fn
;
tn_data
[
idx_thresh
]
+
=
tn
;
fp_data
[
idx_thresh
]
+
=
fp
;
}
// epsilon to avoid divide by zero.
float
epsilon
=
1e-6
;
...
...
python/paddle/fluid/layers/metric_op.py
浏览文件 @
89e511f4
...
...
@@ -76,7 +76,7 @@ def accuracy(input, label, k=1, correct=None, total=None):
return
acc_out
def
auc
(
input
,
label
,
curve
=
'ROC'
,
num_thresholds
=
200
):
def
auc
(
input
,
label
,
curve
=
'ROC'
,
num_thresholds
=
200
,
topk
=
1
):
"""
**Area Under the Curve (AUC) Layer**
...
...
@@ -102,6 +102,7 @@ def auc(input, label, curve='ROC', num_thresholds=200):
curve(str): Curve type, can be 'ROC' or 'PR'. Default 'ROC'.
num_thresholds(int): The number of thresholds to use when discretizing
the roc curve. Default 200.
topk(int): only topk number of prediction output will be used for auc.
Returns:
Variable: A scalar representing the current AUC.
...
...
@@ -115,7 +116,7 @@ def auc(input, label, curve='ROC', num_thresholds=200):
"""
warnings
.
warn
(
"This interface not recommended, fluid.layers.auc compute the auc at every minibatch,
\
"This interface
is
not recommended, fluid.layers.auc compute the auc at every minibatch,
\
but can not aggregate them and get the pass AUC, because pass
\
auc can not be averaged with weighted from the minibatch auc value.
\
Please use fluid.metrics.Auc, it can compute the auc value via Python natively,
\
...
...
@@ -125,14 +126,34 @@ def auc(input, label, curve='ROC', num_thresholds=200):
topk_indices
=
helper
.
create_tmp_variable
(
dtype
=
"int64"
)
topk_out
,
topk_indices
=
nn
.
topk
(
input
,
k
=
k
)
auc_out
=
helper
.
create_tmp_variable
(
dtype
=
"float32"
)
# make tp, tn, fp, fn persistable, so that can accumulate all batches.
tp
=
helper
.
create_global_variable
(
persistable
=
True
)
tn
=
helper
.
create_global_variable
(
persistable
=
True
)
fp
=
helper
.
create_global_variable
(
persistable
=
True
)
fn
=
helper
.
create_global_variable
(
persistable
=
True
)
for
var
in
[
tp
,
tn
,
fp
,
fn
]:
helper
.
set_variable_initializer
(
var
,
Constant
(
value
=
0.0
,
force_cpu
=
True
))
helper
.
append_op
(
type
=
"auc"
,
inputs
=
{
"Out"
:
[
topk_out
],
"Indices"
:
[
topk_indices
],
"Label"
:
[
label
]
"Label"
:
[
label
],
"TP"
:
[
tp
],
"TN"
:
[
tn
],
"FP"
:
[
fp
],
"FN"
:
[
fn
]
},
attrs
=
{
"curve"
:
curve
,
"num_thresholds"
:
num_thresholds
},
outputs
=
{
"AUC"
:
[
auc_out
],
})
outputs
=
{
"AUC"
:
[
auc_out
],
"TPOut"
:
[
tp
],
"TNOut"
:
[
tn
],
"FPOut"
:
[
fp
],
"FNOut"
:
[
fn
]
})
return
auc_out
python/paddle/fluid/tests/unittests/test_auc_op.py
浏览文件 @
89e511f4
...
...
@@ -24,7 +24,20 @@ class TestAucOp(OpTest):
indices
=
np
.
random
.
randint
(
0
,
2
,
(
128
,
2
))
labels
=
np
.
random
.
randint
(
0
,
2
,
(
128
,
1
))
num_thresholds
=
200
self
.
inputs
=
{
'Out'
:
pred
,
'Indices'
:
indices
,
'Label'
:
labels
}
tp
=
np
.
zeros
((
num_thresholds
,
)).
astype
(
"int64"
)
tn
=
np
.
zeros
((
num_thresholds
,
)).
astype
(
"int64"
)
fp
=
np
.
zeros
((
num_thresholds
,
)).
astype
(
"int64"
)
fn
=
np
.
zeros
((
num_thresholds
,
)).
astype
(
"int64"
)
self
.
inputs
=
{
'Out'
:
pred
,
'Indices'
:
indices
,
'Label'
:
labels
,
'TP'
:
tp
,
'TN'
:
tn
,
'FP'
:
fp
,
'FN'
:
fn
}
self
.
attrs
=
{
'curve'
:
'ROC'
,
'num_thresholds'
:
num_thresholds
}
# NOTE: sklearn use a different way to generate thresholds
# which will cause the result differs slightly:
...
...
@@ -71,7 +84,13 @@ class TestAucOp(OpTest):
y
=
(
tpr
[:
num_thresholds
-
1
]
+
tpr
[
1
:])
/
2.0
auc_value
=
np
.
sum
(
x
*
y
)
self
.
outputs
=
{
'AUC'
:
auc_value
}
self
.
outputs
=
{
'AUC'
:
auc_value
,
'TPOut'
:
tp_list
,
'FNOut'
:
fn_list
,
'TNOut'
:
tn_list
,
'FPOut'
:
fp_list
}
def
test_check_output
(
self
):
self
.
check_output
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录