Skip to content

Commit 6d6180d

Browse files
committed
Skeleton of model
1 parent d276c32 commit 6d6180d

File tree

6 files changed

+245
-6
lines changed

6 files changed

+245
-6
lines changed

paddle/framework/pybind.cc

+8-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,14 @@ All parameter, weight, gradient are variables in Paddle.
225225
py::class_<operators::NetOp, OperatorBase>(m, "Net")
226226
.def(py::init<>())
227227
.def("add_op", [](operators::NetOp &self,
228-
const OperatorBase &op) { self.AddOp(op); })
228+
const OperatorBase &op) { return self.AddOp(op); })
229+
.def("__len__", &operators::NetOp::Size)
230+
.def("infer_shape",
231+
[](operators::NetOp &self, size_t begin, const Scope &scope) {
232+
self.InferShape(begin, std::numeric_limits<size_t>::max(), scope);
233+
})
234+
.def("infer_shape", [](operators::NetOp &self,
235+
const Scope &scope) { self.InferShape(scope); })
229236
.def("complete_add_op", &operators::NetOp::CompleteAddOp)
230237
.def("complete_add_op",
231238
[](operators::NetOp &self) { self.CompleteAddOp(); })

paddle/operators/net_op.h

+12-4
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,18 @@ class NetOp : public framework::OperatorBase {
5656
* before every mini-batch
5757
*/
5858
void InferShape(const framework::Scope& scope) const override {
59-
for (auto& op : ops_) {
60-
op->InferShape(scope);
59+
InferShape(0, std::numeric_limits<size_t>::max(), scope);
60+
}
61+
62+
void InferShape(size_t begin, size_t end,
63+
const framework::Scope& scope) const {
64+
for (; begin < std::min(end, ops_.size()); ++begin) {
65+
ops_[begin]->InferShape(scope);
6166
}
6267
}
6368

69+
size_t Size() const { return ops_.size(); }
70+
6471
/**
6572
* @brief Run the network.
6673
*
@@ -84,15 +91,16 @@ class NetOp : public framework::OperatorBase {
8491
return true;
8592
}
8693

87-
void AddOp(const framework::OperatorBase& op) { AddOp(op.Clone()); }
94+
size_t AddOp(const framework::OperatorBase& op) { return AddOp(op.Clone()); }
8895

8996
/**
9097
* @brief Add an operator by ptr
9198
*/
92-
void AddOp(std::unique_ptr<framework::OperatorBase> op) {
99+
size_t AddOp(std::unique_ptr<framework::OperatorBase> op) {
93100
PADDLE_ENFORCE(!add_op_done_, "Cannot AddOp when this network is sealed");
94101
PADDLE_ENFORCE_NOT_NULL(op, "Cannot Insert Null op");
95102
ops_.push_back(std::move(op));
103+
return ops_.size() - 1;
96104
}
97105

98106
void InsertOp(size_t pos, std::unique_ptr<framework::OperatorBase> op) {

python/paddle/v2/framework/layers.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from paddle.v2.framework.model import *
2+
import numpy
3+
4+
5+
def is_list_like(o):
6+
return isinstance(o, list) or isinstance(o, tuple)
7+
8+
9+
def data(name, shape, model=None):
10+
if model is None:
11+
model = g_model
12+
13+
if isinstance(shape, int):
14+
shape = [shape]
15+
16+
if not is_list_like(shape):
17+
raise ValueError()
18+
19+
if id(model.cur_scope) != id(model.global_scope):
20+
raise ValueError("Data Layer must be declared in global scope")
21+
22+
tensor = model.cur_scope.new_var(name).get_tensor()
23+
tensor.set_dims([1] + shape)
24+
return name
25+
26+
27+
def fc(input,
28+
size,
29+
name=None,
30+
param_attr=None,
31+
bias_attr=False,
32+
act="sigmoid",
33+
model=None):
34+
if model is None:
35+
model = g_model
36+
37+
if name is None:
38+
name = model.next_name('fc')
39+
40+
if param_attr is None:
41+
param_attr = ParameterAttribute.default_weight_attr()
42+
43+
dim = model.cur_scope.find_var(input).get_tensor().get_dims()
44+
w = model.create_parameter(name + ".weight.", param_attr, [dim[1], size])
45+
46+
tmp = model.add_op_and_infer_shape("mul", X=input, Y=w)
47+
48+
if bias_attr is None or bias_attr is True:
49+
bias_attr = ParameterAttribute.default_bias_attr()
50+
if bias_attr:
51+
b = model.create_parameter(name + ".bias.", bias_attr, [size])
52+
tmp = model.add_op_and_infer_shape('rowwise_add', X=tmp, b=b)
53+
54+
if act:
55+
tmp = model.add_op_and_infer_shape(act, X=tmp)
56+
57+
return tmp
58+
59+
60+
if __name__ == '__main__':
61+
x = data("X", shape=784)
62+
hidden = fc(x, size=100, bias_attr=True)
63+
hidden = fc(hidden, size=100, bias_attr=True)
64+
prediction = fc(hidden, size=10, bias_attr=True, act='softmax')
65+
66+
g_model.init_parameters()
67+
g_model.feed_data({"X": numpy.random.random((1000, 784)).astype('float32')})
68+
69+
for i in xrange(1000):
70+
g_model.run()
71+
print numpy.array(g_model.find_tensor(prediction)).mean()

python/paddle/v2/framework/model.py

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import paddle.v2.framework.network as network
2+
import paddle.v2.framework.core as core
3+
4+
__all__ = ['Model', 'g_model', 'ParameterAttribute']
5+
6+
7+
class ParameterAttribute(object):
8+
def __init__(self,
9+
name=None,
10+
initial_max=None,
11+
initial_min=None,
12+
initial_mean=None,
13+
initial_std=None,
14+
initial_seed=0):
15+
self.name = name
16+
17+
if initial_min is None and initial_max is None and initial_mean is None and initial_std is None:
18+
initial_min = -1.0
19+
initial_max = 1.0
20+
21+
if initial_max is not None and initial_min is not None:
22+
self.init_strategy = ('uniform_random', {
23+
'min': initial_min,
24+
'max': initial_max,
25+
'seed': initial_seed
26+
})
27+
elif initial_mean is not None and initial_std is not None:
28+
self.init_strategy = ('gauss_random', {
29+
'mean': initial_mean,
30+
'std': initial_std,
31+
'seed': initial_seed
32+
})
33+
else:
34+
raise ValueError()
35+
36+
@staticmethod
37+
def default_weight_attr():
38+
return ParameterAttribute()
39+
40+
@staticmethod
41+
def default_bias_attr():
42+
# TODO(yy): Change it to FillZero.
43+
return ParameterAttribute(initial_min=-0.0001, initial_max=0.0001)
44+
45+
46+
class Model(object):
47+
def __init__(self, place=None):
48+
self.init_network = network.Network()
49+
self.network = network.Network()
50+
51+
if place is None:
52+
self.device_context = None
53+
self.place = None
54+
else:
55+
self.device_context = core.DeviceContext.create(place)
56+
self.place = None
57+
58+
self.global_scope = core.Scope()
59+
self.cur_scope = self.global_scope
60+
self.name_counter = 0
61+
self.all_param_names = set()
62+
self.has_been_run = False
63+
64+
def next_name(self, prefix):
65+
name = prefix + str(self.name_counter)
66+
self.name_counter += 1
67+
return name
68+
69+
def create_parameter(self, name_prefix, param_attr, dims):
70+
if not isinstance(param_attr, ParameterAttribute):
71+
raise TypeError()
72+
if param_attr.name is None:
73+
param_attr.name = self.next_name(name_prefix)
74+
75+
if self.cur_scope.find_var(param_attr.name) is not None:
76+
raise ValueError("Parameter {} has been created before",
77+
param_attr.name)
78+
79+
self.cur_scope.new_var(param_attr.name).get_tensor()
80+
81+
op_type, attrs = param_attr.init_strategy
82+
attrs['dims'] = dims
83+
attrs['Out'] = param_attr.name
84+
85+
op_func = getattr(self.init_network, op_type)
86+
pname = op_func(**attrs)
87+
self.all_param_names.add(pname)
88+
89+
self.init_network.infer_shape(
90+
len(self.init_network) - 1, self.cur_scope)
91+
92+
return pname
93+
94+
def add_op_and_infer_shape(self, op_type, **kwargs):
95+
out = self.network.create_and_add_op(op_type, **kwargs)
96+
return_value = out
97+
if out is None:
98+
return
99+
100+
if isinstance(out, unicode) or isinstance(out, str):
101+
out = [out]
102+
103+
for o in out:
104+
v = self.cur_scope.find_var(o)
105+
if v is None:
106+
v = self.cur_scope.new_var(o)
107+
v.get_tensor()
108+
109+
op_idx = len(self.network) - 1
110+
self.network.infer_shape(op_idx, self.cur_scope)
111+
112+
return return_value
113+
114+
def set_place(self, place):
115+
if self.has_been_run:
116+
raise ValueError("Cannot set place to model after run")
117+
118+
self.device_context = core.DeviceContext.create(place)
119+
self.place = place
120+
121+
def init_parameters(self):
122+
if self.device_context is None:
123+
# TODO(yy): Log warning here
124+
self.set_place(core.CPUPlace())
125+
if not self.has_been_run:
126+
self.has_been_run = True
127+
128+
self.init_network.run(self.global_scope, self.device_context)
129+
130+
def run(self):
131+
if not self.has_been_run:
132+
self.has_been_run = True
133+
self.network.infer_shape(self.global_scope)
134+
self.network.run(self.global_scope, self.device_context)
135+
136+
def feed_data(self, data):
137+
for key in data:
138+
tensor = self.global_scope.find_var(key).get_tensor()
139+
d = data[key]
140+
tensor.set_dims(d.shape)
141+
tensor.set(d, self.place)
142+
143+
def find_tensor(self, var_name):
144+
return self.global_scope.find_var(var_name).get_tensor()
145+
146+
147+
g_model = Model()

python/paddle/v2/framework/network.py

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ def __impl__(*args, **kwargs):
3030
else:
3131
raise AttributeError("No such attribute %s" % name)
3232

33+
def create_and_add_op(self, type, **kwargs):
34+
return getattr(self, type)(**kwargs)
35+
3336
def add_op(self, op):
3437
if isinstance(op, Network):
3538
self.add_op(op.net)
@@ -38,3 +41,6 @@ def add_op(self, op):
3841

3942
def __str__(self):
4043
return str(self.net)
44+
45+
def __len__(self):
46+
return len(self.net)

python/paddle/v2/framework/op.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ def get_all_op_protos():
99
Get all registered op proto from Paddle C++
1010
:return: list of OpProto
1111
"""
12+
global g_all_op_protos
1213
protostrs = core.get_all_op_protos()
1314
if g_all_op_protos is None:
14-
global g_all_op_protos
1515
g_all_op_protos = dict()
1616
for pbstr in protostrs:
1717
op_proto = framework_pb2.OpProto.FromString(str(pbstr))

0 commit comments

Comments
 (0)