python_api.md 2.8 KB
Newer Older
Y
Yu Yang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
# Design Doc: Python API

<!-- 引言,说明问题 -->

The top level user API in Python should be as same as API in `paddle.v2` after refactoring Paddle from a layer based framework to an operator based framework. There are many new classes in CPP in [compile time] for describing neural networks, such as `Variable`, `Operator`, `Block`. The issue about current design is how to give a proper way to wrap the C++ API to `paddle.v2` API and writing layers in Python.

<!-- 说明为什么我们要先用runtime概念实现Python API。说明我们必须要同时考虑编译器API,进而让之后迁移更简单 -->

This implementation of Python API includes two steps.

1. Implement the Python API using current C++ runtime concepts.
2. Replace the implementation by using compile-time concepts when they are completed.

...


## Python Class about compile-time concepts

<!-- 引言,引出这个表格 -->
| Python Class | Compile-time protobuf |
| --- | --- |
| Block | BlockDesc |
| Operator | OpDesc |
| Variable | VarDesc |


### Block

<!-- TODO -->

```python
class Block(objects):
	def __init__(self, parent=None):
		self.vars_ = map<string, Variable>()
		self.ops_ = vector<Operator>()
		if parent is None:
			self.global_vars = map<string, Variable>()
			self.parent=None
		else:
			self.parent = parent
			self.global_vars = None
	
	def create_global_vars(...):
		if self.parent is not None:
			return self.parent.create_global_vars(...)
		else:
			return self.global_vars.new()
```


### Operator

<!-- TODO -->

```python
class Operator(object):
	def __init__(self, type, inputs, outputs, attrs):
		# create OpDesc in Python
		op_desc = ...
		self.cpp_op_desc_ptr = cpp.to_cpp_op_desc(op_desc)
		cpp.infer_shapes(self.cpp_op_desc_ptr, inputs, outputs)
		outputs.op = self

	def type(self):
		return self.cpp_op_desc_ptr.type()
```

### Variable

<!-- TODO -->

```python
class Variable(object):
    def __init__(self, shape, dtype="float32", name=None, block=None):
        if name is None:
            if prefix is not None:
                name = unique_name_generator(prefix)
            else:
                name = unique_name_generator("unknown")
        self.name = name
        self.block = block
        self.cpp_var_desc_ptr = ...
        self.op = None

    def shape(self):
        cpp_shape = self.cpp_var_desc_ptr.shape()
        return [None if elem < 0 else elem for elem in cpp_shape]
```

### Parameter

<!-- 虽然Parameter不是编译器的概念,但是Python维护一个Parameter可以帮助我们构造计算图,知道哪个参数是可更新的等等 -->

<!-- 参数 is a special Variable -->

```python
class Parameter(Variable):
    def __init__(self, trainable, initialize_attrs, optimize_attrs):
        pass
```

## Layer Functions

<!-- 给出一个Demo如何写Data Layer和FC Layer -->