diff --git a/doc/paddle/api/alias_api_mapping b/doc/paddle/api/alias_api_mapping index a7470d9ebd64aa0944fef0dda08f281a83d3db49..9216cd32944766f80a68ad214f18480a069c550d 100644 --- a/doc/paddle/api/alias_api_mapping +++ b/doc/paddle/api/alias_api_mapping @@ -225,7 +225,7 @@ paddle.fluid.layers.pool2d paddle.nn.functional.pool2d,paddle.nn.functional.pool paddle.nn.functional.norm.batch_norm paddle.nn.functional.batch_norm paddle.nn.layer.common.UpsamplingNearest2d paddle.nn.UpsamplingNearest2d,paddle.nn.layer.UpsamplingNearest2d paddle.nn.functional.conv.conv_transpose3d paddle.nn.functional.conv_transpose3d -paddle.fluid.layers.switch_case paddle.nn.switch_case,paddle.nn.control_flow.switch_case +paddle.fluid.layers.switch_case paddle.static.nn.switch_case paddle.fluid.layers.image_resize paddle.nn.functional.image_resize,paddle.nn.functional.vision.image_resize paddle.nn.layer.conv.Conv3d paddle.nn.Conv3d,paddle.nn.layer.Conv3d paddle.fluid.layers.logical_or paddle.logical_or,paddle.tensor.logical_or,paddle.tensor.logic.logical_or diff --git a/doc/paddle/api/paddle/fluid/layers/switch_case_cn.rst b/doc/paddle/api/paddle/fluid/layers/switch_case_cn.rst index c6999157f428298be2ab570976fc16d32aebcd9e..87519063994a4fc0fc4aae7a3b95034b0de301bc 100644 --- a/doc/paddle/api/paddle/fluid/layers/switch_case_cn.rst +++ b/doc/paddle/api/paddle/fluid/layers/switch_case_cn.rst @@ -6,13 +6,13 @@ switch_case .. py:function:: paddle.fluid.layers.switch_case(branch_index, branch_fns, default=None, name=None) - +:api_attr: 声明式编程模式(静态图) 该OP的运行方式类似于c++的switch/case。 参数: - - **branch_index** (Variable)- 形状为[1]的Tensor,指定将要执行的分支。数据类型是 ``int32``, ``int64`` 或 ``uint8``。 + - **branch_index** (Tensor)- 形状为[1]的Tensor,指定将要执行的分支。数据类型是 ``int32``, ``int64`` 或 ``uint8``。 - **branch_fns** (dict|list|tuple) - 如果 ``branch_fns`` 是一个list或tuple,它的元素可以是 (int, callable) 二元组,即由整数和可调用对象构成的二元组,整数表示对应的可调用对象的键;也可以仅仅是可调用对象,它在list或者tuple中的实际索引值将作为该可调用对象的键。如果 ``branch_fns`` 是一个字典,那么它的键是整数,它的值是可调用对象。所有的可调用对象都返回相同结构的Tensor。 - **default** (callable,可选) - 可调用对象,返回一个或多个张量。 - **name** (str,可选) – 具体用法请参见 :ref:`api_guide_Name` ,一般无需设置,默认值:None。 @@ -20,7 +20,7 @@ switch_case 返回:如果 ``branch_fns`` 中存在与 ``branch_index`` 匹配的可调用对象,则返回该可调用对象的返回结果;如果 ``branch_fns`` 中不存在与 ``branch_index`` 匹配的可调用对象且 ``default`` 不是None,则返回调用 ``default`` 的返回结果; 如果 ``branch_fns`` 中不存在与 ``branch_index`` 匹配的可调用对象且 ``default`` 是None,则返回 ``branch_fns`` 中键值最大的可调用对象的返回结果。 -返回类型:Variable|list(Variable) +返回类型:Tensor|list(Tensor) 抛出异常: - ``TypeError`` - 如果 ``branch_index`` 的类型不是list或tuple。 @@ -37,43 +37,42 @@ switch_case .. code-block:: python - import paddle.fluid as fluid - import paddle.fluid.layers as layers + import paddle + + paddle.enable_static() def fn_1(): - return layers.fill_constant(shape=[1, 2], dtype='float32', value=1) + return paddle.fill_constant(shape=[1, 2], dtype='float32', value=1) def fn_2(): - return layers.fill_constant(shape=[2, 2], dtype='int32', value=2) + return paddle.fill_constant(shape=[2, 2], dtype='int32', value=2) def fn_3(): - return layers.fill_constant(shape=[3], dtype='int32', value=3) + return paddle.fill_constant(shape=[3], dtype='int32', value=3) - main_program = fluid.default_startup_program() - startup_program = fluid.default_main_program() - with fluid.program_guard(main_program, startup_program): - index_1 = layers.fill_constant(shape=[1], dtype='int32', value=1) - index_2 = layers.fill_constant(shape=[1], dtype='int32', value=2) + main_program = paddle.static.default_startup_program() + startup_program = paddle.static.default_main_program() + with paddle.static.program_guard(main_program, startup_program): + index_1 = paddle.fill_constant(shape=[1], dtype='int32', value=1) + index_2 = paddle.fill_constant(shape=[1], dtype='int32', value=2) - out_1 = layers.switch_case( + out_1 = paddle.static.nn.switch_case( branch_index=index_1, branch_fns={1: fn_1, 2: fn_2}, default=fn_3) - out_2 = layers.switch_case( + out_2 = paddle.static.nn.switch_case( branch_index=index_2, branch_fns=[(1, fn_1), (2, fn_2)], default=fn_3) # Argument default is None and no index matches. fn_3 will be called because of the max index 7. - out_3 = layers.switch_case( + out_3 = paddle.static.nn.switch_case( branch_index=index_2, branch_fns=[(0, fn_1), (4, fn_2), (7, fn_3)]) - exe = fluid.Executor(fluid.CPUPlace()) + exe = paddle.static.Executor(paddle.CPUPlace()) res_1, res_2, res_3 = exe.run(main_program, fetch_list=[out_1, out_2, out_3]) print(res_1) # [[1. 1.]] print(res_2) # [[2 2] [2 2]] print(res_3) # [3 3 3] - - diff --git a/doc/paddle/guides/dygraph_to_static/input_spec_cn.rst b/doc/paddle/guides/dygraph_to_static/input_spec_cn.rst index 26db16711283e109f8925993af2c521be13fc737..2106f4754559c5b99e67abe554e2d9a0263b4475 100644 --- a/doc/paddle/guides/dygraph_to_static/input_spec_cn.rst +++ b/doc/paddle/guides/dygraph_to_static/input_spec_cn.rst @@ -197,4 +197,46 @@ InputSpec 初始化中的只有 ``shape`` 是必须参数, ``dtype`` 和 ``nam 其中 ``input_spec`` 参数是长度为 2 的 list ,对应 forward 函数的 x 和 bias_info 两个参数。 ``input_spec`` 的最后一个元素是包含键名为 x 的 InputSpec 对象的 dict ,对应参数 bias_info 的 Tensor 签名信息。 +2.4 指定非Tensor参数类型 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +目前,``to_static`` 装饰器中的 ``input_spec`` 参数仅接收 ``InputSpec`` 类型对象。若被装饰函数的参数列表除了 Tensor 类型,还包含其他如 Int、 String 等非 Tensor 类型时,推荐在函数中使用 kwargs 形式定义非 Tensor 参数,如下述样例中的 use_act 参数。 + +.. code-block:: python + + class SimpleNet(Layer): + def __init__(self, ): + super(SimpleNet, self).__init__() + self.linear = paddle.nn.Linear(10, 3) + self.relu = paddle.nn.ReLU() + + @to_static(input_spec=[InputSpec(shape=[None, 10], name='x')]) + def forward(self, x, use_act=False): + out = self.linear(x) + if use_act: + out = self.relu(out) + return out + + net = SimpleNet() + adam = paddle.optimizer.Adam(parameters=net.parameters()) + + # train model + batch_num = 10 + for step in range(batch_num): + x = paddle.rand([4, 10], 'float32') + use_act = (step%2 == 0) + out = net(x, use_act) + loss = paddle.mean(out) + loss.backward() + adam.minimize(loss) + net.clear_gradients() + + # save inference model with use_act=False + paddle.jit.save(net, model_path='./simple_net') + + +在上述样例中,step 为奇数时,use_act 取值为 False ; step 为偶数时, use_act 取值为 True 。动转静支持非 Tensor 参数在训练时取不同的值,且保证了取值不同的训练过程都可以更新模型的网络参数,行为与动态图一致。 + +kwargs 参数的默认值主要用于保存推理模型。在借助 ``paddle.jit.save`` 保存预测模型时,动转静会根据 input_spec 和 kwargs 的默认值保存推理模型和网络参数。因此建议将 kwargs 参数默认值设置为预测时的取值。 + 更多关于动转静 ``to_static`` 搭配 ``paddle.jit.save/load`` 的使用方式,可以参考 :ref:`user_guide_model_save_load` 。 \ No newline at end of file diff --git a/doc/paddle/guides/dygraph_to_static/input_spec_en.rst b/doc/paddle/guides/dygraph_to_static/input_spec_en.rst index c7c62ffc668f24dc9b25aa9a371152d26125250e..a7b42307430e33bc44a51b2ce5c07089fee1b402 100644 --- a/doc/paddle/guides/dygraph_to_static/input_spec_en.rst +++ b/doc/paddle/guides/dygraph_to_static/input_spec_en.rst @@ -194,3 +194,46 @@ If a function takes an argument of type dict, the element in the ``input_spec`` The length of ``input_spec`` is 2 corresponding to arguments x and bias_info in forward function. The last element of ``input_spec`` is a InputSpec dict with same key corresponding to signature information of bias_info. + + +2.4 Specify non-Tensor arguments +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Currently, the ``input_spec`` from ``to_static`` decorator only receives objects with ``InputSpec`` type. When the decorated function contains some non-Tensor arguments, such as Int, String or other python types, we recommend to use kwargs with default values as argument, see use_act in followed example. + +.. code-block:: python + + class SimpleNet(Layer): + def __init__(self, ): + super(SimpleNet, self).__init__() + self.linear = paddle.nn.Linear(10, 3) + self.relu = paddle.nn.ReLU() + + @to_static(input_spec=[InputSpec(shape=[None, 10], name='x')]) + def forward(self, x, use_act=False): + out = self.linear(x) + if use_act: + out = self.relu(out) + return out + + net = SimpleNet() + adam = paddle.optimizer.Adam(parameters=net.parameters()) + + # train model + batch_num = 10 + for step in range(batch_num): + x = paddle.rand([4, 10], 'float32') + use_act = (step%2 == 0) + out = net(x, use_act) + loss = paddle.mean(out) + loss.backward() + adam.minimize(loss) + net.clear_gradients() + + # save inference model with use_act=False + paddle.jit.save(net, model_path='./simple_net') + + +In above example, use_act is equal to True if step is an odd number, and False if step is an even number. We support non-tensor argument applied to different values during training after conversion. Moreover, the shared parameters of the model can be updated during the training with different values. The behavior is consistent with the dynamic graph. + +The default value of the kwargs is primarily used for saving inference model. The inference model and network parameters will be exported based on input_spec and the default values of kwargs. Therefore, it is recommended to set the default value of the kwargs arguments for prediction. \ No newline at end of file