Files
paddlepaddle--paddle/test/legacy_test/test_unpool_indices.py
T
2026-07-13 12:40:42 +08:00

605 lines
19 KiB
Python

# Copyright (c) 2024 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.
import itertools
import unittest
import numpy as np
from op_test import OpTest, get_places
import paddle
import paddle.nn.functional as F
paddle.enable_static()
paddle.seed(2024)
def _unpool_output_size(x, kernel_size, stride, padding, output_size):
input_size = x.shape
default_size = []
for d in range(len(kernel_size)):
default_size.append(
(input_size[-len(kernel_size) + d] - 1) * stride[d]
+ kernel_size[d]
- 2 * padding[d]
)
if output_size is None:
ret = default_size
else:
ret = output_size
return ret
def unpool1dmax_forward_naive(
input, indices, ksize, strides, paddings, output_size
):
s0, s1, s2 = input.shape
output_size = _unpool_output_size(
input, ksize, strides, paddings, output_size
)
out_lsize = output_size[0]
out = np.zeros((s0, s1, out_lsize))
for nidx, cidx, l in itertools.product(
range(s0),
range(s1),
range(s2),
):
index = indices[nidx, cidx, l]
lidx = index % out_lsize
out[nidx, cidx, lidx] = input[nidx, cidx, l]
return out
def unpool2dmax_forward_naive(
input, indices, ksize, strides, paddings, output_size
):
s0, s1, s2, s3 = input.shape
output_size = _unpool_output_size(
input, ksize, strides, paddings, output_size
)
out_hsize = output_size[0]
out_wsize = output_size[1]
out = np.zeros((s0, s1, out_hsize, out_wsize))
for nidx, cidx, h, w in itertools.product(
range(s0),
range(s1),
range(s2),
range(s3),
):
index = indices[nidx, cidx, h, w]
hidx = (index - index % out_wsize) // out_wsize
widx = index % out_wsize
out[nidx, cidx, hidx, widx] = input[nidx, cidx, h, w]
return out
def unpool3dmax_forward_naive(
input, indices, ksize, strides, paddings, output_size
):
s0, s1, s2, s3, s4 = input.shape
output_size = _unpool_output_size(
input, ksize, strides, paddings, output_size
)
out_dsize = output_size[0]
out_hsize = output_size[1]
out_wsize = output_size[2]
out = np.zeros((s0, s1, out_dsize, out_hsize, out_wsize))
for nidx, cidx, d, h, w in itertools.product(
range(s0),
range(s1),
range(s2),
range(s3),
range(s4),
):
index = indices[nidx, cidx, d, h, w]
didx = index // (out_wsize * out_hsize)
hidx = (index - didx * out_hsize * out_wsize) // out_wsize
widx = (index - didx * out_hsize * out_wsize) % out_wsize
out[nidx, cidx, didx, hidx, widx] = input[nidx, cidx, d, h, w]
return out
def max_unpool2d_wrapper(
x,
indices,
kernel_size,
stride=None,
padding=0,
output_size=None,
data_format="NCHW",
name=None,
):
out = paddle.nn.functional.max_unpool2d(
x,
indices,
kernel_size,
stride=stride,
padding=padding,
data_format=data_format,
output_size=output_size,
name=name,
)
return out
def max_unpool3d_wrapper(
x,
indices,
kernel_size,
stride=None,
padding=0,
output_size=None,
data_format="NCDHW",
name=None,
):
out = paddle.nn.functional.max_unpool3d(
x,
indices,
kernel_size,
stride=stride,
padding=padding,
data_format=data_format,
output_size=output_size,
name=name,
)
return out
class TestUnpoolOp(OpTest):
def setUp(self):
self.op_type = "unpool"
self.python_api = max_unpool2d_wrapper
self.indices_dtype = "int64"
self.init_test_case()
input = np.random.randint(0, 100, self.shape)
nsize, csize, hsize, wsize = input.shape
self.output_size = _unpool_output_size(
input, self.ksize, self.strides, self.paddings, self.output_size
)
indices = np.random.permutation(
np.arange(0, self.output_size[0] * self.output_size[1])
)[: hsize * wsize]
indices = np.reshape(indices, [hsize, wsize])
idx_list = []
for n in range(nsize):
c_list = []
for c in range(csize):
c_list.append(indices.tolist())
idx_list.append(c_list)
indices = np.array(idx_list)
output = self.unpool2d_forward_naive(
input,
indices,
self.ksize,
self.strides,
self.paddings,
self.output_size,
).astype("float64")
self.inputs = {
'X': input.astype('float64'),
'Indices': indices.astype(self.indices_dtype),
}
self.attrs = {
'strides': self.strides,
'paddings': self.paddings,
'ksize': self.ksize,
'unpooling_type': self.unpooling_type,
'output_size': self.output_size,
}
self.outputs = {'Out': output.astype('float64')}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad(self):
self.check_grad(['X'], 'Out', check_pir=True)
def init_test_case(self):
self.unpool2d_forward_naive = unpool2dmax_forward_naive
self.unpooling_type = "max"
self.shape = [2, 4, 7, 8]
self.ksize = [2, 2]
self.strides = [2, 2]
self.paddings = [0, 0]
self.output_size = None
class TestUnpoolOpcase1(TestUnpoolOp):
def init_test_case(self):
self.unpool2d_forward_naive = unpool2dmax_forward_naive
self.unpooling_type = "max"
self.shape = [3, 2, 5, 5]
self.ksize = [4, 4]
self.strides = [2, 2]
self.paddings = [0, 0]
self.output_size = None
class TestUnpoolOpOutputsize(TestUnpoolOp):
def init_test_case(self):
self.unpool2d_forward_naive = unpool2dmax_forward_naive
self.unpooling_type = "max"
self.shape = [3, 2, 5, 5]
self.ksize = [4, 4]
self.strides = [2, 2]
self.paddings = [0, 0]
self.output_size = [12, 12]
class TestUnpoolOpOutput(TestUnpoolOp):
def init_test_case(self):
self.unpool2d_forward_naive = unpool2dmax_forward_naive
self.unpooling_type = "max"
self.shape = [3, 2, 5, 5]
self.ksize = [4, 4]
self.strides = [2, 2]
self.paddings = [0, 0]
self.output_size = [12, 12]
class TestUnpool3DOp(OpTest):
def setUp(self):
self.op_type = "unpool3d"
self.python_api = max_unpool3d_wrapper
self.indices_dtype = "int64"
self.init_test_case()
inputs = np.random.randint(0, 100, self.shape)
nsize, csize, dsize, hsize, wsize = inputs.shape
self.output_size = _unpool_output_size(
inputs, self.ksize, self.strides, self.paddings, self.output_size
)
indices = np.random.permutation(
np.arange(
0,
self.output_size[0] * self.output_size[1] * self.output_size[2],
)
)[: dsize * hsize * wsize]
indices = np.reshape(indices, [dsize, hsize, wsize])
idx_list = []
for n in range(nsize):
c_list = []
for c in range(csize):
c_list.append(indices.tolist())
idx_list.append(c_list)
indices = np.array(idx_list)
output = self.unpool3d_forward_naive(
inputs,
indices,
self.ksize,
self.strides,
self.paddings,
self.output_size,
).astype("float64")
self.inputs = {
'X': inputs.astype('float64'),
'Indices': indices.astype(self.indices_dtype),
}
self.attrs = {
'strides': self.strides,
'paddings': self.paddings,
'ksize': self.ksize,
'unpooling_type': self.unpooling_type,
'output_size': self.output_size,
}
self.outputs = {'Out': output.astype('float64')}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad(self):
self.check_grad(['X'], 'Out', check_pir=True)
def init_test_case(self):
self.unpool3d_forward_naive = unpool3dmax_forward_naive
self.unpooling_type = "max"
self.shape = [1, 1, 4, 5, 6]
self.ksize = [2, 2, 2]
self.strides = [2, 2, 2]
self.paddings = [0, 0, 0]
self.output_size = None
class TestUnpool3DOpcase1(TestUnpool3DOp):
def init_test_case(self):
self.unpool3d_forward_naive = unpool3dmax_forward_naive
self.unpooling_type = "max"
self.shape = [1, 3, 4, 5, 6]
self.ksize = [2, 2, 2]
self.strides = [2, 2, 2]
self.paddings = [0, 0, 0]
self.output_size = None
class TestUnpool3DOpcase2(TestUnpool3DOp):
def init_test_case(self):
self.unpool3d_forward_naive = unpool3dmax_forward_naive
self.unpooling_type = "max"
self.shape = [1, 3, 4, 5, 6]
self.ksize = [2, 2, 2]
self.strides = [2, 2, 2]
self.paddings = [0, 0, 0]
self.output_size = None
self.indices_dtype = "int64"
class TestUnpool3DOpOutput(TestUnpool3DOp):
def init_test_case(self):
self.unpool3d_forward_naive = unpool3dmax_forward_naive
self.unpooling_type = "max"
self.shape = [1, 3, 4, 5, 6]
self.ksize = [2, 2, 2]
self.strides = [2, 2, 2]
self.paddings = [0, 0, 0]
self.output_size = [7, 9, 11]
class TestUnpool1DAPI_dy(unittest.TestCase):
def test_case(self):
for place in get_places():
paddle.disable_static(place)
input_data = np.arange(3 * 16).reshape([1, 3, 16]).astype("float32")
input_x = paddle.to_tensor(input_data)
output, indices = F.max_pool1d(
input_x, kernel_size=2, stride=2, return_mask=True
)
output_unpool = F.max_unpool1d(
output,
indices.astype("int64"),
kernel_size=2,
stride=2,
output_size=input_x.shape,
)
expected_output_unpool = unpool1dmax_forward_naive(
output.numpy(), indices.numpy(), [2], [2], [0], [16]
)
np.testing.assert_allclose(
output_unpool.numpy(), expected_output_unpool, rtol=1e-05
)
paddle.enable_static()
class TestUnpool1DAPI_st(unittest.TestCase):
def test_case(self):
paddle.enable_static()
for place in get_places():
with paddle.static.program_guard(
paddle.static.Program(), paddle.static.Program()
):
input_data = np.array(
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]]
).astype("float32")
x = paddle.static.data(
name='x', shape=[1, 3, 4], dtype='float32'
)
output, indices = F.max_pool1d(
x, kernel_size=2, stride=2, return_mask=True
)
output_unpool = F.max_unpool1d(
output, indices.astype("int64"), kernel_size=2, stride=None
)
exe = paddle.static.Executor(place)
fetches = exe.run(
feed={"x": input_data},
fetch_list=[output_unpool],
return_numpy=True,
)
pool1d_out_np = np.array(
[[[2.0, 4.0], [6.0, 8.0], [10.0, 12.0]]]
).astype("float32")
indices_np = np.array([[[1, 3], [1, 3], [1, 3]]]).astype(
"int64"
)
expected_output_unpool = unpool1dmax_forward_naive(
pool1d_out_np, indices_np, [2], [2], [0], [4]
)
np.testing.assert_allclose(
fetches[0], expected_output_unpool, rtol=1e-05
)
class TestUnpool2DAPI_dy(unittest.TestCase):
def test_case(self):
for place in get_places():
paddle.disable_static(place)
input_data = np.array(
[
[
[
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
]
]
]
).astype("float32")
input_x = paddle.to_tensor(input_data)
output, indices = F.max_pool2d(
input_x, kernel_size=2, stride=2, return_mask=True
)
out_pp = F.max_unpool2d(
output,
indices.astype("int64"),
kernel_size=2,
stride=None,
output_size=input_x.shape,
)
output_np = output.numpy()
indices_np = indices.numpy()
expect_res = unpool2dmax_forward_naive(
output_np, indices_np, [2, 2], [2, 2], [0, 0], [4, 5]
).astype("float64")
np.testing.assert_allclose(out_pp.numpy(), expect_res, rtol=1e-05)
paddle.enable_static()
class TestUnpool2DAPI_st(unittest.TestCase):
def test_case(self):
paddle.enable_static()
for place in get_places():
with paddle.static.program_guard(
paddle.static.Program(), paddle.static.Program()
):
input_data = np.array(
[
[
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]
]
]
).astype("float32")
x = paddle.static.data(
name="x", shape=[1, 1, 4, 4], dtype="float32"
)
output, indices = F.max_pool2d(
x, kernel_size=2, stride=2, return_mask=True
)
unpool_out = F.max_unpool2d(
output,
indices.astype("int64"),
kernel_size=2,
stride=None,
output_size=(5, 5),
)
exe = paddle.static.Executor(place)
results = exe.run(
feed={"x": input_data},
fetch_list=[unpool_out],
return_numpy=True,
)
pool_out_np = np.array([[[[6.0, 8.0], [14.0, 16.0]]]]).astype(
"float32"
)
indices_np = np.array([[[[5, 7], [13, 15]]]]).astype("int64")
expect_res = unpool2dmax_forward_naive(
pool_out_np, indices_np, [2, 2], [2, 2], [0, 0], [5, 5]
).astype("float64")
np.testing.assert_allclose(results[0], expect_res, rtol=1e-05)
class TestUnpool3DAPI_dy(unittest.TestCase):
def test_case(self):
for place in get_places():
paddle.disable_static(place)
input_data = (
np.arange(3 * 4 * 4 * 6)
.reshape([1, 3, 4, 4, 6])
.astype("float32")
)
input_x = paddle.to_tensor(input_data)
output, indices = F.max_pool3d(
input_x, kernel_size=2, stride=2, return_mask=True
)
output_unpool = F.max_unpool3d(
output,
indices.astype("int64"),
kernel_size=2,
stride=2,
output_size=input_x.shape,
)
expected_output_unpool = unpool3dmax_forward_naive(
output.numpy(),
indices.numpy(),
[2, 2, 2],
[2, 2, 2],
[0, 0, 0],
[4, 4, 6],
)
np.testing.assert_allclose(
output_unpool.numpy(), expected_output_unpool, rtol=1e-05
)
paddle.enable_static()
class TestUnpool3DAPI_st2(unittest.TestCase):
def test_case(self):
paddle.enable_static()
for place in get_places():
with paddle.static.program_guard(
paddle.static.Program(), paddle.static.Program()
):
input_data = np.array(
[
[
[
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
],
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
],
]
]
]
).astype("float32")
x = paddle.static.data(
name='x', shape=[1, 1, 2, 4, 4], dtype='float32'
)
output, indices = F.max_pool3d(
x, kernel_size=2, stride=2, return_mask=True
)
output_unpool = F.max_unpool3d(
output, indices.astype("int64"), kernel_size=2, stride=None
)
exe = paddle.static.Executor(place)
fetches = exe.run(
feed={"x": input_data},
fetch_list=[output_unpool],
return_numpy=True,
)
pool3d_out_np = np.array(
[[[[[6.0, 8.0], [14.0, 16.0]]]]]
).astype("float32")
indices_np = np.array([[[[[5, 7], [13, 15]]]]]).astype("int64")
expected_output_unpool = unpool3dmax_forward_naive(
pool3d_out_np,
indices_np,
[2, 2, 2],
[2, 2, 2],
[0, 0, 0],
[2, 4, 4],
)
np.testing.assert_allclose(
fetches[0], expected_output_unpool, rtol=1e-05
)
if __name__ == '__main__':
unittest.main()