From cf5d271c5ad81f2371924764c1d627767f75663d Mon Sep 17 00:00:00 2001 From: Yiqun Liu Date: Wed, 22 May 2019 11:58:24 +0800 Subject: [PATCH] Fix examples of fluid.layers.sums and fluid.layers.DynamicRNN (#17308) * Fix examples of fluid.layers.sums. test=document_preview * Correct the example of DynamicRNN and its functions. test=develop * Add 'import paddle.fluid as fluid' to examples. test=develop * Update API.spec. test=develop * Add space lines. test=develop * Update the API.spec. test=develop --- paddle/fluid/API.spec | 8 +- python/paddle/fluid/layers/control_flow.py | 141 ++++++++++++--------- python/paddle/fluid/layers/tensor.py | 25 ++-- 3 files changed, 104 insertions(+), 70 deletions(-) diff --git a/paddle/fluid/API.spec b/paddle/fluid/API.spec index e9c40998483..4aa4a2bfbbd 100644 --- a/paddle/fluid/API.spec +++ b/paddle/fluid/API.spec @@ -257,7 +257,7 @@ paddle.fluid.layers.create_global_var (ArgSpec(args=['shape', 'value', 'dtype', paddle.fluid.layers.cast (ArgSpec(args=['x', 'dtype'], varargs=None, keywords=None, defaults=None), ('document', '992eb42590fc1c380841a6db72ce78b3')) paddle.fluid.layers.tensor_array_to_tensor (ArgSpec(args=['input', 'axis', 'name'], varargs=None, keywords=None, defaults=(1, None)), ('document', 'b12717d3d4567e6119589f7f655b0cbb')) paddle.fluid.layers.concat (ArgSpec(args=['input', 'axis', 'name'], varargs=None, keywords=None, defaults=(0, None)), ('document', 'f9e905b48123914c78055a45fe23106a')) -paddle.fluid.layers.sums (ArgSpec(args=['input', 'out'], varargs=None, keywords=None, defaults=(None,)), ('document', '42912092418620b4be07f36af31e7816')) +paddle.fluid.layers.sums (ArgSpec(args=['input', 'out'], varargs=None, keywords=None, defaults=(None,)), ('document', '5df743d578638cd2bbb9369499b44af4')) paddle.fluid.layers.assign (ArgSpec(args=['input', 'output'], varargs=None, keywords=None, defaults=(None,)), ('document', 'b690184f3537df5501e4d9d8f31152a5')) paddle.fluid.layers.fill_constant_batch_size_like (ArgSpec(args=['input', 'shape', 'dtype', 'value', 'input_dim_idx', 'output_dim_idx'], varargs=None, keywords=None, defaults=(0, 0)), ('document', 'd4059a2f5763036b07018d76429f9acb')) paddle.fluid.layers.fill_constant (ArgSpec(args=['shape', 'dtype', 'value', 'force_cpu', 'out'], varargs=None, keywords=None, defaults=(False, None)), ('document', '1d8b14729639fa38509c79b9784740fa')) @@ -297,10 +297,10 @@ paddle.fluid.layers.IfElse.output (ArgSpec(args=['self'], varargs='outs', keywor paddle.fluid.layers.IfElse.true_block (ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None), ('document', '6adf97f83acf6453d4a6a4b1070f3754')) paddle.fluid.layers.DynamicRNN.__init__ (ArgSpec(args=['self', 'name'], varargs=None, keywords=None, defaults=(None,)), ('document', '6adf97f83acf6453d4a6a4b1070f3754')) paddle.fluid.layers.DynamicRNN.block (ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None), ('document', '6d3e0a5d9aa519a9773a36e1620ea9b7')) -paddle.fluid.layers.DynamicRNN.memory (ArgSpec(args=['self', 'init', 'shape', 'value', 'need_reorder', 'dtype'], varargs=None, keywords=None, defaults=(None, None, 0.0, False, 'float32')), ('document', 'b9174d4e91505b0c8ecc193eb51e248d')) +paddle.fluid.layers.DynamicRNN.memory (ArgSpec(args=['self', 'init', 'shape', 'value', 'need_reorder', 'dtype'], varargs=None, keywords=None, defaults=(None, None, 0.0, False, 'float32')), ('document', '57cdd0a63747f4c670cdb9d250ceb7e1')) paddle.fluid.layers.DynamicRNN.output (ArgSpec(args=['self'], varargs='outputs', keywords=None, defaults=None), ('document', 'b439a176a3328de8a75bdc5c08eece4a')) -paddle.fluid.layers.DynamicRNN.static_input (ArgSpec(args=['self', 'x'], varargs=None, keywords=None, defaults=None), ('document', 'f29ad2478b6b2ad4f413d2936a331ea0')) -paddle.fluid.layers.DynamicRNN.step_input (ArgSpec(args=['self', 'x', 'level'], varargs=None, keywords=None, defaults=(0,)), ('document', '7568c5ac7622a10288d3307a94134655')) +paddle.fluid.layers.DynamicRNN.static_input (ArgSpec(args=['self', 'x'], varargs=None, keywords=None, defaults=None), ('document', '55ab9c562edd7dabec0bd6fd6c1a28cc')) +paddle.fluid.layers.DynamicRNN.step_input (ArgSpec(args=['self', 'x', 'level'], varargs=None, keywords=None, defaults=(0,)), ('document', '4b300851b5201891d0e11c406e4c7d07')) paddle.fluid.layers.DynamicRNN.update_memory (ArgSpec(args=['self', 'ex_mem', 'new_mem'], varargs=None, keywords=None, defaults=None), ('document', '5d83987da13b98363d6a807a52d8024f')) paddle.fluid.layers.StaticRNN.__init__ (ArgSpec(args=['self', 'name'], varargs=None, keywords=None, defaults=(None,)), ('document', '6adf97f83acf6453d4a6a4b1070f3754')) paddle.fluid.layers.StaticRNN.memory (ArgSpec(args=['self', 'init', 'shape', 'batch_ref', 'init_value', 'init_batch_dim_idx', 'ref_batch_dim_idx'], varargs=None, keywords=None, defaults=(None, None, None, 0.0, 0, 1)), ('document', 'f1b60dc4194d0bb714d6c6f5921b227f')) diff --git a/python/paddle/fluid/layers/control_flow.py b/python/paddle/fluid/layers/control_flow.py index bf8f1413f2e..f53394babf6 100644 --- a/python/paddle/fluid/layers/control_flow.py +++ b/python/paddle/fluid/layers/control_flow.py @@ -1645,23 +1645,7 @@ class DynamicRNN(object): sample sequence can be different. This API automatically process them in batch. - The input lod must be set. Please reference `lod_tensor` - - >>> import paddle.fluid as fluid - >>> data = fluid.layers.data(name='sentence', dtype='int64', lod_level=1) - >>> embedding = fluid.layers.embedding(input=data, size=[65535, 32], - >>> is_sparse=True) - >>> - >>> drnn = fluid.layers.DynamicRNN() - >>> with drnn.block(): - >>> word = drnn.step_input(embedding) - >>> prev = drnn.memory(shape=[200]) - >>> hidden = fluid.layers.fc(input=[word, prev], size=200, act='relu') - >>> drnn.update_memory(prev, hidden) # set prev to hidden - >>> drnn.output(hidden) - >>> - >>> # last is the last time step of rnn. It is the encoding result. - >>> last = fluid.layers.sequence_last_step(drnn()) + The input lod must be set. Please reference to `lod_tensor`. The dynamic RNN will unfold sequence into timesteps. Users need to define how to process each time step during the :code:`with` block. @@ -1671,10 +1655,30 @@ class DynamicRNN(object): The dynamic RNN can mark multiple variables as its output. Use `drnn()` to get the output sequence. - + NOTES: Currently it is not supported that setting is_sparse to True of any layers within DynamicRNN. + + Examples: + .. code-block:: python + + import paddle.fluid as fluid + + sentence = fluid.layers.data(name='sentence', shape=[1], dtype='int64', lod_level=1) + embedding = fluid.layers.embedding(input=sentence, size=[65536, 32], is_sparse=True) + + drnn = fluid.layers.DynamicRNN() + with drnn.block(): + word = drnn.step_input(embedding) + prev = drnn.memory(shape=[200]) + hidden = fluid.layers.fc(input=[word, prev], size=200, act='relu') + drnn.update_memory(prev, hidden) # set prev to hidden + drnn.output(hidden) + + # Get the last time step of rnn. It is the encoding result. + rnn_output = drnn() + last = fluid.layers.sequence_last_step(rnn_output) """ BEFORE_RNN = 0 IN_RNN = 1 @@ -1701,8 +1705,8 @@ class DynamicRNN(object): Mark a sequence as a dynamic RNN input. Args: - x(Variable): The input sequence. - level(int): The level of lod used to split steps. Default: 0. + x (Variable): The input sequence which should have lod information. + level (int): The level of lod used to split steps. Default: 0. Returns: The current timestep in the input sequence. @@ -1753,13 +1757,37 @@ class DynamicRNN(object): def static_input(self, x): """ Mark a variable as a RNN input. The input will not be scattered into - time steps. + time steps. It is optional. Args: - x(Variable): The input variable. + x (Variable): The input variable. Returns: The input variable that can access in RNN. + + Examples: + .. code-block:: python + + import paddle.fluid as fluid + + sentence = fluid.layers.data(name='sentence', dtype='float32', shape=[32], lod_level=1) + encoder_proj = fluid.layers.data(name='encoder_proj', dtype='float32', shape=[32], lod_level=1) + decoder_boot = fluid.layers.data(name='boot', dtype='float32', shape=[10], lod_level=1) + + drnn = fluid.layers.DynamicRNN() + with drnn.block(): + current_word = drnn.step_input(sentence) + encoder_word = drnn.static_input(encoder_proj) + hidden_mem = drnn.memory(init=decoder_boot, need_reorder=True) + fc_1 = fluid.layers.fc(input=encoder_word, size=30, bias_attr=False) + fc_2 = fluid.layers.fc(input=current_word, size=30, bias_attr=False) + decoder_inputs = fc_1 + fc_2 + h, _, _ = fluid.layers.gru_unit(input=decoder_inputs, hidden=hidden_mem, size=30) + drnn.update_memory(hidden_mem, h) + out = fluid.layers.fc(input=h, size=10, bias_attr=True, act='softmax') + drnn.output(out) + + rnn_output = drnn() """ self._assert_in_rnn_block_("static_input") if not isinstance(x, Variable): @@ -1836,54 +1864,51 @@ class DynamicRNN(object): the input variable. It should be set to true when the initialized memory depends on the input sample. - For example, - - >>> import paddle.fluid as fluid - >>> sentence = fluid.layers.data( - >>> name='sentence', dtype='float32', shape=[32]) - >>> boot_memory = fluid.layers.data( - >>> name='boot', dtype='float32', shape=[10]) - >>> - >>> drnn = fluid.layers.DynamicRNN() - >>> with drnn.block(): - >>> word = drnn.step_input(sentence) - >>> memory = drnn.memory(init=boot_memory, need_reorder=True) - >>> hidden = fluid.layers.fc( - >>> input=[word, memory], size=10, act='tanh') - >>> drnn.update_memory(ex_mem=memory, new_mem=hidden) - >>> drnn.output(hidden) - >>> rnn_output = drnn() + Examples: + .. code-block:: python + + import paddle.fluid as fluid + + sentence = fluid.layers.data(name='sentence', shape=[32], dtype='float32', lod_level=1) + boot_memory = fluid.layers.data(name='boot', shape=[10], dtype='float32', lod_level=1) + + drnn = fluid.layers.DynamicRNN() + with drnn.block(): + word = drnn.step_input(sentence) + memory = drnn.memory(init=boot_memory, need_reorder=True) + hidden = fluid.layers.fc(input=[word, memory], size=10, act='tanh') + drnn.update_memory(ex_mem=memory, new_mem=hidden) + drnn.output(hidden) + + rnn_output = drnn() Otherwise, if :code:`shape`, :code:`value`, :code:`dtype` are set, the :code:`memory` will be initialized by this :code:`value`. - For example, + Examples: + .. code-block:: python - >>> import paddle.fluid as fluid - >>> sentence = fluid.layers.data( - >>> name='sentence', dtype='float32', shape=[32]) - >>> - >>> drnn = fluid.layers.DynamicRNN() - >>> with drnn.block(): - >>> word = drnn.step_input(sentence) - >>> memory = drnn.memory(shape=[10], dtype='float32', value=0) - >>> hidden = fluid.layers.fc( - >>> input=[word, memory], size=10, act='tanh') - >>> drnn.update_memory(ex_mem=memory, new_mem=hidden) - >>> drnn.output(hidden) - >>> rnn_output = drnn() + import paddle.fluid as fluid + sentence = fluid.layers.data(name='sentence', dtype='float32', shape=[32], lod_level=1) + + drnn = fluid.layers.DynamicRNN() + with drnn.block(): + word = drnn.step_input(sentence) + memory = drnn.memory(shape=[10], dtype='float32', value=0) + hidden = fluid.layers.fc(input=[word, memory], size=10, act='tanh') + drnn.update_memory(ex_mem=memory, new_mem=hidden) + drnn.output(hidden) - Args: - init(Variable|None): The initialized variable. + rnn_output = drnn() - shape(list|tuple): The memory shape. NOTE the shape does not contain batch_size. + Args: + init(Variable|None): The initialized variable. + shape(list|tuple): The memory shape. The shape does not contain batch_size. value(float): the initalized value. - need_reorder(bool): True if the initialized memory depends on the input sample. - dtype(str|numpy.dtype): The data type of the initialized memory. Returns: diff --git a/python/paddle/fluid/layers/tensor.py b/python/paddle/fluid/layers/tensor.py index 9a0afcd4516..f1ad1cb9859 100644 --- a/python/paddle/fluid/layers/tensor.py +++ b/python/paddle/fluid/layers/tensor.py @@ -275,14 +275,23 @@ def sums(input, out=None): Examples: .. code-block:: python - tmp = fluid.layers.zeros(shape=[10], dtype='int32') - i = fluid.layers.fill_constant(shape=[1], dtype='int64', value=10) - a0 = layers.array_read(array=tmp, i=i) - i = layers.increment(x=i) - a1 = layers.array_read(array=tmp, i=i) - mean_a0 = layers.mean(a0) - mean_a1 = layers.mean(a1) - a_sum = layers.sums(input=[mean_a0, mean_a1]) + import paddle.fluid as fluid + + # sum of several tensors + a0 = fluid.layers.fill_constant(shape=[1], dtype='int64', value=1) + a1 = fluid.layers.fill_constant(shape=[1], dtype='int64', value=2) + a2 = fluid.layers.fill_constant(shape=[1], dtype='int64', value=3) + sums = fluid.layers.sums(input=[a0, a1, a2]) + + # sum of a tensor array + array = fluid.layers.create_array('int64') + i = fluid.layers.zeros(shape=[1], dtype='int64', force_cpu=True) + fluid.layers.array_write(a0, array=array, i=i) + i = fluid.layers.increment(x=i) + fluid.layers.array_write(a1, array=array, i=i) + i = fluid.layers.increment(x=i) + fluid.layers.array_write(a2, array=array, i=i) + sums = fluid.layers.sums(input=array) """ helper = LayerHelper('sum', **locals()) if out is None: -- GitLab