Created by: kuke
This pull request tries to define the way to implement a complex number neural network in PaddlePaddle.
Major changes and features:
- Add a new class
ComplexVariable
to hold complex numbers, and expose frequently used attributesname
,shape
anddtype
for it; - Support methods
to_variable()
,.numpy()
andprint()
to make sure thatComplexVariable
has the same interaction experience as theVariable
defined on real number. - Users can also visit the members and methods of the real or imaginary part of
ComplexVariable
seperately as a commonVariable
. - Lay down API rules. Users only need to change the prefix of APIs from
paddle
topaddle.complex
to build a complex number model, as the new added layers for element-wise complex numberadd
/sub
/mul
/div
demonstrated.
The usage (only support DyGraph at present):
>>> import numpy as np
>>> import paddle
>>> import paddle.fluid.dygraph as dg
>>> a = np.array([[1.0+1.0j, 2.0+1.0j], [3.0+1.0j, 4.0+1.0j]])
>>> b = np.array([[1.0+1.0j, 1.0+1.0j]])
>>> c = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> with dg.guard():
... x = dg.to_variable(a, "complex_x")
... y = dg.to_variable(b)
... z = dg.to_variable(c)
... out = paddle.complex.elementwise_add(x, y)
... print(out)
...
REAL: name tmp_1, dtype: VarType.FP64 shape: [2L, 2L] lod: {}
dim: 2, 2
layout: NCHW
dtype: double
data: [2 3 4 5]
IMAG: name tmp_2, dtype: VarType.FP64 shape: [2L, 2L] lod: {}
dim: 2, 2
layout: NCHW
dtype: double
data: [2 2 2 2]
>>> print(type(z), type(out))
(<class 'paddle.fluid.core_avx.VarBase'>, <class 'paddle.fluid.framework.ComplexVariable'>)
>>> print(out.numpy())
[[2.+2.j 3.+2.j]
[4.+2.j 5.+2.j]]
>>> out.name
{'real': u'tmp_1', 'imag': u'tmp_2'}
>>> out.name = "out"
>>> out.name
{'real': u'out.real', 'imag': u'out.imag'}
>>> out.real.name = "new_name"
>>> out.name
{'real': u'new_name', 'imag': u'out.imag'}
>>> out.dtype
'complex128'
>>> out.shape
[2L, 2L]
>>> out.real.stop_gradient = True
>>> out.imag.stop_gradient = False
>>> out.real.stop_gradient
True
>>> out.imag.stop_gradient
False