From 8266fcc3be869cfef42ab0ec597b2b4ce08dd37d Mon Sep 17 00:00:00 2001 From: yangyaming Date: Tue, 16 Jan 2018 21:31:08 +0800 Subject: [PATCH 1/5] Add pyton wrapper for row conv operator. --- doc/api/v2/fluid/layers.rst | 5 +++ python/paddle/v2/fluid/layers/nn.py | 65 ++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/doc/api/v2/fluid/layers.rst b/doc/api/v2/fluid/layers.rst index 62c154e65dcff1..ad3c70a6f1e940 100644 --- a/doc/api/v2/fluid/layers.rst +++ b/doc/api/v2/fluid/layers.rst @@ -493,3 +493,8 @@ swish ------ .. autofunction:: paddle.v2.fluid.layers.swish :noindex: + +row_conv +-------- +.. autofunction:: paddle.v2.fluid.layers.row_conv + :noindex: diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 4e8fd407c9983e..7c694ed777088c 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -50,6 +50,7 @@ 'sequence_last_step', 'dropout', 'split', + 'row_conv', ] @@ -1547,13 +1548,13 @@ def split(input, num_or_sections, dim=-1): Args: input (Variable): The input variable which is a Tensor or LoDTensor. - num_or_sections (int|list): If :attr:`num_or_sections` is an integer, - then the integer indicates the number of equal sized sub-tensors - that the tensor will be divided into. If :attr:`num_or_sections` - is a list of integers, the length of list indicates the number of - sub-tensors and the integers indicate the sizes of sub-tensors' + num_or_sections (int|list): If :attr:`num_or_sections` is an integer, + then the integer indicates the number of equal sized sub-tensors + that the tensor will be divided into. If :attr:`num_or_sections` + is a list of integers, the length of list indicates the number of + sub-tensors and the integers indicate the sizes of sub-tensors' :attr:`dim` dimension orderly. - dim (int): The dimension along which to split. If :math:`dim < 0`, the + dim (int): The dimension along which to split. If :math:`dim < 0`, the dimension to split along is :math:`rank(input) + dim`. Returns: @@ -1597,3 +1598,55 @@ def split(input, num_or_sections, dim=-1): 'axis': dim }) return outs + + +def row_conv(input, future_context_size, param_attr=None, act=None): + """Row Conv Operator. This layer will apply lookahead convolution to + **input**. The input variable should be a 2D LoDTensor with shape [T, D]. + Parameters with shape [future_context_size + 1, D] will be created. The math + equation of row convolution is as following: + + .. math:: + Out_{i} = \sum_{j = i} ^ {i + \\tau} X_{j} \odot W_{i - j} + + In the above equation: + + * :math:`Out_{i}`: The i-th row of output variable with shape [1, D]. + * :math:`\\tau`: Future context size. + * :math:`X_{j}`: The j-th row of input variable with shape [1, D]. + * :math:`W_{i-j}`: The (i-j)-th row of parameters with shape [1, D]. + + More details about row_conv please refer to the paper \ + (http://www.cs.cmu.edu/~dyogatam/papers/wang+etal.iclrworkshop2016.pdf) and + the design document \ + (https://github.com/PaddlePaddle/Paddle/issues/2228#issuecomment-303903645). + + Args: + input (Variable): Input variable, a 2D LoDTensor with shape [T, D]. + future_context_size (int): Future context size. + param_attr (ParamAttr): Attributes of parameters, including + name, initializer etc. + act (str): Non-linear activation to be applied to output variable. + + Returns: + Variable: The output tensor with same shape as input tensor. + + Examples: + .. code-block:: python + + x = fluid.layers.data(name='x', shape=[16], + dtype='float32', lod_level=1) + out = fluid.layers.row_conv(input=x, future_context_size=2) + """ + helper = LayerHelper('row_conv', **locals()) + dtype = helper.input_dtype() + filter_shape = [future_context_size + 1, input.shape[1]] + filter_param = helper.create_parameter( + attr=helper.param_attr, shape=filter_shape, dtype=dtype) + out = helper.create_tmp_variable(dtype) + helper.append_op( + type='row_conv', + inputs={'X': [input], + 'Filter': [filter_param]}, + outputs={'Out': [out]}) + return out From 2a0a576130b3b04f3555479f1850fd91dbba4d9a Mon Sep 17 00:00:00 2001 From: yangyaming Date: Tue, 16 Jan 2018 21:40:34 +0800 Subject: [PATCH 2/5] Add non-linear activation. --- python/paddle/v2/fluid/layers/nn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 7c694ed777088c..4546616d1af9a9 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -1649,4 +1649,4 @@ def row_conv(input, future_context_size, param_attr=None, act=None): inputs={'X': [input], 'Filter': [filter_param]}, outputs={'Out': [out]}) - return out + return helper.append_activation(out) From 5c2318a989e003a5293eee844e3da79b77380c8e Mon Sep 17 00:00:00 2001 From: yangyaming Date: Mon, 22 Jan 2018 13:40:11 +0800 Subject: [PATCH 3/5] Add unit test for python wrapper. --- python/paddle/v2/fluid/layers/nn.py | 3 ++- python/paddle/v2/fluid/tests/test_layers.py | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 33dc985ba5553b..10a7dd4b0786dc 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -1985,7 +1985,8 @@ def row_conv(input, future_context_size, param_attr=None, act=None): In the above equation: * :math:`Out_{i}`: The i-th row of output variable with shape [1, D]. - * :math:`\\tau`: Future context size. + * :math:`\\tau`: Future context size. Please note, the shape of + convolution kernel is [future_context_size + 1, D]. * :math:`X_{j}`: The j-th row of input variable with shape [1, D]. * :math:`W_{i-j}`: The (i-j)-th row of parameters with shape [1, D]. diff --git a/python/paddle/v2/fluid/tests/test_layers.py b/python/paddle/v2/fluid/tests/test_layers.py index 709abd6c6a4e0c..01b3db42611434 100644 --- a/python/paddle/v2/fluid/tests/test_layers.py +++ b/python/paddle/v2/fluid/tests/test_layers.py @@ -225,6 +225,14 @@ def test_sequence_reshape(self): self.assertIsNotNone(out) print(str(program)) + def test_row_conv(self): + program = Program() + with program_guard(program): + x = layers.data(name='x', shape=[16], dtype='float32', lod_level=1) + out = layers.row_conv(input=x, future_context_size=2) + self.assertIsNotNone(out) + print(str(program)) + if __name__ == '__main__': unittest.main() From 5f1d2cb9cf7823d08eeed556349736619f61bc95 Mon Sep 17 00:00:00 2001 From: yangyaming Date: Mon, 22 Jan 2018 14:44:22 +0800 Subject: [PATCH 4/5] Fix typo. --- python/paddle/v2/fluid/layers/nn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 10a7dd4b0786dc..3f309852dcb1d1 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -1977,7 +1977,7 @@ def row_conv(input, future_context_size, param_attr=None, act=None): """Row Conv Operator. This layer will apply lookahead convolution to **input**. The input variable should be a 2D LoDTensor with shape [T, D]. Parameters with shape [future_context_size + 1, D] will be created. The math - equation of row convolution is as following: + equation of row convolution is as follows: .. math:: Out_{i} = \sum_{j = i} ^ {i + \\tau} X_{j} \odot W_{i - j} From 41028f5746f6287124cef41eefc433f8e6ece86c Mon Sep 17 00:00:00 2001 From: yangyaming Date: Mon, 22 Jan 2018 14:53:29 +0800 Subject: [PATCH 5/5] Refine the doc. --- python/paddle/v2/fluid/layers/nn.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 3f309852dcb1d1..4eb32627ac5f68 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -1985,8 +1985,7 @@ def row_conv(input, future_context_size, param_attr=None, act=None): In the above equation: * :math:`Out_{i}`: The i-th row of output variable with shape [1, D]. - * :math:`\\tau`: Future context size. Please note, the shape of - convolution kernel is [future_context_size + 1, D]. + * :math:`\\tau`: Future context size. * :math:`X_{j}`: The j-th row of input variable with shape [1, D]. * :math:`W_{i-j}`: The (i-j)-th row of parameters with shape [1, D]. @@ -1997,7 +1996,8 @@ def row_conv(input, future_context_size, param_attr=None, act=None): Args: input (Variable): Input variable, a 2D LoDTensor with shape [T, D]. - future_context_size (int): Future context size. + future_context_size (int): Future context size. Please note, the shape + of convolution kernel is [future_context_size + 1, D]. param_attr (ParamAttr): Attributes of parameters, including name, initializer etc. act (str): Non-linear activation to be applied to output variable.