diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index cafb965d406d93229a442ad8e80f262f9cc615b6..786c987f967411813db12f708530c1fe99d6c363 100755 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -13496,16 +13496,16 @@ def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None): principe of py_func is that Tensor and numpy array can be converted to each other easily. So you can use Python and numpy API to register a python OP. - The forward function of the registered OP is ``func`` and the backward function - of that is ``backward_func``. Paddle will call ``func`` at forward runtime and + The forward function of the registered OP is ``func`` and the backward function + of that is ``backward_func``. Paddle will call ``func`` at forward runtime and call ``backward_func`` at backward runtime(if ``backward_func`` is not None). ``x`` is the input of ``func``, whose type must be Tensor; ``out`` is the output of ``func``, whose type can be either Tensor or numpy array. The input of the backward function ``backward_func`` is ``x``, ``out`` and - the gradient of ``out``. If some variables of ``out`` have no gradient, the - relevant input variable of ``backward_func`` is None. If some variables of - ``x`` do not have a gradient, the user should return None in ``backward_func``. + the gradient of ``out``. If ``out`` have no gradient, the relevant input of + ``backward_func`` is None. If ``x`` do not have a gradient, the user should + return None in ``backward_func``. The data type and shape of ``out`` should also be set correctly before this API is called, and the data type and shape of the gradient of ``out`` and @@ -13520,27 +13520,26 @@ def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None): function and the forward input ``x``. In ``func`` , it's suggested that we actively convert Tensor into a numpy array, so that we can use Python and numpy API arbitrarily. If not, some operations of numpy may not be compatible. - x (Variable|tuple(Variale)|list[Variale]): The input of the forward function ``func``. - It can be Variable|tuple(Variale)|list[Variale], where Variable is Tensor or - Tenosor. In addition, Multiple Variable should be passed in the form of tuple(Variale) - or list[Variale]. - out (Variable|tuple(Variale)|list[Variale]): The output of the forward function ``func``, - it can be Variable|tuple(Variale)|list[Variale], where Variable can be either Tensor - or numpy array. Since Paddle cannot automatically infer the shape and type of ``out``, - you must create ``out`` in advance. + x (Tensor|tuple(Tensor)|list[Tensor]): The input of the forward function ``func``. + It can be Tensor|tuple(Tensor)|list[Tensor]. In addition, Multiple Tensor + should be passed in the form of tuple(Tensor) or list[Tensor]. + out (T|tuple(T)|list[T]): The output of the forward function ``func``, it can be + T|tuple(T)|list[T], where T can be either Tensor or numpy array. Since Paddle + cannot automatically infer the shape and type of ``out``, you must create + ``out`` in advance. backward_func (callable, optional): The backward function of the registered OP. Its default value is None, which means there is no reverse calculation. If it is not None, ``backward_func`` is called to calculate the gradient of ``x`` when the network is at backward runtime. - skip_vars_in_backward_input (Variable, optional): It's used to limit the input - variable list of ``backward_func``, and it can be Variable|tuple(Variale)|list[Variale]. + skip_vars_in_backward_input (Tensor, optional): It's used to limit the input + list of ``backward_func``, and it can be Tensor|tuple(Tensor)|list[Tensor]. It must belong to either ``x`` or ``out``. The default value is None, which means - that no variables need to be removed from ``x`` and ``out``. If it is not None, - these variables will not be the input of ``backward_func``. This parameter is only + that no tensors need to be removed from ``x`` and ``out``. If it is not None, + these tensors will not be the input of ``backward_func``. This parameter is only useful when ``backward_func`` is not None. Returns: - Variable|tuple(Variale)|list[Variale]: The output ``out`` of the forward function ``func``. + Tensor|tuple(Tensor)|list[Tensor]: The output ``out`` of the forward function ``func``. Examples: .. code-block:: python @@ -13548,6 +13547,7 @@ def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None): # example 1: import paddle import six + import numpy as np paddle.enable_static() @@ -13578,16 +13578,31 @@ def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None): dtype=hidden.dtype, shape=hidden.shape) # User-defined forward and backward - hidden = paddle.static.nn.py_func(func=tanh, x=hidden, + hidden = paddle.static.py_func(func=tanh, x=hidden, out=new_hidden, backward_func=tanh_grad, skip_vars_in_backward_input=hidden) # User-defined debug functions that print out the input Tensor - paddle.static.nn.py_func(func=debug_func, x=hidden, out=None) + paddle.static.py_func(func=debug_func, x=hidden, out=None) prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax') - loss = paddle.static.nn.cross_entropy(input=prediction, label=label) - return paddle.mean(loss) + ce_loss = paddle.nn.loss.CrossEntropyLoss() + return ce_loss(prediction, label) + + x = paddle.static.data(name='x', shape=[1,4], dtype='float32') + y = paddle.static.data(name='y', shape=[1,10], dtype='int64') + res = simple_net(x, y) + + exe = paddle.static.Executor(paddle.CPUPlace()) + exe.run(paddle.static.default_startup_program()) + input1 = np.random.random(size=[1,4]).astype('float32') + input2 = np.random.randint(1, 10, size=[1,10], dtype='int64') + out = exe.run(paddle.static.default_main_program(), + feed={'x':input1, 'y':input2}, + fetch_list=[res.name]) + print(out) + + .. code-block:: python # example 2: # This example shows how to turn Tensor into numpy array and @@ -13629,7 +13644,7 @@ def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None): output = create_tmp_var('output','int32', [3,1]) # Multiple Variable should be passed in the form of tuple(Variale) or list[Variale] - paddle.static.nn.py_func(func=element_wise_add, x=[x,y], out=output) + paddle.static.py_func(func=element_wise_add, x=[x,y], out=output) exe=paddle.static.Executor(paddle.CPUPlace()) exe.run(start_program)