-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Sparse MaxPool3D #42130
Add Sparse MaxPool3D #42130
Changes from 33 commits
d04f2e5
bfe56c7
311700f
8e7ae8b
4622c74
760262a
b6bfb2a
8689f7a
661a64f
30f85d8
09b9448
8e3442a
1385e1c
ed97c98
591e3c1
349d948
8ecfa70
6153a5a
4667790
378eb60
6f14902
f3137c7
5467b9c
3a45725
e20c1d9
b609c2b
5b9b786
422e801
56774d9
c36f736
9fc2800
a5cc93f
f6a3907
2596037
89b6f34
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from __future__ import print_function | ||
import unittest | ||
import numpy as np | ||
import paddle | ||
import paddle.fluid.core as core | ||
from paddle import _C_ops | ||
from paddle.fluid.framework import _test_eager_guard | ||
|
||
|
||
class TestMaxPool3DFunc(unittest.TestCase): | ||
def setInput(self): | ||
paddle.seed(0) | ||
self.dense_x = paddle.randn((1, 4, 4, 4, 4)) | ||
|
||
def setKernelSize(self): | ||
self.kernel_sizes = [3, 3, 3] | ||
|
||
def setStride(self): | ||
self.strides = [1, 1, 1] | ||
|
||
def setPadding(self): | ||
self.paddings = [0, 0, 0] | ||
|
||
def setUp(self): | ||
self.setInput() | ||
self.setKernelSize() | ||
self.setStride() | ||
self.setPadding() | ||
|
||
def test(self): | ||
with _test_eager_guard(): | ||
self.setUp() | ||
sparse_x = self.dense_x.to_sparse_coo(4) | ||
out = paddle.sparse.functional.max_pool3d( | ||
sparse_x, | ||
self.kernel_sizes, | ||
stride=self.strides, | ||
padding=self.paddings) | ||
out = out.to_dense() | ||
|
||
dense_out = paddle.nn.functional.max_pool3d( | ||
self.dense_x, | ||
self.kernel_sizes, | ||
stride=self.strides, | ||
padding=self.paddings, | ||
data_format='NDHWC') | ||
#compare with dense | ||
assert np.allclose(dense_out.flatten().numpy(), | ||
out.flatten().numpy()) | ||
|
||
|
||
class TestStride(TestMaxPool3DFunc): | ||
def setStride(self): | ||
self.strides = 1 | ||
|
||
|
||
class TestPadding(TestMaxPool3DFunc): | ||
def setPadding(self): | ||
self.paddings = 1 | ||
|
||
def setInput(self): | ||
self.dense_x = paddle.randn((1, 5, 6, 8, 3)) | ||
|
||
|
||
class TestKernelSize(TestMaxPool3DFunc): | ||
def setKernelSize(self): | ||
self.kernel_sizes = [5, 5, 5] | ||
|
||
def setInput(self): | ||
paddle.seed(0) | ||
self.dense_x = paddle.randn((1, 6, 9, 6, 3)) | ||
|
||
|
||
class TestInput(TestMaxPool3DFunc): | ||
def setInput(self): | ||
paddle.seed(0) | ||
self.dense_x = paddle.randn((2, 6, 7, 9, 3)) | ||
dropout = paddle.nn.Dropout(0.8) | ||
self.dense_x = dropout(self.dense_x) | ||
|
||
|
||
class TestMaxPool3DAPI(unittest.TestCase): | ||
def test(self): | ||
with _test_eager_guard(): | ||
dense_x = paddle.randn((2, 3, 6, 6, 3)) | ||
sparse_x = dense_x.to_sparse_coo(4) | ||
max_pool3d = paddle.sparse.MaxPool3D( | ||
kernel_size=3, data_format='NDHWC') | ||
out = max_pool3d(sparse_x) | ||
out = out.to_dense() | ||
|
||
dense_out = paddle.nn.functional.max_pool3d( | ||
dense_x, 3, data_format='NDHWC') | ||
assert np.allclose(dense_out.numpy(), out.numpy()) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from __future__ import print_function | ||
import unittest | ||
import numpy as np | ||
import paddle | ||
import paddle.fluid.core as core | ||
from paddle import _C_ops | ||
from paddle.fluid.framework import _test_eager_guard | ||
|
||
|
||
class TestMaxPool3DFunc(unittest.TestCase): | ||
def setInput(self): | ||
paddle.seed(0) | ||
self.dense_x = paddle.randn((1, 4, 4, 4, 4)) | ||
|
||
def setKernelSize(self): | ||
self.kernel_sizes = [3, 3, 3] | ||
|
||
def setStride(self): | ||
self.strides = [1, 1, 1] | ||
|
||
def setPadding(self): | ||
self.paddings = [0, 0, 0] | ||
|
||
def setUp(self): | ||
self.setInput() | ||
self.setKernelSize() | ||
self.setStride() | ||
self.setPadding() | ||
|
||
def test(self): | ||
with _test_eager_guard(): | ||
self.setUp() | ||
sparse_x = self.dense_x.to_sparse_coo(4) | ||
out = paddle.sparse.functional.max_pool3d( | ||
sparse_x, | ||
self.kernel_sizes, | ||
stride=self.strides, | ||
padding=self.paddings) | ||
out = out.to_dense() | ||
|
||
dense_out = paddle.nn.functional.max_pool3d( | ||
self.dense_x, | ||
self.kernel_sizes, | ||
stride=self.strides, | ||
padding=self.paddings, | ||
data_format='NDHWC') | ||
#compare with dense | ||
assert np.allclose(dense_out.flatten().numpy(), | ||
out.flatten().numpy()) | ||
|
||
|
||
class TestStride(TestMaxPool3DFunc): | ||
def setStride(self): | ||
self.strides = 1 | ||
|
||
|
||
class TestPadding(TestMaxPool3DFunc): | ||
def setPadding(self): | ||
self.paddings = 1 | ||
|
||
def setInput(self): | ||
self.dense_x = paddle.randn((1, 5, 6, 8, 3)) | ||
|
||
|
||
class TestKernelSize(TestMaxPool3DFunc): | ||
def setKernelSize(self): | ||
self.kernel_sizes = [5, 5, 5] | ||
|
||
def setInput(self): | ||
paddle.seed(0) | ||
self.dense_x = paddle.randn((1, 6, 9, 6, 3)) | ||
|
||
|
||
class TestInput(TestMaxPool3DFunc): | ||
def setInput(self): | ||
paddle.seed(0) | ||
self.dense_x = paddle.randn((2, 6, 7, 9, 3)) | ||
dropout = paddle.nn.Dropout(0.8) | ||
self.dense_x = dropout(self.dense_x) | ||
|
||
|
||
class TestMaxPool3DAPI(unittest.TestCase): | ||
def test(self): | ||
with _test_eager_guard(): | ||
dense_x = paddle.randn((2, 3, 6, 6, 3)) | ||
sparse_x = dense_x.to_sparse_coo(4) | ||
max_pool3d = paddle.sparse.MaxPool3D( | ||
kernel_size=3, data_format='NDHWC') | ||
out = max_pool3d(sparse_x) | ||
out = out.to_dense() | ||
|
||
dense_out = paddle.nn.functional.max_pool3d( | ||
dense_x, 3, data_format='NDHWC') | ||
assert np.allclose(dense_out.numpy(), out.numpy()) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from ...fluid.layers import utils | ||
from paddle import _C_ops, in_dynamic_mode | ||
from paddle.nn.functional.pooling import _update_padding_nd | ||
|
||
__all__ = [] | ||
|
||
|
||
def max_pool3d(x, | ||
kernel_size, | ||
stride=None, | ||
padding=0, | ||
ceil_mode=False, | ||
data_format="NDHWC", | ||
name=None): | ||
""" | ||
This API implements sparse max pooling 3d operation. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
See more details in :ref:`api_sparse_pooling_MaxPool3d` . | ||
Args: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a blank line before Args There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
x (Tensor): The input SparseCooTensor of pooling operator, which is a 5-D tensor with | ||
shape [N, D, H, W, C]. The format of input tensor `"NDHWC"`, where N represents batch size, C represents the number of channels, D, H and W represent the depth, height and width of the feature respectively. | ||
kernel_size (int|list|tuple): The pool kernel size. If the kernel size | ||
is a tuple or list, it must contain three integers, | ||
(kernel_size_Depth, kernel_size_Height, kernel_size_Width). | ||
Otherwise, the pool kernel size will be the cube of an int. | ||
stride (int|list|tuple): The pool stride size. If pool stride size is a tuple or list, | ||
it must contain three integers, [stride_Depth, stride_Height, stride_Width). | ||
Otherwise, the pool stride size will be a cube of an int. | ||
padding (string|int|list|tuple): The padding size. Padding could be in one of the following forms. | ||
1. A string in ['valid', 'same']. | ||
2. An int, which means the feature map is zero padded by size of `padding` on every sides. | ||
3. A list[int] or tuple(int) whose length is 3, [pad_depth, pad_height, pad_weight] whose value means the padding size of each dimension. | ||
4. A list[int] or tuple(int) whose length is 6. [pad_depth_front, pad_depth_back, pad_height_top, pad_height_bottom, pad_width_left, pad_width_right] whose value means the padding size of each side. | ||
5. A list or tuple of pairs of integers. It has the form [[pad_before, pad_after], [pad_before, pad_after], ...]. Note that, the batch dimension and channel dimension should be [0,0] or (0,0). | ||
The default value is 0. | ||
ceil_mode (bool): ${ceil_mode_comment} | ||
data_format (string): The data format of the input and output data. An optional string from: `"NCDHW"`, `"NDHWC"`. | ||
The default is `"NCDHW"`. When it is `"NCDHW"`, the data is stored in the order of: | ||
`[batch_size, input_channels, input_depth, input_height, input_width]`. Currently only support `"NDHWC"` . | ||
name(str, optional): For detailed information, please refer | ||
to :ref:`api_guide_Name`. Usually name is no need to set and | ||
None by default. | ||
|
||
Returns: | ||
Tensor: The output tensor of pooling result. The data type is same as input tensor. | ||
|
||
Raises: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete Raises There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
ValueError: If `padding` is a string, but not "SAME" or "VALID". | ||
ValueError: If `padding` is "VALID", but `ceil_mode` is True. | ||
ShapeError: If the output's shape calculated is not greater than 0. | ||
|
||
Examples: | ||
.. code-block:: python | ||
|
||
import paddle | ||
from paddle.fluid.framework import _test_eager_guard | ||
|
||
with _test_eager_guard(): | ||
dense_x = paddle.randn((1, 4, 4, 4, 3)) | ||
sparse_x = dense_x.to_sparse_coo(4) | ||
kernel_sizes = [3, 3, 3] | ||
paddings = [0, 0, 0] | ||
strides = [1, 1, 1] | ||
out = paddle.sparse.functional.max_pool3d(sparse_x, kernel_sizes, stride=strides, padding=paddings) | ||
#[1, 2, 2, 2, 3] | ||
""" | ||
|
||
assert in_dynamic_mode(), "Currently, Sparse API only support dynamic mode" | ||
assert x.is_sparse_coo( | ||
), "Currently, sparse.relu only support the input of SparseCooTensor" | ||
assert data_format == 'NDHWC', "Currently, sparse.max_pool3d only support data format of 'NDHWC'" | ||
|
||
kernel_size = utils.convert_to_list(kernel_size, 3, 'pool_size') | ||
if stride is None: | ||
stride = kernel_size | ||
else: | ||
stride = utils.convert_to_list(stride, 3, 'pool_stride') | ||
|
||
channel_last = True | ||
|
||
padding, padding_algorithm = _update_padding_nd( | ||
padding, 3, channel_last=channel_last, ceil_mode=ceil_mode) | ||
|
||
#TODO(zkh2016): remove the dependency on dilation from the backend | ||
dilation = [1, 1, 1] | ||
|
||
return _C_ops.final_state_sparse_maxpool(x, kernel_size, padding, dilation, | ||
stride) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
后续增加一些测试
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok