Skip to content

Commit be219ac

Browse files
authored
Merge pull request #10354 from helinwang/scaffold
Improve trainer API
2 parents 73650a8 + 0fca8a1 commit be219ac

File tree

5 files changed

+37
-81
lines changed

5 files changed

+37
-81
lines changed

python/paddle/fluid/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
from executor import *
2222

2323
import trainer
24-
from trainer import *
24+
from trainer import Trainer
25+
from trainer import BeginEpochEvent
26+
from trainer import EndEpochEvent
27+
from trainer import BeginStepEvent
28+
from trainer import EndStepEvent
2529

2630
import inferencer
2731
from inferencer import Inferencer
2832

29-
import params
30-
from params import Params
31-
3233
import io
3334
import evaluator
3435
import initializer
@@ -57,7 +58,7 @@
5758
Tensor = LoDTensor
5859

5960
__all__ = framework.__all__ + executor.__all__ + concurrency.__all__ +\
60-
trainer.__all__ + inferencer.__all__ + params.__all__ + [
61+
trainer.__all__ + inferencer.__all__ + [
6162
'io',
6263
'initializer',
6364
'layers',

python/paddle/fluid/inferencer.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import core
16+
1517
__all__ = ['Inferencer', ]
1618

1719

1820
class Inferencer(object):
19-
def __init__(self, network_func, params, place=None):
21+
def __init__(self, network_func, param_path=None, place=None):
2022
# 1. we need to generate a framework.Program by calling
2123
# network_func. Reference: fluid.program_guard in test_word2vec.py
2224

2325
# 2. move the default_main_program to self.program.
2426

2527
# 3. run the default_startup program.
26-
self.params = params
28+
29+
# 4. load params from param_path into scope
30+
self.scope = core.Scope()
2731
self.place = place
2832

2933
def infer(self, inputs):

python/paddle/fluid/params.py

Lines changed: 0 additions & 39 deletions
This file was deleted.

python/paddle/fluid/tests/book/word2vec/no_test_word2vec_new_api.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def create_random_lodtensor(lod, place, low, high):
3939
dict_size = len(word_dict)
4040

4141

42-
def inference_network(is_sparse):
42+
def inference_program(is_sparse):
4343
first_word = fluid.layers.data(name='firstw', shape=[1], dtype='int64')
4444
second_word = fluid.layers.data(name='secondw', shape=[1], dtype='int64')
4545
third_word = fluid.layers.data(name='thirdw', shape=[1], dtype='int64')
@@ -79,9 +79,9 @@ def inference_network(is_sparse):
7979
return predict_word
8080

8181

82-
def train_network(is_sparse):
82+
def train_program(is_sparse):
8383
next_word = fluid.layers.data(name='nextw', shape=[1], dtype='int64')
84-
predict_word = inference_network(is_sparse)
84+
predict_word = inference_program(is_sparse)
8585
cost = fluid.layers.cross_entropy(input=predict_word, label=next_word)
8686
avg_cost = fluid.layers.mean(cost)
8787
return avg_cost
@@ -100,23 +100,25 @@ def event_handler(event):
100100
word_dict, N))
101101

102102
if avg_cost < 5.0:
103-
trainer.params.save(save_path)
103+
trainer.save_params(save_path)
104104
return
105105
if math.isnan(avg_cost):
106106
sys.exit("got NaN loss, training failed.")
107107

108108
trainer = fluid.Trainer(
109-
partial(train_network, is_sparse),
109+
partial(train_program, is_sparse),
110110
fluid.optimizer.SGD(learning_rate=0.001),
111111
place=place)
112112
trainer.train(
113113
reader=train_reader, num_epochs=100, event_handler=event_handler)
114114

115115

116-
def infer(use_cuda, save_path):
117-
params = fluid.Params(save_path)
116+
def infer(use_cuda, is_sparse, save_path):
118117
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
119-
inferencer = fluid.Inferencer(inference_network, params, place=place)
118+
inferencer = fluid.Inferencer(
119+
partial(inference_program, is_sparse),
120+
param_path=save_path,
121+
place=place)
120122

121123
lod = [0, 1]
122124
first_word = create_random_lodtensor(lod, place, low=0, high=dict_size - 1)
@@ -138,7 +140,7 @@ def main(use_cuda, is_sparse):
138140

139141
save_path = "word2vec.inference.model"
140142
train(use_cuda, is_sparse, save_path)
141-
infer(use_cuda, save_path)
143+
infer(use_cuda, is_sparse, save_path)
142144

143145

144146
if __name__ == '__main__':

python/paddle/fluid/trainer.py

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,22 @@ class Trainer(object):
5656
"""
5757
5858
Args:
59-
network_func(callable): A function which will return loss. The loss must be a scaler.
59+
program_func(callable): A function which will return loss. The loss must be a scaler.
6060
optimizer(optimizer.Optimizer): The optimizer should be an instance of Optimizer
61-
params:
6261
place: The device place of this trainer.
6362
"""
6463

65-
def __init__(self, network_func, optimizer, params=None, place=None):
64+
def __init__(self, program_func, optimizer, param_path=None, place=None):
6665
# 1. we need to generate a framework.Program by calling
67-
# network_func. Reference: fluid.program_guard in
66+
# program_func. Reference: fluid.program_guard in
6867
# test_word2vec.py
69-
self.scope = self._get_scope_from_params(params)
68+
self.scope = core.Scope()
7069

7170
self.startup_program = framework.Program()
7271
self.train_program = framework.Program()
7372

7473
with framework.program_guard(self.train_program, self.startup_program):
75-
loss = network_func()
74+
loss = program_func()
7675
if not isinstance(optimizer, opt_module.Optimizer):
7776
raise TypeError(
7877
"The optimizer should be an instance of Optimizer")
@@ -84,14 +83,13 @@ def __init__(self, network_func, optimizer, params=None, place=None):
8483
# 2. move the default_main_program to self.program and run the
8584
# default_startup program on an empty core.Scope()
8685
# Run startup program
87-
if params is None:
88-
exe = executor.Executor(place)
89-
exe.run(self.startup_program, scope=self.scope)
86+
exe = executor.Executor(place)
87+
exe.run(self.startup_program, scope=self.scope)
9088

91-
# 3. call self.params.add_vars with the initialized scope, it
92-
# will add the new vars of the initialized scope into
93-
# self.params.
94-
# TODO(yuyang): This depends on parameters implementation.
89+
if param_path:
90+
# load params from param_path into scope
91+
# TODO(yuyang): This depends on parameters implementation.
92+
pass
9593

9694
# TODO(helin): support distributed training
9795

@@ -124,19 +122,9 @@ def train(self,
124122
def test(self, reader):
125123
pass
126124

127-
def _get_scope_from_params(self, params):
128-
"""
129-
Get Scope from parameter object.
130-
Args:
131-
params(Parameter|None): The parameter object instance. Could be None.
132-
133-
Returns: New scope if params is None. Or params.scope()
134-
NOTE: This method is WIP. Not fully implemented.
135-
"""
136-
if params is None:
137-
return core.Scope() # new scope when params is None
138-
else:
139-
raise NotImplementedError("Not implemented right now.")
125+
def save_params(self, param_path):
126+
# reference: save_persistables in io.py
127+
pass
140128

141129
@staticmethod
142130
def _check_and_get_place(place):

0 commit comments

Comments
 (0)