From 5dc51750079d03b3eb66ebb2dd241bdb14987da6 Mon Sep 17 00:00:00 2001 From: whs Date: Wed, 19 Sep 2018 12:29:16 +0800 Subject: [PATCH] Add python api for expand op. (#13453) * Add python api for expand op. * Fix unitest. * Remove 'out' from arguments and fix code style. * fix API.spec * Fix API * Fix unitest --- paddle/fluid/API.spec | 1 + python/paddle/fluid/layers/nn.py | 51 +++++++++++++++++++ .../fluid/tests/unittests/test_layers.py | 7 +++ 3 files changed, 59 insertions(+) diff --git a/paddle/fluid/API.spec b/paddle/fluid/API.spec index bbd9429e30..6876f5423d 100644 --- a/paddle/fluid/API.spec +++ b/paddle/fluid/API.spec @@ -168,6 +168,7 @@ paddle.fluid.layers.stack ArgSpec(args=['x', 'axis'], varargs=None, keywords=Non paddle.fluid.layers.pad2d ArgSpec(args=['input', 'paddings', 'mode', 'pad_value', 'data_format', 'name'], varargs=None, keywords=None, defaults=([0, 0, 0, 0], 'constant', 0.0, 'NCHW', None)) paddle.fluid.layers.unstack ArgSpec(args=['x', 'axis', 'num'], varargs=None, keywords=None, defaults=(0, None)) paddle.fluid.layers.sequence_enumerate ArgSpec(args=['input', 'win_size', 'pad_value', 'name'], varargs=None, keywords=None, defaults=(0, None)) +paddle.fluid.layers.expand ArgSpec(args=['x', 'expand_times', 'name'], varargs=None, keywords=None, defaults=(None,)) paddle.fluid.layers.sequence_concat ArgSpec(args=['input', 'name'], varargs=None, keywords=None, defaults=(None,)) paddle.fluid.layers.data ArgSpec(args=['name', 'shape', 'append_batch_size', 'dtype', 'lod_level', 'type', 'stop_gradient'], varargs=None, keywords=None, defaults=(True, 'float32', 0, VarType.LOD_TENSOR, True)) paddle.fluid.layers.open_files ArgSpec(args=['filenames', 'shapes', 'lod_levels', 'dtypes', 'thread_num', 'buffer_size', 'pass_num', 'is_test'], varargs=None, keywords=None, defaults=(None, None, 1, None)) diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index b0b3b0ad6f..e8a11e68b1 100644 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -113,6 +113,7 @@ __all__ = [ 'pad2d', 'unstack', 'sequence_enumerate', + 'expand', 'sequence_concat', ] @@ -6118,3 +6119,53 @@ def unstack(x, axis=0, num=None): attrs={'axis': axis, 'num': num}) return outs + + +def expand(x, expand_times, name=None): + """Expand operator tiles the input by given times number. You should set times + number for each dimension by providing attribute 'expand_times'. The rank of X + should be in [1, 6]. Please note that size of 'expand_times' must be the same + with X's rank. Following is a using case: + + + .. code-block:: text + + Input(X) is a 3-D tensor with shape [2, 3, 1]: + + [ + [[1], [2], [3]], + [[4], [5], [6]] + ] + + Attr(expand_times): [1, 2, 2] + + Output(Out) is a 3-D tensor with shape [2, 6, 2]: + + [ + [[1, 1], [2, 2], [3, 3], [1, 1], [2, 2], [3, 3]], + [[4, 4], [5, 5], [6, 6], [4, 4], [5, 5], [6, 6]] + ] + + Args: + x (Variable): A tensor with rank in [1, 6]. + expand_times (list|tuple): Expand times number for each dimension. + + Returns: + Variable: The expanded variable which is a LoDTensor. After expanding, size of each dimension of Output(Out) is equal to ithe size of the corresponding dimension of Input(X) multiplying the corresponding value given by expand_times. + + + Examples: + .. code-block:: python + + x = fluid.layers.data(name='x', shape=[10], dtype='float32') + out = fluid.layers.expand(x=x, expand_times=[1, 2, 2]) + """ + helper = LayerHelper('expand', input=x, **locals()) + dtype = helper.input_dtype(input_param_name='x') + out = helper.create_tmp_variable(dtype) + helper.append_op( + type='expand', + inputs={'X': x}, + outputs={'Out': out}, + attrs={'expand_times': expand_times}) + return out diff --git a/python/paddle/fluid/tests/unittests/test_layers.py b/python/paddle/fluid/tests/unittests/test_layers.py index b04346b052..7a97d907f4 100644 --- a/python/paddle/fluid/tests/unittests/test_layers.py +++ b/python/paddle/fluid/tests/unittests/test_layers.py @@ -565,6 +565,13 @@ class TestBook(unittest.TestCase): out = layers.cross_entropy(x, label, False, 4) self.assertIsNotNone(out) + def test_expand(self): + program = Program() + with program_guard(program): + x = layers.data(name="input", shape=[10], dtype='int32') + out = layers.expand(x, [1, 2]) + print(str(program)) + if __name__ == '__main__': unittest.main() -- GitLab