From 94c99998ae3556e0a54dc5637643c568e0fd9263 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 03:17:24 -0400 Subject: [PATCH 01/11] add AvgPooling layer --- mindspore/nn/layer/__init__.py | 4 +- mindspore/nn/layer/pooling.py | 84 ++++++++++++++++++++++++++++++ tests/ut/python/nn/test_pooling.py | 16 ++++++ 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/mindspore/nn/layer/__init__.py b/mindspore/nn/layer/__init__.py index 098489a91d..b9f79b6cf7 100644 --- a/mindspore/nn/layer/__init__.py +++ b/mindspore/nn/layer/__init__.py @@ -24,7 +24,7 @@ from .conv import Conv2d, Conv2dTranspose from .lstm import LSTM from .basic import Dropout, Flatten, Dense, ClipByNorm, Norm, OneHot, Pad, Unfold from .embedding import Embedding -from .pooling import AvgPool2d, MaxPool2d +from .pooling import AvgPool2d, MaxPool2d, AvgPool1d from .image import ImageGradients, SSIM, PSNR __all__ = ['Softmax', 'LogSoftmax', 'ReLU', 'ReLU6', 'Tanh', 'GELU', 'Sigmoid', @@ -35,6 +35,6 @@ __all__ = ['Softmax', 'LogSoftmax', 'ReLU', 'ReLU6', 'Tanh', 'GELU', 'Sigmoid', 'LSTM', 'Dropout', 'Flatten', 'Dense', 'ClipByNorm', 'Norm', 'OneHot', 'Embedding', - 'AvgPool2d', 'MaxPool2d', 'Pad', 'Unfold', + 'AvgPool2d', 'MaxPool2d', 'AvgPool1d', 'Pad', 'Unfold', 'ImageGradients', 'SSIM', 'PSNR', ] diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 53d97807cf..17700ff7b4 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -208,3 +208,87 @@ class AvgPool2d(_PoolNd): def construct(self, x): return self.avg_pool(x) + + +class AvgPool1d(_PoolNd): + r""" + Average pooling for temporal data. + + Applies a 2D average pooling over an input Tensor which can be regarded as a composition of 2D input planes. + + Typically the input is of shape :math:`(N_{in}, C_{in}, H_{in}, W_{in})`, AvgPool2d outputs + regional average in the :math:`(H_{in}, W_{in})`-dimension. Given kernel size + :math:`ks = (h_{ker}, w_{ker})` and stride :math:`s = (s_0, s_1)`, the operation is as follows. + + .. math:: + \text{output}(N_i, C_j, h, w) = \frac{1}{h_{ker} * w_{ker}} \sum_{m=0}^{h_{ker}-1} \sum_{n=0}^{w_{ker}-1} + \text{input}(N_i, C_j, s_0 \times h + m, s_1 \times w + n) + + Note: + pad_mode for training only supports "same" and "valid". + + Args: + kernel_size (Union[int, tuple[int]]): The size of kernel used to take the average value, + is an int number that represents height and width are both kernel_size, + or a tuple of two int numbers that represent height and width respectively. + Default: 1. + stride (Union[int, tuple[int]]): The distance of kernel moving, an int number that represents + the height and width of movement are both strides, or a tuple of two int numbers that + represent height and width of movement respectively. Default: 1. + pad_mode (str): The optional values for pad mode, is "same" or "valid", not case sensitive. + Default: "valid". + + - same: Adopts the way of completion. Output height and width will be the same as + the input. Total number of padding will be calculated for horizontal and vertical + direction and evenly distributed to top and bottom, left and right if possible. + Otherwise, the last extra padding will be done from the bottom and the right side. + + - valid: Adopts the way of discarding. The possibly largest height and width of output + will be return without padding. Extra pixels will be discarded. + + + Inputs: + - **input** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. + + Outputs: + Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. + + Examples: + >>> pool = nn.AvgPool2d(kernel_size=3, strides=1) + >>> x = Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), mindspore.float32) + [[[[5. 5. 9. 9.] + [8. 4. 3. 0.] + [2. 7. 1. 2.] + [1. 8. 3. 3.]] + [[6. 8. 2. 4.] + [3. 0. 2. 1.] + [0. 8. 9. 7.] + [2. 1. 4. 9.]]]] + >>> output = pool(x) + >>> output.shape() + (1, 2, 2, 2) + >>> output + [[[[4.888889 4.4444447] + [4.111111 3.4444444]] + [[4.2222223 4.5555553] + [3.2222223 4.5555553]]]] + """ + + def __init__(self, + kernel_size=1, + stride=1, + pad_mode="valid"): + super(AvgPool1d, self).__init__(kernel_size, stride, pad_mode) + if not isinstance(kernel_size, int): + raise ValueError("kernel_size should be 1 int number but got {}". + format(kernel_size)) + if not isinstance(stride, int): + raise ValueError("stride should be 1 int number but got {}".format(stride)) + self.kernel_size = (1, kernel_size) + self.stride = (1, stride) + self.avg_pool = P.AvgPool(ksize=self.kernel_size, + strides=self.stride, + padding=self.pad_mode) + + def construct(self, x): + return self.avg_pool(x) diff --git a/tests/ut/python/nn/test_pooling.py b/tests/ut/python/nn/test_pooling.py index 10bb7632b2..428e050ea2 100644 --- a/tests/ut/python/nn/test_pooling.py +++ b/tests/ut/python/nn/test_pooling.py @@ -56,3 +56,19 @@ def test_compile_max(): net = MaxNet(3, stride=1, padding=0) x = Tensor(np.random.randint(0, 255, [1, 3, 6, 6]).astype(np.float32)) _executor.compile(net, x) + + +class Avg1dNet(nn.Cell): + def __init__(self, + kernel_size, + stride=None): + super(Avg1dNet, self).__init__() + self.avg1d = nn.AvgPool1d(kernel_size, stride) + + def construct(self, x): + return self.avg1d(x) + +def test_avg1d(): + net = Avg1dNet(3, 1) + input = Tensor(np.random.randint(0, 255, [1, 3, 6, 6]).astype(np.float32)) + _executor.compile(net, input) \ No newline at end of file From e170a0355ce78f671183a11c4ce2b538d5e42864 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 03:50:31 -0400 Subject: [PATCH 02/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 37 ++++++++++------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 17700ff7b4..299891232e 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -214,27 +214,23 @@ class AvgPool1d(_PoolNd): r""" Average pooling for temporal data. - Applies a 2D average pooling over an input Tensor which can be regarded as a composition of 2D input planes. + Applies a 1D average pooling over an input Tensor which can be regarded as a composition of 1D input planes. - Typically the input is of shape :math:`(N_{in}, C_{in}, H_{in}, W_{in})`, AvgPool2d outputs - regional average in the :math:`(H_{in}, W_{in})`-dimension. Given kernel size - :math:`ks = (h_{ker}, w_{ker})` and stride :math:`s = (s_0, s_1)`, the operation is as follows. + Typically the input is of shape :math:`(N_{in}, C_{in}, H_{in}, W_{in})`, AvgPool1d outputs + regional average in the :math:`(W_{in})`-dimension. Given kernel size + :math:`ks = (w_{ker})` and stride :math:`s = (s_0)`, the operation is as follows. .. math:: - \text{output}(N_i, C_j, h, w) = \frac{1}{h_{ker} * w_{ker}} \sum_{m=0}^{h_{ker}-1} \sum_{n=0}^{w_{ker}-1} - \text{input}(N_i, C_j, s_0 \times h + m, s_1 \times w + n) + \text{output}(N_i, C_j, h_k, w) = \frac{1}{w_{ker}} \sum_{n=0}^{w_{ker}-1} + \text{input}(N_i, C_j, h_k, s_0 \times w + n) Note: pad_mode for training only supports "same" and "valid". Args: - kernel_size (Union[int, tuple[int]]): The size of kernel used to take the average value, - is an int number that represents height and width are both kernel_size, - or a tuple of two int numbers that represent height and width respectively. - Default: 1. - stride (Union[int, tuple[int]]): The distance of kernel moving, an int number that represents - the height and width of movement are both strides, or a tuple of two int numbers that - represent height and width of movement respectively. Default: 1. + kernel_size (int): The size of kernel window used to take the average value, Default: 1. + stride (int): The distance of kernel moving, an int number that represents + the width of movement is strides, Default: 1. pad_mode (str): The optional values for pad mode, is "same" or "valid", not case sensitive. Default: "valid". @@ -254,24 +250,11 @@ class AvgPool1d(_PoolNd): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> pool = nn.AvgPool2d(kernel_size=3, strides=1) + >>> pool = nn.AvgPool1d(kernel_size=3, strides=1) >>> x = Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), mindspore.float32) - [[[[5. 5. 9. 9.] - [8. 4. 3. 0.] - [2. 7. 1. 2.] - [1. 8. 3. 3.]] - [[6. 8. 2. 4.] - [3. 0. 2. 1.] - [0. 8. 9. 7.] - [2. 1. 4. 9.]]]] >>> output = pool(x) >>> output.shape() - (1, 2, 2, 2) >>> output - [[[[4.888889 4.4444447] - [4.111111 3.4444444]] - [[4.2222223 4.5555553] - [3.2222223 4.5555553]]]] """ def __init__(self, From 92695a0da8a908a9ee86fb44827ef6b359484783 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 04:44:33 -0400 Subject: [PATCH 03/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 299891232e..fef9494ea4 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -218,7 +218,7 @@ class AvgPool1d(_PoolNd): Typically the input is of shape :math:`(N_{in}, C_{in}, H_{in}, W_{in})`, AvgPool1d outputs regional average in the :math:`(W_{in})`-dimension. Given kernel size - :math:`ks = (w_{ker})` and stride :math:`s = (s_0)`, the operation is as follows. + :math:`ks = w_{ker}` and stride :math:`s = s_0`, the operation is as follows. .. math:: \text{output}(N_i, C_j, h_k, w) = \frac{1}{w_{ker}} \sum_{n=0}^{w_{ker}-1} From 422bc304df5b690e217b473b7d968f233290fc60 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 09:32:37 -0400 Subject: [PATCH 04/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index fef9494ea4..1628f8d1c3 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -14,6 +14,7 @@ # ============================================================================ """pooling""" from mindspore.ops import operations as P +from mindspore.ops import functional as F from mindspore._checkparam import Validator as validator from ... import context from ..cell import Cell @@ -272,6 +273,17 @@ class AvgPool1d(_PoolNd): self.avg_pool = P.AvgPool(ksize=self.kernel_size, strides=self.stride, padding=self.pad_mode) + self.shape = F.shape + self.reduce_mean = P.ReduceMean(keep_dims=True) + self.slice = P.Slice() def construct(self, x): - return self.avg_pool(x) + batch, channel, high, width = self.shape(x) + if width == self.kernel_size[1]: + x = self.reduce_mean(x, 3) + elif width - self.kernel_size[1] < self.stride[1]: + x = self.slice(x, (0, 0, 0, 0), (batch, channel, high, self.kernel_size[1])) + x = self.reduce_mean(x, 3) + else: + x = self.avg_pool(x) + return x From e1b6addefd6afd4c71fade2f13d8d8bbdf560af6 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 09:48:35 -0400 Subject: [PATCH 05/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 1628f8d1c3..359e75a4c0 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -18,6 +18,7 @@ from mindspore.ops import functional as F from mindspore._checkparam import Validator as validator from ... import context from ..cell import Cell +from ..._checkparam import Rel class _PoolNd(Cell): @@ -263,10 +264,15 @@ class AvgPool1d(_PoolNd): stride=1, pad_mode="valid"): super(AvgPool1d, self).__init__(kernel_size, stride, pad_mode) + validator.check_type('kernel_size', kernel_size, [int,]) + validator.check_type('stride', stride, [int,]) + self.padding = validator.check_string('pad_mode', pad_mode.upper(), ['VALID', 'SAME']) if not isinstance(kernel_size, int): + validator.check_integer("kernel_size", kernel_size, 1, Rel.GE) raise ValueError("kernel_size should be 1 int number but got {}". format(kernel_size)) if not isinstance(stride, int): + validator.check_integer("stride", stride, 1, Rel.GE) raise ValueError("stride should be 1 int number but got {}".format(stride)) self.kernel_size = (1, kernel_size) self.stride = (1, stride) From 5d289ef029a40cdbb103e5ac6cffeec0d8d99bec Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 10:10:49 -0400 Subject: [PATCH 06/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 359e75a4c0..a19ef06b7e 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -19,6 +19,7 @@ from mindspore._checkparam import Validator as validator from ... import context from ..cell import Cell from ..._checkparam import Rel +from ..._checkparam import ParamValidator class _PoolNd(Cell): @@ -264,15 +265,15 @@ class AvgPool1d(_PoolNd): stride=1, pad_mode="valid"): super(AvgPool1d, self).__init__(kernel_size, stride, pad_mode) - validator.check_type('kernel_size', kernel_size, [int,]) - validator.check_type('stride', stride, [int,]) - self.padding = validator.check_string('pad_mode', pad_mode.upper(), ['VALID', 'SAME']) + ParamValidator.check_type('kernel_size', kernel_size, [int,]) + ParamValidator.check_type('stride', stride, [int,]) + self.pad_mode = ParamValidator.check_string('pad_mode', pad_mode.upper(), ['VALID', 'SAME']) if not isinstance(kernel_size, int): - validator.check_integer("kernel_size", kernel_size, 1, Rel.GE) + ParamValidator.check_integer("kernel_size", kernel_size, 1, Rel.GE) raise ValueError("kernel_size should be 1 int number but got {}". format(kernel_size)) if not isinstance(stride, int): - validator.check_integer("stride", stride, 1, Rel.GE) + ParamValidator.check_integer("stride", stride, 1, Rel.GE) raise ValueError("stride should be 1 int number but got {}".format(stride)) self.kernel_size = (1, kernel_size) self.stride = (1, stride) From 227da6e7205e0470ebf377d1b7403e8c94ea1f7a Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 10:27:26 -0400 Subject: [PATCH 07/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index a19ef06b7e..28826c88bb 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -268,13 +268,8 @@ class AvgPool1d(_PoolNd): ParamValidator.check_type('kernel_size', kernel_size, [int,]) ParamValidator.check_type('stride', stride, [int,]) self.pad_mode = ParamValidator.check_string('pad_mode', pad_mode.upper(), ['VALID', 'SAME']) - if not isinstance(kernel_size, int): - ParamValidator.check_integer("kernel_size", kernel_size, 1, Rel.GE) - raise ValueError("kernel_size should be 1 int number but got {}". - format(kernel_size)) - if not isinstance(stride, int): - ParamValidator.check_integer("stride", stride, 1, Rel.GE) - raise ValueError("stride should be 1 int number but got {}".format(stride)) + ParamValidator.check_integer("kernel_size", kernel_size, 1, Rel.GE) + ParamValidator.check_integer("stride", stride, 1, Rel.GE) self.kernel_size = (1, kernel_size) self.stride = (1, stride) self.avg_pool = P.AvgPool(ksize=self.kernel_size, From f24065806d16574392c290dc62a05b8234883719 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 22:52:36 -0400 Subject: [PATCH 08/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 28826c88bb..c7841b804b 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -255,9 +255,26 @@ class AvgPool1d(_PoolNd): Examples: >>> pool = nn.AvgPool1d(kernel_size=3, strides=1) >>> x = Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), mindspore.float32) + [[[[8. 8. 7. 4.] + [8. 4. 0. 9.] + [6. 4. 6. 1.] + [6. 8. 8. 5.] + [[4. 8. 5. 4.] + [8. 4. 7. 5.] + [3. 5. 3. 9.] + [7. 5. 4. 7.]]]] >>> output = pool(x) >>> output.shape() + (1, 2, 4, 2) >>> output + [[[[7.6640625 6.3320312] + [4. 4.3320312] + [5.3320312 3.6660156] + [7.3320312 7 ] + [[5.6640625 5.6640625] + [6.3320312 5.3320312] + [3.6660156 5.6640625] + [5.3320312 5.3320312]]]] """ def __init__(self, From beca38a3993baf0c137500d7f261c610f22f8b0a Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 22:57:18 -0400 Subject: [PATCH 09/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index c7841b804b..9880763041 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -258,7 +258,7 @@ class AvgPool1d(_PoolNd): [[[[8. 8. 7. 4.] [8. 4. 0. 9.] [6. 4. 6. 1.] - [6. 8. 8. 5.] + [6. 8. 8. 5.]] [[4. 8. 5. 4.] [8. 4. 7. 5.] [3. 5. 3. 9.] @@ -270,7 +270,7 @@ class AvgPool1d(_PoolNd): [[[[7.6640625 6.3320312] [4. 4.3320312] [5.3320312 3.6660156] - [7.3320312 7 ] + [7.3320312 7 ]] [[5.6640625 5.6640625] [6.3320312 5.3320312] [3.6660156 5.6640625] From 06ca226da4976ba413b1bb09ceb02003bc828d47 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 23:50:45 -0400 Subject: [PATCH 10/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 9880763041..84ec2414a3 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -255,14 +255,6 @@ class AvgPool1d(_PoolNd): Examples: >>> pool = nn.AvgPool1d(kernel_size=3, strides=1) >>> x = Tensor(np.random.randint(0, 10, [1, 2, 4, 4]), mindspore.float32) - [[[[8. 8. 7. 4.] - [8. 4. 0. 9.] - [6. 4. 6. 1.] - [6. 8. 8. 5.]] - [[4. 8. 5. 4.] - [8. 4. 7. 5.] - [3. 5. 3. 9.] - [7. 5. 4. 7.]]]] >>> output = pool(x) >>> output.shape() (1, 2, 4, 2) From faf95e40ebf6a6c8aca1481844016e7f0934a370 Mon Sep 17 00:00:00 2001 From: zhaojichen Date: Tue, 21 Apr 2020 23:52:06 -0400 Subject: [PATCH 11/11] add AvgPooling layer --- mindspore/nn/layer/pooling.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/mindspore/nn/layer/pooling.py b/mindspore/nn/layer/pooling.py index 84ec2414a3..6cf06de029 100644 --- a/mindspore/nn/layer/pooling.py +++ b/mindspore/nn/layer/pooling.py @@ -258,15 +258,6 @@ class AvgPool1d(_PoolNd): >>> output = pool(x) >>> output.shape() (1, 2, 4, 2) - >>> output - [[[[7.6640625 6.3320312] - [4. 4.3320312] - [5.3320312 3.6660156] - [7.3320312 7 ]] - [[5.6640625 5.6640625] - [6.3320312 5.3320312] - [3.6660156 5.6640625] - [5.3320312 5.3320312]]]] """ def __init__(self,