提交 c7eb89bb 编写于 作者: Z zhouwei25

Merge branch 'develop' of https://github.com/PaddlePaddle/FluidDoc into develop

......@@ -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
......
......@@ -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]
......@@ -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
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册