Skip to content

Commit f95c291

Browse files
authored
Merge pull request #5651 from emailweixu/fix_conv_bias
Fix conv2d bias
2 parents 4fc9f55 + 81bb26f commit f95c291

File tree

4 files changed

+65
-31
lines changed

4 files changed

+65
-31
lines changed

python/paddle/v2/fluid/io.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def save_vars(executor, dirname, main_program=None, vars=None, predicate=None):
3535
3636
:param executor: executor that save variable
3737
:param dirname: directory path
38-
:param main_program: program. If vars is None, then filter all variables in this
38+
:param main_program: program. If vars is None, then filter all variables in this
3939
program which fit `predicate`. Default g_program.
4040
:param predicate: The Predicate describes a callable that returns a variable
4141
as a bool. If it returns true, the variables will be saved.
@@ -96,11 +96,11 @@ def load_vars(executor, dirname, main_program=None, vars=None, predicate=None):
9696
9797
:param executor: executor that save variable
9898
:param dirname: directory path
99-
:param main_program: program. If vars is None, then filter all variables in this
99+
:param main_program: program. If vars is None, then filter all variables in this
100100
program which fit `predicate`. Default g_program.
101101
:param predicate: The Predicate describes a callable that returns a variable
102102
as a bool. If it returns true, the variables will be loaded.
103-
:param vars: variables need to be loaded. If specify vars, program &
103+
:param vars: variables need to be loaded. If specify vars, program &
104104
predicate will be ignored
105105
:return: None
106106
"""
@@ -157,15 +157,15 @@ def save_inference_model(dirname,
157157
executor,
158158
main_program=None):
159159
"""
160-
Build a model especially for inference,
160+
Build a model especially for inference,
161161
and save it to directory by the executor.
162162
163163
:param dirname: directory path
164164
:param feeded_var_names: Names of variables that need to be feeded data during inference
165165
:param target_vars: Variables from which we can get inference results.
166166
:param executor: executor that save inference model
167-
:param main_program: original program, which will be pruned to build the inference model.
168-
Default g_program.
167+
:param main_program: original program, which will be pruned to build the inference model.
168+
Default g_main_program.
169169
170170
:return: None
171171
"""
@@ -234,3 +234,35 @@ def load_inference_model(dirname, executor):
234234
fetch_vars = [program.global_block().var(name) for name in fetch_var_names]
235235

236236
return [program, feed_var_names, fetch_vars]
237+
238+
239+
def get_parameter_value(para, executor):
240+
"""
241+
Get the LoDTensor for the parameter
242+
243+
:param executor: executor for retrieving the value
244+
:param para: the given parameter
245+
:return: the LoDTensor for the parameter
246+
"""
247+
assert is_parameter(para)
248+
249+
get_program = Program()
250+
block = get_program.global_block()
251+
new_var = _clone_var_in_block_(block, para)
252+
return executor.run(get_program, feed={}, fetch_list=[new_var])[0]
253+
254+
255+
def get_parameter_value_by_name(name, executor, program=None):
256+
"""
257+
Get the LoDTensor for paramter with the given name
258+
259+
:param executor: executor for retrieving the value
260+
:param name: the name of the parameter
261+
:param program: the program where the variable is found
262+
Default g_main_program.
263+
:return: the LoDTensor for the variable
264+
"""
265+
if program is None:
266+
program = g_main_program
267+
var = program.global_block().var(name)
268+
return get_parameter_value(var, executor)

python/paddle/v2/fluid/layer_helper.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def param_attr(self):
7272

7373
@property
7474
def bias_attr(self):
75-
default = {'name': None, 'initializer': XavierInitializer()}
75+
default = {'name': None, 'initializer': ConstantInitializer()}
7676
bias_attr = self.kwargs.get('bias_attr', None)
7777
if bias_attr is None:
7878
bias_attr = default
@@ -149,24 +149,19 @@ def set_variable_initializer(self, var, initializer):
149149
persistable=True,
150150
initializer=initializer)
151151

152-
def append_bias_op(self, input_var, num_flatten_dims=None):
152+
def append_bias_op(self, input_var, dim_start=1, dim_end=None):
153153
"""
154-
Append bias operator and return its output. If the user does not set
154+
Append bias operator and return its output. If the user does not set
155155
bias_attr, append_bias_op will return input_var
156-
156+
157157
:param input_var: the input variable. The len(input_var.shape) is larger
158158
or equal than 2.
159-
:param num_flatten_dims: The input tensor will be flatten as a matrix
160-
when adding bias.
161-
`matrix.shape = product(input_var.shape[0:num_flatten_dims]), product(
162-
input_var.shape[num_flatten_dims:])`
159+
:param dim_start:
160+
:param dim_end: the shape of the bias will be
161+
input_var.shape[dim_start:dim_end]. The bias is broadcasted to other
162+
dimensions and added to input_var to get the output
163163
"""
164-
if num_flatten_dims is None:
165-
num_flatten_dims = self.kwargs.get('num_flatten_dims', None)
166-
if num_flatten_dims is None:
167-
num_flatten_dims = 1
168-
169-
size = list(input_var.shape[num_flatten_dims:])
164+
size = list(input_var.shape[dim_start:dim_end])
170165
bias_attr = self.bias_attr
171166
if not bias_attr:
172167
return input_var
@@ -178,7 +173,8 @@ def append_bias_op(self, input_var, num_flatten_dims=None):
178173
type='elementwise_add',
179174
inputs={'X': [input_var],
180175
'Y': [b]},
181-
outputs={'Out': [tmp]})
176+
outputs={'Out': [tmp]},
177+
attrs={'axis': dim_start})
182178
return tmp
183179

184180
def append_activation(self, input_var):

python/paddle/v2/fluid/layers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def _convert_(name):
250250
def _generate_doc_string_(op_proto):
251251
"""
252252
Generate docstring by OpProto
253-
253+
254254
Args:
255255
op_proto (framework_pb2.OpProto): a protobuf message typed OpProto
256256
@@ -694,7 +694,7 @@ def conv2d(input,
694694
'paddings': padding,
695695
'groups': groups})
696696

