Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
cdf2579d
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看板
未验证
提交
cdf2579d
编写于
10月 31, 2018
作者:
T
Tao Luo
提交者:
GitHub
10月 31, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #14053 from jczaja/prv-seqpool-max
Max Sequence pool optimization
上级
35915fc5
458b16f4
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
77 addition
and
15 deletion
+77
-15
paddle/fluid/API.spec
paddle/fluid/API.spec
+1
-1
paddle/fluid/operators/math/sequence_pooling.cc
paddle/fluid/operators/math/sequence_pooling.cc
+44
-4
paddle/fluid/operators/math/sequence_pooling.cu
paddle/fluid/operators/math/sequence_pooling.cu
+1
-1
paddle/fluid/operators/math/sequence_pooling.h
paddle/fluid/operators/math/sequence_pooling.h
+1
-1
paddle/fluid/operators/sequence_pool_op.cc
paddle/fluid/operators/sequence_pool_op.cc
+1
-0
paddle/fluid/operators/sequence_pool_op.h
paddle/fluid/operators/sequence_pool_op.h
+11
-6
python/paddle/fluid/layers/nn.py
python/paddle/fluid/layers/nn.py
+4
-2
python/paddle/fluid/tests/unittests/test_seq_pool.py
python/paddle/fluid/tests/unittests/test_seq_pool.py
+14
-0
未找到文件。
paddle/fluid/API.spec
浏览文件 @
cdf2579d
...
...
@@ -64,7 +64,7 @@ paddle.fluid.layers.chunk_eval ArgSpec(args=['input', 'label', 'chunk_scheme', '
paddle.fluid.layers.sequence_conv ArgSpec(args=['input', 'num_filters', 'filter_size', 'filter_stride', 'padding', 'bias_attr', 'param_attr', 'act', 'name'], varargs=None, keywords=None, defaults=(3, 1, None, None, None, None, None))
paddle.fluid.layers.conv2d ArgSpec(args=['input', 'num_filters', 'filter_size', 'stride', 'padding', 'dilation', 'groups', 'param_attr', 'bias_attr', 'use_cudnn', 'act', 'name'], varargs=None, keywords=None, defaults=(1, 0, 1, None, None, None, True, None, None))
paddle.fluid.layers.conv3d ArgSpec(args=['input', 'num_filters', 'filter_size', 'stride', 'padding', 'dilation', 'groups', 'param_attr', 'bias_attr', 'use_cudnn', 'act', 'name'], varargs=None, keywords=None, defaults=(1, 0, 1, None, None, None, True, None, None))
paddle.fluid.layers.sequence_pool ArgSpec(args=['input', 'pool_type'
], varargs=None, keywords=None, defaults=None
)
paddle.fluid.layers.sequence_pool ArgSpec(args=['input', 'pool_type'
, 'is_test'], varargs=None, keywords=None, defaults=(False,)
)
paddle.fluid.layers.sequence_softmax ArgSpec(args=['input', 'use_cudnn', 'name'], varargs=None, keywords=None, defaults=(False, None))
paddle.fluid.layers.softmax ArgSpec(args=['input', 'use_cudnn', 'name'], varargs=None, keywords=None, defaults=(True, None))
paddle.fluid.layers.pool2d ArgSpec(args=['input', 'pool_size', 'pool_type', 'pool_stride', 'pool_padding', 'global_pooling', 'use_cudnn', 'ceil_mode', 'name'], varargs=None, keywords=None, defaults=(-1, 'max', 1, 0, False, True, False, None))
...
...
paddle/fluid/operators/math/sequence_pooling.cc
浏览文件 @
cdf2579d
...
...
@@ -31,7 +31,7 @@ template <typename T, int MajorType = Eigen::RowMajor,
typename
IndexType
=
Eigen
::
DenseIndex
>
using
EigenMatrix
=
framework
::
EigenMatrix
<
T
,
MajorType
,
IndexType
>
;
template
<
typename
T
>
template
<
typename
T
,
bool
is_test
>
class
MaxSeqPoolFunctor
{
public:
void
operator
()(
const
platform
::
CPUDeviceContext
&
context
,
...
...
@@ -70,7 +70,41 @@ class MaxSeqPoolFunctor {
}
}
};
// Instantisation of Max Sequence Pooling for test phase eg. no need to fill
// index buffer
template
<
typename
T
>
class
MaxSeqPoolFunctor
<
T
,
true
>
{
public:
void
operator
()(
const
platform
::
CPUDeviceContext
&
context
,
const
framework
::
LoDTensor
&
input
,
framework
::
Tensor
*
output
,
framework
::
Tensor
*
index
)
{
auto
in_dims
=
input
.
dims
();
auto
out_dims
=
output
->
dims
();
PADDLE_ENFORCE_GT
(
in_dims
.
size
(),
1
);
PADDLE_ENFORCE_GT
(
out_dims
.
size
(),
1
);
for
(
int64_t
i
=
1
;
i
<
in_dims
.
size
();
++
i
)
{
PADDLE_ENFORCE_EQ
(
in_dims
[
i
],
out_dims
[
i
]);
}
auto
starts
=
input
.
lod
()[
0
];
const
T
*
in_data
=
input
.
data
<
T
>
();
T
*
out_data
=
output
->
data
<
T
>
();
int64_t
num_seq
=
out_dims
[
0
];
int64_t
dim
=
output
->
numel
()
/
num_seq
;
for
(
int64_t
i
=
0
;
i
<
num_seq
;
++
i
)
{
std
::
memcpy
(
&
out_data
[
i
*
dim
],
&
in_data
[
starts
[
i
]
*
dim
],
dim
*
sizeof
(
T
));
for
(
size_t
j
=
starts
[
i
]
+
1
;
j
<
starts
[
i
+
1
];
++
j
)
{
for
(
int64_t
k
=
0
;
k
<
dim
;
++
k
)
{
if
(
in_data
[
j
*
dim
+
k
]
>
out_data
[
i
*
dim
+
k
])
{
out_data
[
i
*
dim
+
k
]
=
in_data
[
j
*
dim
+
k
];
}
}
}
}
}
};
template
<
typename
T
>
class
MaxSeqPoolGradFunctor
{
public:
...
...
@@ -188,11 +222,16 @@ class SequencePoolFunctor<platform::CPUDeviceContext, T> {
/* max pool has index output */
void
operator
()(
const
platform
::
CPUDeviceContext
&
context
,
const
std
::
string
pooltype
,
const
framework
::
LoDTensor
&
input
,
framework
::
Tensor
*
output
,
framework
::
Tensor
*
output
,
bool
is_test
,
framework
::
Tensor
*
index
=
nullptr
)
{
if
(
pooltype
==
"MAX"
)
{
math
::
MaxSeqPoolFunctor
<
T
>
max_pool
;
max_pool
(
context
,
input
,
output
,
index
);
if
(
is_test
)
{
math
::
MaxSeqPoolFunctor
<
T
,
true
>
max_pool
;
max_pool
(
context
,
input
,
output
,
index
);
}
else
{
math
::
MaxSeqPoolFunctor
<
T
,
false
>
max_pool
;
max_pool
(
context
,
input
,
output
,
index
);
}
return
;
}
if
(
pooltype
==
"LAST"
)
{
...
...
@@ -200,6 +239,7 @@ class SequencePoolFunctor<platform::CPUDeviceContext, T> {
last_pool
(
context
,
input
,
output
);
return
;
}
if
(
pooltype
==
"FIRST"
)
{
math
::
FirstSeqPoolFunctor
<
T
>
first_pool
;
first_pool
(
context
,
input
,
output
);
...
...
paddle/fluid/operators/math/sequence_pooling.cu
浏览文件 @
cdf2579d
...
...
@@ -133,7 +133,7 @@ class SequencePoolFunctor<platform::CUDADeviceContext, T> {
public:
void
operator
()(
const
platform
::
CUDADeviceContext
&
context
,
const
std
::
string
pooltype
,
const
framework
::
LoDTensor
&
input
,
framework
::
Tensor
*
output
,
framework
::
Tensor
*
output
,
bool
is_test
,
framework
::
Tensor
*
index
=
nullptr
)
{
auto
&
lod
=
input
.
lod
()[
0
];
const
size_t
item_dim
=
output
->
numel
()
/
output
->
dims
()[
0
];
...
...
paddle/fluid/operators/math/sequence_pooling.h
浏览文件 @
cdf2579d
...
...
@@ -28,7 +28,7 @@ class SequencePoolFunctor {
/* max pool has index output */
void
operator
()(
const
DeviceContext
&
context
,
const
std
::
string
pooltype
,
const
framework
::
LoDTensor
&
input
,
framework
::
Tensor
*
output
,
framework
::
Tensor
*
index
=
nullptr
);
bool
is_test
=
false
,
framework
::
Tensor
*
index
=
nullptr
);
};
template
<
typename
DeviceContext
,
typename
T
>
...
...
paddle/fluid/operators/sequence_pool_op.cc
浏览文件 @
cdf2579d
...
...
@@ -47,6 +47,7 @@ class SequencePoolOpMaker : public framework::OpProtoAndCheckerMaker {
"(Tensor<int>) This tensor is used for the sequence max-pooling "
"to record the max indexes."
)
.
AsIntermediate
();
AddAttr
<
bool
>
(
"is_test"
,
""
).
SetDefault
(
false
);
AddAttr
<
std
::
string
>
(
"pooltype"
,
"(string, default 'AVERAGE') the pooling pooltype of SequencePoolOp."
)
...
...
paddle/fluid/operators/sequence_pool_op.h
浏览文件 @
cdf2579d
...
...
@@ -32,10 +32,6 @@ class SequencePoolKernel : public framework::OpKernel<T> {
auto
*
in
=
context
.
Input
<
LoDTensor
>
(
"X"
);
auto
*
out
=
context
.
Output
<
Tensor
>
(
"Out"
);
std
::
string
pooltype
=
context
.
Attr
<
std
::
string
>
(
"pooltype"
);
Tensor
*
index
=
nullptr
;
if
(
pooltype
==
"MAX"
)
{
index
=
context
.
Output
<
Tensor
>
(
"MaxIndex"
);
}
auto
dims
=
in
->
dims
();
auto
lod
=
in
->
lod
();
...
...
@@ -48,13 +44,22 @@ class SequencePoolKernel : public framework::OpKernel<T> {
dims
[
0
]
=
lod
[
0
].
size
()
-
1
;
out
->
Resize
({
dims
});
out
->
mutable_data
<
T
>
(
context
.
GetPlace
());
if
(
pooltype
==
"MAX"
)
{
Tensor
*
index
=
nullptr
;
const
bool
is_test
=
context
.
Attr
<
bool
>
(
"is_test"
);
// Do not create index buffer for inference (is_test) mode
// TODO(jczaja): Skip index buffer creation for other devices eg. GPU
if
(
pooltype
==
"MAX"
&&
(
is_test
==
false
||
platform
::
is_cpu_place
(
context
.
GetPlace
())
==
false
))
{
index
=
context
.
Output
<
Tensor
>
(
"MaxIndex"
);
index
->
Resize
({
dims
});
index
->
mutable_data
<
int
>
(
context
.
GetPlace
());
}
math
::
SequencePoolFunctor
<
DeviceContext
,
T
>
pool
;
pool
(
context
.
template
device_context
<
DeviceContext
>(),
pooltype
,
*
in
,
out
,
index
);
i
s_test
,
i
ndex
);
}
};
...
...
python/paddle/fluid/layers/nn.py
浏览文件 @
cdf2579d
...
...
@@ -1825,7 +1825,7 @@ def conv3d(input,
return
helper
.
append_activation
(
pre_act
)
def
sequence_pool
(
input
,
pool_type
):
def
sequence_pool
(
input
,
pool_type
,
is_test
=
False
):
"""
This function add the operator for sequence pooling.
It pools features of all time-steps of each instance, and is applied
...
...
@@ -1862,6 +1862,7 @@ def sequence_pool(input, pool_type):
input(variable): The input variable which is a LoDTensor.
pool_type (string): The pooling type of sequence_pool.
It supports average, sum, sqrt and max.
is_test(bool, Default False): Used distinguish training from scoring mode.
Returns:
The sequence pooling variable which is a Tensor.
...
...
@@ -1889,7 +1890,8 @@ def sequence_pool(input, pool_type):
inputs
=
{
"X"
:
input
},
outputs
=
{
"Out"
:
pool_out
,
"MaxIndex"
:
max_index
},
attrs
=
{
"pooltype"
:
pool_type
.
upper
()})
attrs
=
{
"pooltype"
:
pool_type
.
upper
(),
"is_test"
:
is_test
})
# when pool_type is max, variable max_index is initialized,
# so we stop the gradient explicitly here
...
...
python/paddle/fluid/tests/unittests/test_seq_pool.py
浏览文件 @
cdf2579d
...
...
@@ -184,6 +184,20 @@ class TestSeqMaxPool2D(TestSeqAvgPool2D):
out
[
i
]
=
np
.
reshape
(
np
.
amax
(
sub_x
,
axis
=
0
),
(
3
,
11
))
class
TestSeqMaxPool2DInference
(
TestSeqMaxPool2D
):
def
compute
(
self
,
x
,
offset
,
out
):
self
.
attrs
=
{
'pooltype'
:
"MAX"
,
'is_test'
:
True
}
for
i
in
range
(
len
(
offset
[
0
])
-
1
):
sub_x
=
np
.
reshape
(
x
[
offset
[
0
][
i
]:
offset
[
0
][
i
+
1
],
:],
(
-
1
,
3
*
11
))
out
[
i
]
=
np
.
reshape
(
np
.
amax
(
sub_x
,
axis
=
0
),
(
3
,
11
))
def
test_check_grad
(
self
):
"""Grad computation does not apply to Sequence MAX
Pool executed when is_test is true """
return
class
TestSeqLastPool2D
(
TestSeqAvgPool2D
):
def
compute
(
self
,
x
,
offset
,
out
):
self
.
attrs
=
{
'pooltype'
:
"LAST"
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录