Skip to content

Commit 16c07d8

Browse files
Merge pull request #276 from wanghaoshuang/recognize_digits_demo
Add demo of recognize_digits on paddlecloud
2 parents e803a6c + c4b6067 commit 16c07d8

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

demo/recognize_digits/train.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
from PIL import Image
2+
import numpy as np
3+
import paddle.v2 as paddle
4+
import paddle.v2.dataset.common as common
5+
import os
6+
import sys
7+
import glob
8+
import pickle
9+
10+
11+
# NOTE: must change this to your own username on paddlecloud.
12+
USERNAME = "wanghaoshuang@baidu.com"
13+
DC = os.getenv("PADDLE_CLOUD_CURRENT_DATACENTER")
14+
common.DATA_HOME = "/pfs/%s/home/%s" % (DC, USERNAME)
15+
TRAIN_FILES_PATH = os.path.join(common.DATA_HOME, "mnist")
16+
TEST_FILES_PATH = os.path.join(common.DATA_HOME, "mnist")
17+
18+
TRAINER_ID = int(os.getenv("PADDLE_INIT_TRAINER_ID", "-1"))
19+
TRAINER_COUNT = int(os.getenv("PADDLE_INIT_NUM_GRADIENT_SERVERS", "-1"))
20+
21+
def prepare_dataset():
22+
# convert will also split the dataset by line-count
23+
common.convert(TRAIN_FILES_PATH,
24+
paddle.dataset.mnist.train(),
25+
8192, "train")
26+
common.convert(TEST_FILES_PATH,
27+
paddle.dataset.mnist.test(),
28+
1, "test")
29+
30+
def cluster_reader_recordio(trainer_id, trainer_count, flag):
31+
'''
32+
read from cloud dataset which is stored as recordio format
33+
each trainer will read a subset of files of the whole dataset.
34+
'''
35+
import recordio
36+
def reader():
37+
PATTERN_STR = "%s-*" % flag
38+
FILES_PATTERN = os.path.join(TRAIN_FILES_PATH, PATTERN_STR)
39+
file_list = glob.glob(FILES_PATTERN)
40+
file_list.sort()
41+
my_file_list = []
42+
# read files for current trainer_id
43+
for idx, f in enumerate(file_list):
44+
if idx % trainer_count == trainer_id:
45+
my_file_list.append(f)
46+
for f in my_file_list:
47+
print "processing ", f
48+
reader = recordio.reader(f)
49+
record_raw = reader.read()
50+
while record_raw:
51+
yield pickle.loads(record_raw)
52+
record_raw = reader.read()
53+
reader.close()
54+
return reader
55+
56+
57+
58+
def softmax_regression(img):
59+
predict = paddle.layer.fc(
60+
input=img, size=10, act=paddle.activation.Softmax())
61+
return predict
62+
63+
64+
def multilayer_perceptron(img):
65+
# The first fully-connected layer
66+
hidden1 = paddle.layer.fc(input=img, size=128, act=paddle.activation.Relu())
67+
# The second fully-connected layer and the according activation function
68+
hidden2 = paddle.layer.fc(
69+
input=hidden1, size=64, act=paddle.activation.Relu())
70+
# The thrid fully-connected layer, note that the hidden size should be 10,
71+
# which is the number of unique digits
72+
predict = paddle.layer.fc(
73+
input=hidden2, size=10, act=paddle.activation.Softmax())
74+
return predict
75+
76+
77+
def convolutional_neural_network(img):
78+
# first conv layer
79+
conv_pool_1 = paddle.networks.simple_img_conv_pool(
80+
input=img,
81+
filter_size=5,
82+
num_filters=20,
83+
num_channel=1,
84+
pool_size=2,
85+
pool_stride=2,
86+
act=paddle.activation.Relu())
87+
# second conv layer
88+
conv_pool_2 = paddle.networks.simple_img_conv_pool(
89+
input=conv_pool_1,
90+
filter_size=5,
91+
num_filters=50,
92+
num_channel=20,
93+
pool_size=2,
94+
pool_stride=2,
95+
act=paddle.activation.Relu())
96+
# fully-connected layer
97+
predict = paddle.layer.fc(
98+
input=conv_pool_2, size=10, act=paddle.activation.Softmax())
99+
return predict
100+
101+
102+
def main():
103+
paddle.init()
104+
105+
# define network topology
106+
images = paddle.layer.data(
107+
name='pixel', type=paddle.data_type.dense_vector(784))
108+
label = paddle.layer.data(
109+
name='label', type=paddle.data_type.integer_value(10))
110+
111+
# Here we can build the prediction network in different ways. Please
112+
# choose one by uncomment corresponding line.
113+
# predict = softmax_regression(images)
114+
# predict = multilayer_perceptron(images)
115+
predict = convolutional_neural_network(images)
116+
117+
cost = paddle.layer.classification_cost(input=predict, label=label)
118+
119+
parameters = paddle.parameters.create(cost)
120+
121+
optimizer = paddle.optimizer.Momentum(
122+
learning_rate=0.1 / 128.0,
123+
momentum=0.9,
124+
regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 128))
125+
126+
trainer = paddle.trainer.SGD(
127+
cost=cost, parameters=parameters, update_equation=optimizer)
128+
129+
def event_handler(event):
130+
if isinstance(event, paddle.event.EndIteration):
131+
if event.batch_id % 100 == 0:
132+
print "Pass %d, Batch %d, Cost %f, %s" % (
133+
event.pass_id, event.batch_id, event.cost, event.metrics)
134+
if isinstance(event, paddle.event.EndPass):
135+
result = trainer.test(
136+
reader=paddle.batch(
137+
cluster_reader_recordio(TRAINER_ID, TRAINER_COUNT, "test"),
138+
batch_size=2))
139+
print "Test with Pass %d, Cost %f, %s\n" % (
140+
event.pass_id, result.cost, result.metrics)
141+
142+
trainer.train(
143+
reader=paddle.batch(
144+
cluster_reader_recordio(TRAINER_ID, TRAINER_COUNT, "train"),
145+
batch_size=128),
146+
event_handler=event_handler,
147+
num_passes=5)
148+
149+
if __name__ == '__main__':
150+
usage = "python train.py [prepare|train]"
151+
if len(sys.argv) != 2:
152+
print usage
153+
exit(1)
154+
155+
if TRAINER_ID == -1 or TRAINER_COUNT == -1:
156+
print "no cloud environ found, must run on cloud"
157+
exit(1)
158+
159+
if sys.argv[1] == "prepare":
160+
prepare_dataset()
161+
elif sys.argv[1] == "train":
162+
main()

0 commit comments

Comments
 (0)