提交 f05144ee 编写于 作者: Y Yu Yang

Merge branch 'feature/python_api_design' of github.com:reyoung/Paddle into...

Merge branch 'feature/python_api_design' of github.com:reyoung/Paddle into feature/python_api_design
...@@ -82,18 +82,16 @@ After creating a C++ `OpDesc`, `Operator` in Python can only reads the attribute ...@@ -82,18 +82,16 @@ After creating a C++ `OpDesc`, `Operator` in Python can only reads the attribute
### Variable ### Variable
<!-- TODO --> Operators' inputs, outputs, and parameters are all variables. In our design, a variable has four key attributes: its name(`name`), the block it belongs to(`block`), a pointer pointed to its C++ Protobuf object(`cpp_var_desc_ptr`), and the operator it is created by(`op`). All of these attributes are initialized in the constructor, except the `op`. The `op` will keep being `None` till the variable is taken as an operator's output.
```python ```python
class Variable(object): class Variable(object):
def __init__(self, shape, dtype="float32", name=None, block=None): def __init__(self, shape, dtype="float32", name=None, block=None):
if name is None: if name is None:
if prefix is not None: name = unique_name_generator()
name = unique_name_generator(prefix)
else:
name = unique_name_generator("unknown")
self.name = name self.name = name
self.block = block self.block = block
# build C++ Protobuf object
self.cpp_var_desc_ptr = ... self.cpp_var_desc_ptr = ...
self.op = None self.op = None
...@@ -102,11 +100,13 @@ class Variable(object): ...@@ -102,11 +100,13 @@ class Variable(object):
return [None if elem < 0 else elem for elem in cpp_shape] return [None if elem < 0 else elem for elem in cpp_shape]
``` ```
### Parameter The Protobuf object should be created in C++ not Python because it is needed by infershape, and infershape is implemented by C++ code. The C++ Protobuf object is accessible for Python through the `cpp_var_desc_ptr`, just like how `shape()` function does.
The user is allowed to build a variable without specifying its name. If so, it is going to be assigned with an automatically generated unique name.
<!-- 虽然Parameter不是编译器的概念,但是Python维护一个Parameter可以帮助我们构造计算图,知道哪个参数是可更新的等等 --> ### Parameter
<!-- 参数 is a special Variable --> The parameter is a kind of special variable. They need to be initialized at the very beginning and updated after each batch training. So if a variable is a parameter, our compiler will add an initializer op and an optimizer op for it during the building process of computation graph. Apart from these, there is no more difference between variable and parameter. In other words, 'parameter' is only a label attached to variables, to tell the compiler these ones require additional processing.
```python ```python
class Parameter(Variable): class Parameter(Variable):
...@@ -114,6 +114,43 @@ class Parameter(Variable): ...@@ -114,6 +114,43 @@ class Parameter(Variable):
pass pass
``` ```
The class `Parameter` is derived from class `Variable`. In addition to variables have, parameters are able to hold their initializing and updating information. A parameter's `self.op` will always be `None` because it can never be an operator's output.
## Layer Functions ## Layer Functions
<!-- 给出一个Demo如何写Data Layer和FC Layer --> A layer is a Python function. When it is invoked, it creates a series of operators and variables then inserts them into the block. It is something like the macro in C++. It is called 'Layer' because the combination of added operators acts just like what a neural network layer does.
Here are examples of how to write a data layer and FC layer:
### Data Layer
```python
def data_layer(name, type, block=None):
if block is None:
block = g_block
# type = dense_vector(size=10) / integer_value(range=10)
return block.create_global_var(
name=name,
shape=[None] + type.dims(),
dtype=type.dtype)
```
Before building new variables, we need to specify which block to use. If we don't, the default one `g_block` will be used. In the above `data_layer` code, a variable is created and be inserted into the root block to make it global. This variable is going to be used as input data of the whole network.
### FC Layer
```python
def fc_layer(input, size, block=None, ...):
if block is None:
block = g_block
w = block.create_parameter(...)
b = block.create_parameter(...)
out = stack.create_var()
op = block.append_operator(Operator("FC", X=input, W=w, b=b, Out=out))
out.op = op
return out
```
In the `fc_layer` code, we create two parameters(`w` and `b`), one variable(`out`) and one operator(`FC operator`), then insert all of them into the specified block.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册