697-
pre_act = helper.append_bias_op(pre_bias, 1)
697+
pre_act = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
698698

699699
return helper.append_activation(pre_act)
700700

python/paddle/v2/fluid/tests/test_parameter.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
import unittest
22
from paddle.v2.fluid.framework import g_main_program
33
import paddle.v2.fluid.core as core
4+
from paddle.v2.fluid.executor import Executor
5+
import paddle.v2.fluid.io as io
6+
from paddle.v2.fluid.initializer import ConstantInitializer
7+
import numpy as np
48

59

610
class TestParameter(unittest.TestCase):
711
def test_param(self):
8-
b = g_main_program.create_block()
12+
shape = [784, 100]
13+
val = 1.0625
14+
b = g_main_program.global_block()
915
param = b.create_parameter(
1016
name='fc.w',
11-
shape=[784, 100],
17+
shape=shape,
1218
dtype='float32',
13-
initialize_attr={
14-
'type': 'uniform_random',
15-
'seed': 13,
16-
'min': -5.0,
17-
'max': 5.0
18-
})
19+
initializer=ConstantInitializer(val))
1920
self.assertIsNotNone(param)
2021
self.assertEqual('fc.w', param.name)
2122
self.assertEqual((784, 100), param.shape)
2223
self.assertEqual(core.DataType.FP32, param.data_type)
2324
self.assertEqual(0, param.block.idx)
25+
exe = Executor(core.CPUPlace())
26+
p = exe.run(g_main_program, fetch_list=[param])[0]
27+
self.assertTrue(np.allclose(np.array(p), np.ones(shape) * val))
28+
p = io.get_parameter_value_by_name('fc.w', exe, g_main_program)
29+
self.assertTrue(np.allclose(np.array(p), np.ones(shape) * val))
2430

2531

2632
if __name__ == '__main__':

0 commit comments

Comments
 (0)