Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
c975fe1b
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看板
未验证
提交
c975fe1b
编写于
11月 28, 2017
作者:
Q
Qiao Longfei
提交者:
GitHub
11月 28, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
batch norm support matrix input (#5980)
* batch norm support matrix input * update gpu code * format code
上级
23b3fef0
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
93 addition
and
44 deletion
+93
-44
paddle/operators/batch_norm_op.cc
paddle/operators/batch_norm_op.cc
+8
-7
paddle/operators/batch_norm_op.cu.cc
paddle/operators/batch_norm_op.cu.cc
+19
-12
python/paddle/v2/fluid/tests/book/test_image_classification_train.py
...le/v2/fluid/tests/book/test_image_classification_train.py
+1
-2
python/paddle/v2/fluid/tests/test_batch_norm_op.py
python/paddle/v2/fluid/tests/test_batch_norm_op.py
+47
-13
python/paddle/v2/fluid/tests/test_image_classification_layer.py
.../paddle/v2/fluid/tests/test_image_classification_layer.py
+18
-10
未找到文件。
paddle/operators/batch_norm_op.cc
浏览文件 @
c975fe1b
...
...
@@ -62,13 +62,14 @@ class BatchNormOp : public framework::OperatorWithKernel {
const
auto
x_dims
=
ctx
->
GetInputDim
(
"X"
);
const
TensorFormat
tensor_format
=
StringToTensorFormat
(
ctx
->
Attrs
().
Get
<
std
::
string
>
(
"tensor_format"
));
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
2
&&
x_dims
.
size
()
<=
5
,
"Input X must have 2 to 5 dimensions."
);
const
int
C
=
(
tensor_format
==
TensorFormat
::
NCHW
?
x_dims
[
1
]
:
x_dims
[
x_dims
.
size
()
-
1
]);
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
3
&&
x_dims
.
size
()
<=
5
,
"Input X must have 3 to 5 dimensions."
);
PADDLE_ENFORCE_EQ
(
ctx
->
GetInputDim
(
"Scale"
).
size
(),
1UL
);
PADDLE_ENFORCE_EQ
(
ctx
->
GetInputDim
(
"Scale"
)[
0
],
C
);
PADDLE_ENFORCE_EQ
(
ctx
->
GetInputDim
(
"Bias"
).
size
(),
1UL
);
...
...
@@ -146,8 +147,8 @@ class BatchNormKernel<platform::CPUPlace, T> : public framework::OpKernel<T> {
const
auto
*
x
=
ctx
.
Input
<
Tensor
>
(
"X"
);
const
auto
&
x_dims
=
x
->
dims
();
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
3
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
3
and 5"
);
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
2
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
2
and 5"
);
const
int
N
=
x_dims
[
0
];
const
int
C
=
(
tensor_format
==
TensorFormat
::
NCHW
?
x_dims
[
1
]
...
...
@@ -339,8 +340,8 @@ class BatchNormGradKernel<platform::CPUPlace, T>
// Get the size for each dimension.
// NCHW [batch_size, in_channels, in_height, in_width]
const
auto
&
x_dims
=
x
->
dims
();
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
3
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
3
and 5"
);
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
2
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
2
and 5"
);
const
int
N
=
x_dims
[
0
];
const
int
C
=
(
tensor_format
==
TensorFormat
::
NCHW
?
x_dims
[
1
]
...
...
paddle/operators/batch_norm_op.cu.cc
浏览文件 @
c975fe1b
...
...
@@ -29,14 +29,21 @@ void ExtractNCWHD(const framework::DDim &dims,
const
TensorFormat
&
tensor_format
,
int
*
N
,
int
*
C
,
int
*
H
,
int
*
W
,
int
*
D
)
{
*
N
=
dims
[
0
];
*
C
=
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
1
]
:
dims
[
dims
.
size
()
-
1
];
*
H
=
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
2
]
:
dims
[
1
];
*
W
=
dims
.
size
()
>
3
?
(
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
3
]
:
dims
[
2
])
:
1
;
*
D
=
dims
.
size
()
>
4
?
(
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
4
]
:
dims
[
3
])
:
1
;
if
(
dims
.
size
()
==
2
)
{
*
C
=
dims
[
1
];
*
H
=
1
;
*
W
=
1
;
*
D
=
1
;
}
else
{
*
C
=
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
1
]
:
dims
[
dims
.
size
()
-
1
];
*
H
=
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
2
]
:
dims
[
1
];
*
W
=
dims
.
size
()
>
3
?
(
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
3
]
:
dims
[
2
])
:
1
;
*
D
=
dims
.
size
()
>
4
?
(
tensor_format
==
TensorFormat
::
NCHW
?
dims
[
4
]
:
dims
[
3
])
:
1
;
}
}
template
<
typename
T
>
...
...
@@ -56,8 +63,8 @@ class BatchNormKernel<platform::GPUPlace, T> : public framework::OpKernel<T> {
// NCHW [batch_size, in_channels, in_height, in_width]
const
auto
*
x
=
ctx
.
Input
<
Tensor
>
(
"X"
);
const
auto
&
x_dims
=
x
->
dims
();
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
3
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
3
and 5"
);
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
2
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
2
and 5"
);
int
N
,
C
,
H
,
W
,
D
;
ExtractNCWHD
(
x_dims
,
tensor_format
,
&
N
,
&
C
,
&
H
,
&
W
,
&
D
);
...
...
@@ -180,8 +187,8 @@ class BatchNormGradKernel<platform::GPUPlace, T>
const
auto
&
x_dims
=
x
->
dims
();
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
3
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
3
and 5"
);
PADDLE_ENFORCE
(
x_dims
.
size
()
>=
2
&&
x_dims
.
size
()
<=
5
,
"The Input dim size should be between
2
and 5"
);
int
N
,
C
,
H
,
W
,
D
;
ExtractNCWHD
(
x_dims
,
tensor_format
,
&
N
,
&
C
,
&
H
,
&
W
,
&
D
);
...
...
python/paddle/v2/fluid/tests/book/test_image_classification_train.py
浏览文件 @
c975fe1b
...
...
@@ -69,8 +69,7 @@ def vgg16_bn_drop(input):
drop
=
fluid
.
layers
.
dropout
(
x
=
conv5
,
dropout_prob
=
0.5
)
fc1
=
fluid
.
layers
.
fc
(
input
=
drop
,
size
=
512
,
act
=
None
)
reshape1
=
fluid
.
layers
.
reshape
(
x
=
fc1
,
shape
=
list
(
fc1
.
shape
+
(
1
,
1
)))
bn
=
fluid
.
layers
.
batch_norm
(
input
=
reshape1
,
act
=
'relu'
)
bn
=
fluid
.
layers
.
batch_norm
(
input
=
fc1
,
act
=
'relu'
)
drop2
=
fluid
.
layers
.
dropout
(
x
=
bn
,
dropout_prob
=
0.5
)
fc2
=
fluid
.
layers
.
fc
(
input
=
drop2
,
size
=
512
,
act
=
None
)
return
fc2
...
...
python/paddle/v2/fluid/tests/test_batch_norm_op.py
浏览文件 @
c975fe1b
...
...
@@ -21,6 +21,13 @@ def get_backward_op(scope, op, no_grad_set):
def
_reference_training
(
x
,
scale
,
offset
,
epsilon
,
data_format
):
x_shape
=
x
.
shape
if
len
(
x_shape
)
==
2
:
if
data_format
==
"NCHW"
:
x
=
np
.
reshape
(
x
,
(
x
.
shape
[
0
],
x
.
shape
[
1
],
1
,
1
))
else
:
x
=
np
.
reshape
(
x
,
(
x
.
shape
[
0
],
1
,
1
,
x
.
shape
[
1
]))
if
data_format
==
"NCHW"
:
n
,
c
,
h
,
w
=
x
.
shape
x_square
=
x
*
x
...
...
@@ -39,6 +46,8 @@ def _reference_training(x, scale, offset, epsilon, data_format):
offset_tile
=
np
.
reshape
(
offset
,
(
1
,
c
,
1
,
1
))
offset_tile
=
np
.
reshape
(
offset_tile
,
(
1
,
c
,
1
,
1
))
y
=
normalized
*
scale_tile
+
offset_tile
if
len
(
x_shape
)
==
2
:
y
=
np
.
reshape
(
y
,
(
y
.
shape
[
0
],
y
.
shape
[
1
]))
return
y
,
mean
,
var
elif
data_format
==
"NHWC"
:
x_square
=
x
*
x
...
...
@@ -48,7 +57,10 @@ def _reference_training(x, scale, offset, epsilon, data_format):
mean
=
x_sum
/
element_count
var
=
x_square_sum
/
element_count
-
mean
*
mean
normalized
=
(
x
-
mean
)
/
np
.
sqrt
(
var
+
epsilon
)
return
(
normalized
*
scale
+
offset
),
mean
,
var
y
=
normalized
*
scale
+
offset
if
len
(
x_shape
)
==
2
:
y
=
np
.
reshape
(
y
,
x_shape
)
return
y
,
mean
,
var
else
:
raise
ValueError
(
"Unknown data order."
)
...
...
@@ -65,6 +77,18 @@ def _reference_grad(x, grad_y, scale, mean, var, epsilon, data_format):
# (x - mean) * sum(grad_y * (x - mean)) / (var + epsilon))
# transfer from (N, C, H, W) to (N, H, W, C) to simplify computation
x_shape
=
x
.
shape
if
len
(
x_shape
)
==
2
:
if
data_format
==
"NCHW"
:
x
=
np
.
reshape
(
x
,
(
x
.
shape
[
0
],
x
.
shape
[
1
],
1
,
1
))
grad_y
=
np
.
reshape
(
grad_y
,
(
grad_y
.
shape
[
0
],
grad_y
.
shape
[
1
],
1
,
1
))
else
:
x
=
np
.
reshape
(
x
,
(
x
.
shape
[
0
],
1
,
1
,
x
.
shape
[
1
]))
grad_y
=
np
.
reshape
(
grad_y
,
(
grad_y
.
shape
[
0
],
1
,
1
,
grad_y
.
shape
[
1
]))
if
data_format
==
"NCHW"
:
x
=
np
.
transpose
(
x
,
(
0
,
2
,
3
,
1
))
grad_y
=
np
.
transpose
(
grad_y
,
(
0
,
2
,
3
,
1
))
...
...
@@ -83,6 +107,9 @@ def _reference_grad(x, grad_y, scale, mean, var, epsilon, data_format):
grad_x
=
np
.
transpose
(
grad_x
,
(
0
,
3
,
1
,
2
))
x
=
np
.
transpose
(
x
,
(
0
,
3
,
1
,
2
))
grad_y
=
np
.
transpose
(
grad_y
,
(
0
,
3
,
1
,
2
))
if
len
(
x_shape
)
==
2
:
grad_x
=
np
.
reshape
(
grad_x
,
x_shape
)
return
grad_x
,
grad_scale
,
grad_offset
...
...
@@ -127,7 +154,7 @@ class TestBatchNormOp(OpTest):
momentum
=
0.9
# N, H, W, C: 2, 3, 4, 2
n
,
h
,
w
,
c
=
2
,
3
,
4
,
2
n
,
h
,
w
,
c
=
2
,
3
,
4
,
5
x_shape
=
[
n
,
h
,
w
,
c
]
scale_shape
=
[
c
]
...
...
@@ -184,20 +211,23 @@ class TestBatchNormOp(OpTest):
print
'python: NHWC, NCHW, backward checking passed'
def
test_forward_backward
(
self
):
def
test_with_place
(
place
,
tensor_format
):
def
test_with_place
(
place
,
tensor_format
,
shape
):
# attr
epsilon
=
0.00001
momentum
=
0.9
# N, H, W, C: 12, 3, 4, 2
n
,
h
,
w
,
c
=
2
,
3
,
4
,
2
if
data_format
==
"NHWC"
:
x_shape
=
[
n
,
h
,
w
,
c
]
elif
data_format
==
"NCHW"
:
x_shape
=
[
n
,
c
,
h
,
w
]
if
len
(
shape
)
==
2
:
x_shape
=
shape
c
=
shape
[
1
]
else
:
raise
ValueError
(
"Unknown data type."
)
# n, h, w, c = 2, 3, 4, 2
n
,
h
,
w
,
c
=
shape
[
0
],
shape
[
1
],
shape
[
2
],
shape
[
3
]
if
data_format
==
"NHWC"
:
x_shape
=
[
n
,
h
,
w
,
c
]
elif
data_format
==
"NCHW"
:
x_shape
=
[
n
,
c
,
h
,
w
]
else
:
raise
ValueError
(
"Unknown data type."
)
scale_shape
=
[
c
]
x_val
=
np
.
random
.
random_sample
(
x_shape
).
astype
(
np
.
float32
)
...
...
@@ -219,7 +249,10 @@ class TestBatchNormOp(OpTest):
# for gradient test
# y_grad = np.ones(x_shape).astype(np.float32)
y_grad
=
np
.
zeros
(
x_shape
).
astype
(
np
.
float32
)
y_grad
[
0
,
0
,
0
,
0
]
=
1.
if
len
(
y_grad
.
shape
)
==
2
:
y_grad
[
0
,
0
]
=
1.
else
:
y_grad
[
0
,
0
,
0
,
0
]
=
1.
# y_grad = np.random.random_sample(x_shape).astype(np.float32)
x_grad_ref
,
scale_grad_ref
,
bias_grad_ref
=
_reference_grad
(
x_val
,
y_grad
,
scale_val
,
saved_mean
,
var_ref
,
epsilon
,
...
...
@@ -313,7 +346,8 @@ class TestBatchNormOp(OpTest):
places
.
append
(
core
.
GPUPlace
(
0
))
for
place
in
places
:
for
data_format
in
[
"NCHW"
,
"NHWC"
]:
test_with_place
(
place
,
data_format
)
test_with_place
(
place
,
data_format
,
[
2
,
3
,
4
,
5
])
test_with_place
(
place
,
data_format
,
[
2
,
3
])
if
__name__
==
'__main__'
:
...
...
python/paddle/v2/fluid/tests/test_image_classification_layer.py
浏览文件 @
c975fe1b
import
unittest
import
paddle.v2.fluid
.layers
as
layers
import
paddle.v2.fluid
as
fluid
import
paddle.v2.fluid.nets
as
nets
from
paddle.v2.fluid.framework
import
Program
...
...
@@ -29,27 +29,35 @@ class TestLayer(unittest.TestCase):
def
test_batch_norm_layer
(
self
):
main_program
=
Program
()
startup_program
=
Program
()
images
=
layers
.
data
(
images
=
fluid
.
layers
.
data
(
name
=
'pixel'
,
shape
=
[
3
,
48
,
48
],
dtype
=
'float32'
,
main_program
=
main_program
)
layers
.
batch_norm
(
hidden1
=
fluid
.
layers
.
batch_norm
(
input
=
images
,
main_program
=
main_program
,
startup_program
=
startup_program
)
hidden2
=
fluid
.
layers
.
fc
(
input
=
hidden1
,
size
=
128
,
act
=
'relu'
,
main_program
=
main_program
)
hidden3
=
fluid
.
layers
.
batch_norm
(
input
=
hidden2
,
main_program
=
main_program
,
startup_program
=
startup_program
)
#
print str(main_program)
print
str
(
main_program
)
def
test_dropout_layer
(
self
):
main_program
=
Program
()
startup_program
=
Program
()
images
=
layers
.
data
(
images
=
fluid
.
layers
.
data
(
name
=
'pixel'
,
shape
=
[
3
,
48
,
48
],
dtype
=
'float32'
,
main_program
=
main_program
)
layers
.
dropout
(
fluid
.
layers
.
dropout
(
x
=
images
,
dropout_prob
=
0.5
,
main_program
=
main_program
,
...
...
@@ -61,7 +69,7 @@ class TestLayer(unittest.TestCase):
main_program
=
Program
()
startup_program
=
Program
()
images
=
layers
.
data
(
images
=
fluid
.
layers
.
data
(
name
=
'pixel'
,
shape
=
[
3
,
48
,
48
],
dtype
=
'float32'
,
...
...
@@ -77,19 +85,19 @@ class TestLayer(unittest.TestCase):
def
test_elementwise_add_with_act
(
self
):
main_program
=
Program
()
startup_program
=
Program
()
image1
=
layers
.
data
(
image1
=
fluid
.
layers
.
data
(
name
=
'pixel1'
,
shape
=
[
3
,
48
,
48
],
dtype
=
'float32'
,
main_program
=
main_program
,
startup_program
=
startup_program
)
image2
=
layers
.
data
(
image2
=
fluid
.
layers
.
data
(
name
=
'pixel2'
,
shape
=
[
3
,
48
,
48
],
dtype
=
'float32'
,
main_program
=
main_program
,
startup_program
=
startup_program
)
out
=
layers
.
elementwise_add
(
out
=
fluid
.
layers
.
elementwise_add
(
x
=
image1
,
y
=
image2
,
act
=
'relu'
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录