Skip to content

Commit 6d5e582

Browse files
authored
Merge pull request #10343 from reyoung/feature/new_api_train_impl
A naive implement trainer.train by executor
2 parents 753ea15 + 1bb579a commit 6d5e582

File tree

5 files changed

+325
-22
lines changed

5 files changed

+325
-22
lines changed

python/paddle/fluid/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
from executor import *
2222

2323
import trainer
24-
from trainer import Trainer
25-
from trainer import Event
24+
from trainer import *
2625

2726
import inferencer
2827
from inferencer import Inferencer

python/paddle/fluid/layers/io.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ def data(name,
5050
dtype(int|float): The type of data : float32, float_16, int etc
5151
type(VarType): The output type. By default it is LOD_TENSOR.
5252
lod_level(int): The LoD Level. 0 means the input data is not a sequence.
53-
main_program(Program): Name of the main program that calls this
54-
startup_program(Program): Name of the startup program
5553
stop_gradient(bool): A boolean that mentions whether gradient should flow.
5654
5755
Returns:
@@ -74,13 +72,15 @@ def data(name,
7472
if append_batch_size:
7573
shape = [-1] + shape # append batch size as -1
7674

77-
return helper.create_global_variable(
75+
data_var = helper.create_global_variable(
7876
name=name,
7977
shape=shape,
8078
dtype=dtype,
8179
type=type,
8280
stop_gradient=stop_gradient,
8381
lod_level=lod_level)
82+
data_var.is_data = True
83+
return data_var
8484

8585

8686
class BlockGuardServ(BlockGuard):

python/paddle/fluid/optimizer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
__all__ = [
2929
'SGD', 'Momentum', 'Adagrad', 'Adam', 'Adamax', 'DecayedAdagrad',
3030
'SGDOptimizer', 'MomentumOptimizer', 'AdagradOptimizer', 'AdamOptimizer',
31-
'AdamaxOptimizer', 'DecayedAdagradOptimizer', 'Adadelta', 'ModelAverage'
31+
'AdamaxOptimizer', 'DecayedAdagradOptimizer', 'Adadelta', 'ModelAverage',
32+
'Optimizer'
3233
]
3334

3435

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserve.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import paddle
16+
import paddle.fluid as fluid
17+
import numpy as np
18+
import math
19+
import sys
20+
from functools import partial
21+
22+
PASS_NUM = 100
23+
EMBED_SIZE = 32
24+
HIDDEN_SIZE = 256
25+
N = 5
26+
BATCH_SIZE = 32
27+
28+
29+
def create_random_lodtensor(lod, place, low, high):
30+
# The range of data elements is [low, high]
31+
data = np.random.random_integers(low, high, [lod[-1], 1]).astype("int64")
32+
res = fluid.LoDTensor()
33+
res.set(data, place)
34+
res.set_lod([lod])
35+
return res
36+
37+
38+
word_dict = paddle.dataset.imikolov.build_dict()
39+
dict_size = len(word_dict)
40+
41+
42+
def inference_network(is_sparse):
43+
first_word = fluid.layers.data(name='firstw', shape=[1], dtype='int64')
44+
second_word = fluid.layers.data(name='secondw', shape=[1], dtype='int64')
45+
third_word = fluid.layers.data(name='thirdw', shape=[1], dtype='int64')
46+
forth_word = fluid.layers.data(name='forthw', shape=[1], dtype='int64')
47+
48+
embed_first = fluid.layers.embedding(
49+
input=first_word,
50+
size=[dict_size, EMBED_SIZE],
51+
dtype='float32',
52+
is_sparse=is_sparse,
53+
param_attr='shared_w')
54+
embed_second = fluid.layers.embedding(
55+
input=second_word,
56+
size=[dict_size, EMBED_SIZE],
57+
dtype='float32',
58+
is_sparse=is_sparse,
59+
param_attr='shared_w')
60+
embed_third = fluid.layers.embedding(
61+
input=third_word,
62+
size=[dict_size, EMBED_SIZE],
63+
dtype='float32',
64+
is_sparse=is_sparse,
65+
param_attr='shared_w')
66+
embed_forth = fluid.layers.embedding(
67+
input=forth_word,
68+
size=[dict_size, EMBED_SIZE],
69+
dtype='float32',
70+
is_sparse=is_sparse,
71+
param_attr='shared_w')
72+
73+
concat_embed = fluid.layers.concat(
74+
input=[embed_first, embed_second, embed_third, embed_forth], axis=1)
75+
hidden1 = fluid.layers.fc(input=concat_embed,
76+
size=HIDDEN_SIZE,
77+
act='sigmoid')
78+
predict_word = fluid.layers.fc(input=hidden1, size=dict_size, act='softmax')
79+
return predict_word
80+
81+
82+
def train_network(is_sparse):
83+
next_word = fluid.layers.data(name='nextw', shape=[1], dtype='int64')
84+
predict_word = inference_network(is_sparse)
85+
cost = fluid.layers.cross_entropy(input=predict_word, label=next_word)
86+
avg_cost = fluid.layers.mean(cost)
87+
return avg_cost
88+
89+
90+
def train(use_cuda, is_sparse, save_path):
91+
train_reader = paddle.batch(
92+
paddle.dataset.imikolov.train(word_dict, N), BATCH_SIZE)
93+
94+
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
95+
96+
def event_handler(event):
97+
print type(event)
98+
if isinstance(event, fluid.EndEpochEvent):
99+
avg_cost = trainer.test(reader=paddle.dataset.imikolov.test(
100+
word_dict, N))
101+
102+
if avg_cost < 5.0:
103+
trainer.params.save(save_path)
104+
return
105+
if math.isnan(avg_cost):
106+
sys.exit("got NaN loss, training failed.")
107+
108+
trainer = fluid.Trainer(
109+
partial(train_network, is_sparse),
110+
fluid.optimizer.SGD(learning_rate=0.001),
111+
place=place)
112+
trainer.train(
113+
reader=train_reader, num_epochs=100, event_handler=event_handler)
114+
115+
116+
def infer(use_cuda, save_path):
117+
params = fluid.Params(save_path)
118+
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
119+
inferencer = fluid.Inferencer(inference_network, params, place=place)
120+
121+
lod = [0, 1]
122+
first_word = create_random_lodtensor(lod, place, low=0, high=dict_size - 1)
123+
second_word = create_random_lodtensor(lod, place, low=0, high=dict_size - 1)
124+
third_word = create_random_lodtensor(lod, place, low=0, high=dict_size - 1)
125+
fourth_word = create_random_lodtensor(lod, place, low=0, high=dict_size - 1)
126+
result = inferencer.infer({
127+
'firstw': first_word,
128+
'secondw': second_word,
129+
'thirdw': third_word,
130+
'forthw': fourth_word
131+
})
132+
print(result)
133+
134+
135+
def main(use_cuda, is_sparse):
136+
if use_cuda and not fluid.core.is_compiled_with_cuda():
137+
return
138+
139+
save_path = "word2vec.inference.model"
140+
train(use_cuda, is_sparse, save_path)
141+
infer(use_cuda, save_path)
142+
143+
144+
if __name__ == '__main__':
145+
for use_cuda in (False, True):
146+
for is_sparse in (False, True):
147+
main(use_cuda=use_cuda, is_sparse=is_sparse)

0 commit comments

Comments
 (0)