From 1443d762fd232203de2e4e512ab7db161983c4c6 Mon Sep 17 00:00:00 2001 From: Yibing Liu Date: Sun, 19 Aug 2018 14:52:34 +0000 Subject: [PATCH] Wrap unsqueeze & squeeze ops --- python/paddle/fluid/layers/nn.py | 82 +++++++++++++++++++ .../fluid/tests/unittests/test_layers.py | 17 ++++ 2 files changed, 99 insertions(+) diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index 66b776c08e4..64864c267d0 100644 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -84,6 +84,8 @@ __all__ = [ 'one_hot', 'autoincreased_step_counter', 'reshape', + 'squeeze', + 'unsqueeze', 'lod_reset', 'lrn', 'pad', @@ -4483,6 +4485,86 @@ def reshape(x, shape, actual_shape=None, act=None, inplace=True, name=None): return helper.append_activation(out) +def squeeze(x, axes, inplace=False, name=None): + """ + Remove single-dimensional entries from the shape of a tensor. Takes a + parameter axes with a list of axes to squeeze. If axes is not provided, all + the single dimensions will be removed from the shape. If an axis is + selected with shape entry not equal to one, an error is raised. + + Examples: + Case 1: + Given + X.shape = (1, 3, 1, 5) + and + axes = [0] + we get: + Out.shape = (3, 1, 5) + Case 2: + Given + X.shape = (1, 3, 1, 5) + and + axes = [] + we get: + Out.shape = (3, 5) + + Args: + x (Variable): The input variable to be squeezed. + axes (list): List of integers, indicating the dimensions to be squeezed. + name (str): Name for this layers. + + Returns: + Variable: Output squeezed variable. + + Examples: + .. code-block:: python + + x = layers.data(name='x', shape=[5, 1, 10]) + y = layers.sequeeze(x, axes=[1]) + """ + helper = LayerHelper("squeeze", **locals()) + out = helper.create_tmp_variable(dtype=x.dtype) + helper.append_op( + type="squeeze", + inputs={"X": x}, + attrs={"axes": axes}, + outputs={"Out": out}) + + return out + +def unsqueeze(x, axes, inplace=False, name=None): + """ + Insert single-dimensional entries to the shape of a tensor. Takes one + required argument axes, a list of dimensions that will be inserted. + Dimension indices in axes are as seen in the output tensor. + + For example: + Given a tensor such that tensor with shape [3, 4, 5], + then Unsqueezed tensor with axes=[0, 4] has shape [1, 3, 4, 5, 1]. + + Args: + x (Variable): The input variable to be unsqueezed. + axes (list): List of integers, indicating the dimensions to be inserted. + name (str): Name for this layers. + + Returns: + Variable: Output unsqueezed variable. + + Examples: + .. code-block:: python + + x = layers.data(name='x', shape=[5, 10]) + y = layers.unsequeeze(x, axes=[1]) + """ + helper = LayerHelper("unsqueeze", **locals()) + out = helper.create_tmp_variable(dtype=x.dtype) + helper.append_op( + type="unsqueeze", + inputs={"X": x}, + attrs={"axes": axes}, + outputs={"Out": out}) + + return out def lod_reset(x, y=None, target_lod=None): """ diff --git a/python/paddle/fluid/tests/unittests/test_layers.py b/python/paddle/fluid/tests/unittests/test_layers.py index 8e707c8b00b..248976a9ffe 100644 --- a/python/paddle/fluid/tests/unittests/test_layers.py +++ b/python/paddle/fluid/tests/unittests/test_layers.py @@ -240,6 +240,22 @@ class TestBook(unittest.TestCase): self.assertIsNotNone(layers.softmax(hid)) print(str(program)) + def test_sequence_unsqueeze(self): + program = Program() + with program_guard(program): + x = layers.data(name='x', shape=[8,2], dtype='float32') + out = layers.unsqueeze(x=x, axes=[1]) + self.assertIsNotNone(out) + print(str(program)) + + def test_squeeze(self): + program = Program() + with program_guard(program): + x = layers.data(name='x', shape=[1, 1, 4], dtype='float32') + out = layers.squeeze(x=x, axes=[0]) + self.assertIsNotNone(out) + print(str(program)) + def test_lrn(self): program = Program() with program_guard(program): @@ -261,6 +277,7 @@ class TestBook(unittest.TestCase): out = layers.sequence_reshape(input=x, new_dim=16) self.assertIsNotNone(out) print(str(program)) + def test_im2sequence(self): program = Program() -- GitLab