Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle-Lite
提交
a23d5612
P
Paddle-Lite
项目概览
PaddlePaddle
/
Paddle-Lite
通知
331
Star
4
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
271
列表
看板
标记
里程碑
合并请求
78
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle-Lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
271
Issue
271
列表
看板
标记
里程碑
合并请求
78
合并请求
78
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
a23d5612
编写于
6月 19, 2019
作者:
N
NazgulLee
提交者:
GitHub
6月 19, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
handle exclusive param for pool3*3 (#1691)
上级
7c216695
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
57 addition
and
36 deletion
+57
-36
src/operators/kernel/central-arm-func/pool_arm_func.h
src/operators/kernel/central-arm-func/pool_arm_func.h
+5
-4
src/operators/math/pooling.h
src/operators/math/pooling.h
+6
-1
src/operators/math/pooling3x3.cpp
src/operators/math/pooling3x3.cpp
+41
-31
src/operators/op_param.h
src/operators/op_param.h
+4
-0
test/operators/test_pool_op.cpp
test/operators/test_pool_op.cpp
+1
-0
未找到文件。
src/operators/kernel/central-arm-func/pool_arm_func.h
浏览文件 @
a23d5612
...
...
@@ -32,6 +32,7 @@ void PoolCompute(const PoolParam<CPU> ¶m) {
std
::
vector
<
int
>
ksize
=
param
.
Ksize
();
std
::
vector
<
int
>
strides
=
param
.
Strides
();
std
::
vector
<
int
>
paddings
=
param
.
Paddings
();
const
bool
exclusive
=
param
.
isExclusive
();
if
(
param
.
isGlobalPooling
())
{
for
(
size_t
i
=
0
;
i
<
ksize
.
size
();
++
i
)
{
paddings
[
i
]
=
0
;
...
...
@@ -41,17 +42,17 @@ void PoolCompute(const PoolParam<CPU> ¶m) {
if
(
ksize
[
0
]
==
3
&&
ksize
[
0
]
==
ksize
[
1
])
{
if
(
pooling_type
==
"max"
&&
strides
[
0
]
==
strides
[
1
])
{
if
(
strides
[
0
]
==
1
)
{
math
::
Pooling3x3
<
MAX
,
1
>
()(
*
input
,
paddings
,
output
);
math
::
Pooling3x3
<
MAX
,
1
>
()(
*
input
,
paddings
,
exclusive
,
output
);
}
else
if
(
strides
[
0
]
==
2
)
{
math
::
Pooling3x3
<
MAX
,
2
>
()(
*
input
,
paddings
,
output
);
math
::
Pooling3x3
<
MAX
,
2
>
()(
*
input
,
paddings
,
exclusive
,
output
);
}
else
{
math
::
Pooling
<
MAX
>
()(
*
input
,
ksize
,
strides
,
paddings
,
output
);
}
}
else
if
(
pooling_type
==
"avg"
&&
strides
[
0
]
==
strides
[
1
])
{
if
(
strides
[
0
]
==
1
)
{
math
::
Pooling3x3
<
AVG
,
1
>
()(
*
input
,
paddings
,
output
);
math
::
Pooling3x3
<
AVG
,
1
>
()(
*
input
,
paddings
,
exclusive
,
output
);
}
else
if
(
strides
[
0
]
==
2
)
{
math
::
Pooling3x3
<
AVG
,
2
>
()(
*
input
,
paddings
,
output
);
math
::
Pooling3x3
<
AVG
,
2
>
()(
*
input
,
paddings
,
exclusive
,
output
);
}
else
{
math
::
Pooling
<
AVG
>
()(
*
input
,
ksize
,
strides
,
paddings
,
output
);
}
...
...
src/operators/math/pooling.h
浏览文件 @
a23d5612
...
...
@@ -41,6 +41,9 @@ struct PoolingVal {
return
*
this
;
}
inline
float
Value
()
{
return
(
count
>
0
)
?
val
:
0.
f
;
}
inline
float
ExclusiveSum
(
int
total
)
{
return
((
count
>
0
)
?
val
:
0.
f
)
*
total
;
}
};
template
<
>
...
...
@@ -54,6 +57,7 @@ struct PoolingVal<AVG> {
return
*
this
;
}
inline
float
Value
()
{
return
(
count
>
0
)
?
val
*
(
1.
f
/
count
)
:
0.
f
;
}
inline
float
ExclusiveSum
(
int
total
)
{
return
(
count
>
0
)
?
val
:
0.
f
;
}
};
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
...
...
@@ -172,7 +176,8 @@ struct Pooling2x2 {
template
<
PoolingType
P
,
int
Stride
>
struct
Pooling3x3
{
void
operator
()(
const
framework
::
Tensor
&
input
,
const
std
::
vector
<
int
>
&
paddings
,
framework
::
Tensor
*
output
);
const
std
::
vector
<
int
>
&
paddings
,
const
bool
exclusive
,
framework
::
Tensor
*
output
);
};
template
<
PoolingType
P
,
int
Stride
>
...
...
src/operators/math/pooling3x3.cpp
浏览文件 @
a23d5612
...
...
@@ -23,19 +23,19 @@ namespace paddle_mobile {
namespace
operators
{
namespace
math
{
#define POOLING3X3_NORMAL_BORDER(start, end
)
\
for (int w = start; w < end; ++w) { \
const int w_in_start = -padding_w + w * Stride; \
const int w_in_end = w_in_start + 3; \
const int w_start = w_in_start > 0 ? w_in_start : 0; \
const int w_end = w_in_end < input_w ? w_in_end : input_w; \
PoolingVal<P> val; \
for (int h_in = h_start; h_in < h_end; ++h_in) { \
for (int w_in = w_start; w_in < w_end; ++w_in) { \
val += input[h_in * input_w + w_in]; \
} \
} \
output_ptr[w] =
val.Value();
\
#define POOLING3X3_NORMAL_BORDER(start, end
, exclusive)
\
for (int w = start; w < end; ++w) {
\
const int w_in_start = -padding_w + w * Stride;
\
const int w_in_end = w_in_start + 3;
\
const int w_start = w_in_start > 0 ? w_in_start : 0;
\
const int w_end = w_in_end < input_w ? w_in_end : input_w;
\
PoolingVal<P> val;
\
for (int h_in = h_start; h_in < h_end; ++h_in) {
\
for (int w_in = w_start; w_in < w_end; ++w_in) {
\
val += input[h_in * input_w + w_in];
\
}
\
}
\
output_ptr[w] =
exclusive ? val.Value() : val.ExclusiveSum(9) / 9.f;
\
}
template
<
PoolingType
P
,
int
Stride
=
1
>
...
...
@@ -80,7 +80,8 @@ template <PoolingType P, int Stride>
inline
void
Pooling3x3NormalRow
(
const
float
*
input
,
const
int
h_output
,
const
int
input_h
,
const
int
input_w
,
const
int
padding_h
,
const
int
padding_w
,
const
int
output_w
,
float
*
output
)
{
const
int
output_w
,
const
bool
exclusive
,
float
*
output
)
{
const
int
h_in_start
=
-
padding_h
+
h_output
*
Stride
;
const
int
h_in_end
=
h_in_start
+
3
;
const
int
h_start
=
h_in_start
>
0
?
h_in_start
:
0
;
...
...
@@ -97,13 +98,14 @@ inline void Pooling3x3NormalRow(const float *input, const int h_output,
const
int
valid_w
=
valid_w_end
-
valid_w_start
;
// border left
POOLING3X3_NORMAL_BORDER
(
0
,
valid_w_start
)
POOLING3X3_NORMAL_BORDER
(
0
,
valid_w_start
,
exclusive
)
// middle
int
output_tiles
=
(
valid_w_end
-
valid_w_start
)
/
6
;
int
output_tiles_w
=
output_tiles
*
6
;
Pooling3x3NormalRowLoadInput
<
P
,
Stride
>
PoolingCompute
;
float32x4x2_t
x0
,
x1
,
x2
,
y0
;
float32x4_t
post
=
vdupq_n_f32
(
1.
f
/
(
3
*
(
h_end
-
h_start
)));
float32x4_t
post
=
exclusive
?
vdupq_n_f32
(
1.
f
/
(
3
*
(
h_end
-
h_start
)))
:
vdupq_n_f32
(
1.
f
/
9
);
for
(
int
w
=
0
;
w
<
output_tiles_w
;
w
+=
6
)
{
int
output_offset
=
valid_w_start
+
w
;
int
input_w_offset
=
output_offset
*
Stride
-
padding_w
;
...
...
@@ -150,13 +152,13 @@ inline void Pooling3x3NormalRow(const float *input, const int h_output,
}
}
// border right
POOLING3X3_NORMAL_BORDER
(
valid_w_end
,
output_w
)
POOLING3X3_NORMAL_BORDER
(
valid_w_end
,
output_w
,
exclusive
)
}
template
<
PoolingType
P
>
struct
Pooling3x3
<
P
,
1
>
{
inline
void
operator
()(
const
framework
::
Tensor
&
input
,
const
std
::
vector
<
int
>
&
paddings
,
const
std
::
vector
<
int
>
&
paddings
,
const
bool
exclusive
,
framework
::
Tensor
*
output
)
{
const
float
*
input_data
=
input
.
data
<
float
>
();
float
*
output_data
=
output
->
mutable_data
<
float
>
();
...
...
@@ -184,7 +186,7 @@ struct Pooling3x3<P, 1> {
// top
for
(
int
h
=
0
;
h
<
valid_h_start
;
++
h
)
{
Pooling3x3NormalRow
<
P
,
1
>
(
input_ptr
,
h
,
input_h
,
input_w
,
padding_h
,
padding_w
,
output_w
,
output_ptr
);
padding_w
,
output_w
,
exclusive
,
output_ptr
);
}
// valid
int
output_w_tiles
=
valid_w
/
6
;
...
...
@@ -218,7 +220,8 @@ struct Pooling3x3<P, 1> {
output_ptr2
[
w
]
=
0.
f
;
output_ptr3
[
w
]
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc12
=
vPoolPre_f32
<
P
>
(
row1
,
row2
);
acc34
=
vPoolPre_f32
<
P
>
(
row3
,
row4
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
acc12
);
...
...
@@ -526,7 +529,8 @@ struct Pooling3x3<P, 1> {
*
output_ptr2
=
0.
f
;
*
output_ptr3
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc12
=
vPoolPre_f32
<
P
>
(
row1
,
row2
);
acc34
=
vPoolPre_f32
<
P
>
(
row3
,
row4
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
acc12
);
...
...
@@ -578,7 +582,8 @@ struct Pooling3x3<P, 1> {
if
(
padding
>=
3
)
{
output_ptr0
[
w
]
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
row1
);
acc0
=
vPoolPre_f32
<
P
>
(
acc0
,
row2
);
acc0
=
vpPoolPre_f32
<
P
>
(
acc0
,
acc0
);
...
...
@@ -718,7 +723,8 @@ struct Pooling3x3<P, 1> {
if
(
padding
>=
3
)
{
*
output_ptr0
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
row1
);
acc0
=
vPoolPre_f32
<
P
>
(
acc0
,
row2
);
acc0
=
vpPoolPre_f32
<
P
>
(
acc0
,
acc0
);
...
...
@@ -735,7 +741,7 @@ struct Pooling3x3<P, 1> {
// pad bottom
for
(
int
h
=
valid_h_end
;
h
<
output_h
;
++
h
)
{
Pooling3x3NormalRow
<
P
,
1
>
(
input_ptr
,
h
,
input_h
,
input_w
,
padding_h
,
padding_w
,
output_w
,
output_ptr
);
padding_w
,
output_w
,
exclusive
,
output_ptr
);
}
}
}
...
...
@@ -745,7 +751,7 @@ struct Pooling3x3<P, 1> {
template
<
PoolingType
P
>
struct
Pooling3x3
<
P
,
2
>
{
inline
void
operator
()(
const
framework
::
Tensor
&
input
,
const
std
::
vector
<
int
>
&
paddings
,
const
std
::
vector
<
int
>
&
paddings
,
const
bool
exclusive
,
framework
::
Tensor
*
output
)
{
const
float
*
input_data
=
input
.
data
<
float
>
();
float
*
output_data
=
output
->
mutable_data
<
float
>
();
...
...
@@ -784,7 +790,7 @@ struct Pooling3x3<P, 2> {
// top
for
(
int
h
=
0
;
h
<
valid_h_start
;
++
h
)
{
Pooling3x3NormalRow
<
P
,
2
>
(
input_ptr
,
h
,
input_h
,
input_w
,
padding_h
,
padding_w
,
output_w
,
output_ptr
);
padding_w
,
output_w
,
exclusive
,
output_ptr
);
}
// valid
int
output_w_tiles
=
valid_w
/
6
;
...
...
@@ -818,7 +824,8 @@ struct Pooling3x3<P, 2> {
output_ptr1
[
w
]
=
0.
f
;
output_ptr2
[
w
]
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
row1
);
acc1
=
vPoolPre_f32
<
P
>
(
row2
,
row3
);
acc2
=
vPoolPre_f32
<
P
>
(
row4
,
row5
);
...
...
@@ -1097,7 +1104,8 @@ struct Pooling3x3<P, 2> {
*
output_ptr1
=
0.
f
;
*
output_ptr2
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
row1
);
acc1
=
vPoolPre_f32
<
P
>
(
row2
,
row3
);
acc2
=
vPoolPre_f32
<
P
>
(
row4
,
row5
);
...
...
@@ -1141,7 +1149,8 @@ struct Pooling3x3<P, 2> {
if
(
padding
>=
3
)
{
output_ptr0
[
w
]
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
row1
);
acc0
=
vPoolPre_f32
<
P
>
(
acc0
,
row2
);
if
(
padding
==
1
)
{
...
...
@@ -1271,7 +1280,8 @@ struct Pooling3x3<P, 2> {
if
(
padding
>=
3
)
{
*
output_ptr0
=
0.
f
;
}
else
{
post
=
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)));
post
=
exclusive
?
vdup_n_f32
(
1.
f
/
(
3
*
(
3
-
padding
)))
:
vdup_n_f32
(
1.
f
/
9
);
acc0
=
vPoolPre_f32
<
P
>
(
row0
,
row1
);
acc0
=
vPoolPre_f32
<
P
>
(
acc0
,
row2
);
if
(
padding
==
1
)
{
...
...
@@ -1287,7 +1297,7 @@ struct Pooling3x3<P, 2> {
// bottom
for
(
int
h
=
valid_h_end
;
h
<
output_h
;
++
h
)
{
Pooling3x3NormalRow
<
P
,
2
>
(
input_ptr
,
h
,
input_h
,
input_w
,
padding_h
,
padding_w
,
output_w
,
output_ptr
);
padding_w
,
output_w
,
exclusive
,
output_ptr
);
}
}
}
...
...
src/operators/op_param.h
浏览文件 @
a23d5612
...
...
@@ -909,6 +909,7 @@ class PoolParam : public OpParam {
paddings_
=
GetAttr
<
vector
<
int
>>
(
"paddings"
,
attrs
);
ceil_mode_
=
GetAttr
<
bool
>
(
"ceil_mode"
,
attrs
);
global_pooling_
=
GetAttr
<
bool
>
(
"global_pooling"
,
attrs
);
exclusive_
=
GetAttr
<
bool
>
(
"exclusive"
,
attrs
);
}
const
GType
*
Input
()
const
{
return
input_
;
}
...
...
@@ -927,6 +928,8 @@ class PoolParam : public OpParam {
bool
isGlobalPooling
()
const
{
return
global_pooling_
;
}
bool
isExclusive
()
const
{
return
exclusive_
;
}
private:
GType
*
input_
;
GType
*
output_
;
...
...
@@ -936,6 +939,7 @@ class PoolParam : public OpParam {
vector
<
int
>
paddings_
;
bool
ceil_mode_
;
bool
global_pooling_
=
false
;
bool
exclusive_
=
true
;
#ifdef PADDLE_MOBILE_FPGA
private:
...
...
test/operators/test_pool_op.cpp
浏览文件 @
a23d5612
...
...
@@ -62,6 +62,7 @@ int TestPoolOp(int in_channels, int in_height, int in_width) {
attrs
[
"ceil_mode"
].
Set
<
bool
>
(
true
);
// attrs["ceil_mode"].Set<bool>(false);
attrs
[
"global_pooling"
].
Set
<
bool
>
(
false
);
attrs
[
"exclusive"
].
Set
<
bool
>
(
true
);
auto
*
op
=
new
operators
::
PoolOp
<
CPU
,
float
>
(
"pool2d"
,
inputs
,
outputs
,
attrs
,
scope
.
get
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录