test_pool2d_api.py 20.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Copyright (c) 2020 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 unittest
16

17
import numpy as np
18 19 20 21 22
from test_pool2d_op import (
    avg_pool2D_forward_naive,
    max_pool2D_forward_naive,
    pool2D_forward_naive,
)
23

24 25 26 27 28
import paddle
import paddle.fluid as fluid
import paddle.fluid.core as core
from paddle.nn.functional import avg_pool2d, max_pool2d

29

C
cnn 已提交
30
class TestPool2D_API(unittest.TestCase):
31 32 33 34 35 36 37 38
    def setUp(self):
        np.random.seed(123)
        self.places = [fluid.CPUPlace()]
        if core.is_compiled_with_cuda():
            self.places.append(fluid.CUDAPlace(0))

    def check_avg_static_results(self, place):
        with fluid.program_guard(fluid.Program(), fluid.Program()):
39 40 41
            input = fluid.data(
                name="input", shape=[2, 3, 32, 32], dtype="float32"
            )
42 43 44
            result = avg_pool2d(input, kernel_size=2, stride=2, padding=0)

            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
45 46 47 48 49 50 51
            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='avg',
            )
52 53

            exe = fluid.Executor(place)
54 55 56 57 58
            fetches = exe.run(
                fluid.default_main_program(),
                feed={"input": input_np},
                fetch_list=[result],
            )
59
            np.testing.assert_allclose(fetches[0], result_np, rtol=1e-05)
60 61 62 63 64 65 66

    def check_avg_dygraph_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
            result = avg_pool2d(input, kernel_size=2, stride=2, padding=0)

67 68 69 70 71 72 73
            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='avg',
            )
74
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
75

76 77 78
            avg_pool2d_dg = paddle.nn.layer.AvgPool2D(
                kernel_size=2, stride=2, padding=0
            )
79
            result = avg_pool2d_dg(input)
80
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
81

D
Double_V 已提交
82 83 84 85
    def check_avg_dygraph_padding_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
86 87 88 89 90 91 92 93 94 95 96 97
            result = avg_pool2d(
                input, kernel_size=2, stride=2, padding=1, ceil_mode=False
            )

            result_np = avg_pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[1, 1],
                ceil_mode=False,
                exclusive=False,
            )
98
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
99

100 101 102
            avg_pool2d_dg = paddle.nn.layer.AvgPool2D(
                kernel_size=2, stride=2, padding=1, ceil_mode=False
            )
D
Double_V 已提交
103
            result = avg_pool2d_dg(input)
104
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
105 106 107 108 109

    def check_avg_dygraph_ceilmode_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
110 111 112 113 114 115 116 117 118 119 120
            result = avg_pool2d(
                input, kernel_size=2, stride=2, padding=0, ceil_mode=True
            )

            result_np = avg_pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                ceil_mode=True,
            )
121
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
122

123 124 125
            avg_pool2d_dg = paddle.nn.layer.AvgPool2D(
                kernel_size=2, stride=2, padding=0, ceil_mode=True
            )
D
Double_V 已提交
126
            result = avg_pool2d_dg(input)
127
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
128

129 130
    def check_max_static_results(self, place):
        with fluid.program_guard(fluid.Program(), fluid.Program()):
131 132 133
            input = fluid.data(
                name="input", shape=[2, 3, 32, 32], dtype="float32"
            )
134 135 136
            result = max_pool2d(input, kernel_size=2, stride=2, padding=0)

            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
137 138 139 140 141 142 143
            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='max',
            )
144 145

            exe = fluid.Executor(place)
146 147 148 149 150
            fetches = exe.run(
                fluid.default_main_program(),
                feed={"input": input_np},
                fetch_list=[result],
            )
151
            np.testing.assert_allclose(fetches[0], result_np, rtol=1e-05)
152 153 154 155 156

    def check_max_dygraph_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
157 158 159 160 161 162 163 164 165 166 167
            result = max_pool2d(
                input, kernel_size=2, stride=2, padding=0, return_mask=False
            )

            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='max',
            )
168
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
169

170 171 172
            max_pool2d_dg = paddle.nn.layer.MaxPool2D(
                kernel_size=2, stride=2, padding=0
            )
173
            result = max_pool2d_dg(input)
174
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
175

D
Double_V 已提交
176 177 178 179
    def check_max_dygraph_nhwc_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
                np.transpose(input_np, [0, 2, 3, 1])
            )
            result = max_pool2d(
                input,
                kernel_size=2,
                stride=2,
                padding=0,
                return_mask=False,
                data_format="NHWC",
            )

            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='max',
            )
            np.testing.assert_allclose(
                np.transpose(result.numpy(), [0, 3, 1, 2]),
                result_np,
                rtol=1e-05,
            )
D
Double_V 已提交
203 204 205 206 207

    def check_max_dygraph_padding_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
208 209 210 211 212 213 214 215 216 217 218 219
            result = max_pool2d(
                input, kernel_size=2, stride=2, padding=1, ceil_mode=False
            )

            result_np = max_pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[1, 1],
                ceil_mode=False,
                exclusive=False,
            )
220
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
221

222 223 224
            max_pool2d_dg = paddle.nn.layer.MaxPool2D(
                kernel_size=2, stride=2, padding=1, ceil_mode=False
            )
D
Double_V 已提交
225
            result = max_pool2d_dg(input)
226
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
227 228 229 230 231

    def check_max_dygraph_ceilmode_results(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
232 233 234 235 236 237 238 239 240 241 242
            result = max_pool2d(
                input, kernel_size=2, stride=2, padding=0, ceil_mode=True
            )

            result_np = max_pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                ceil_mode=True,
            )
243
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
244

245 246 247
            max_pool2d_dg = paddle.nn.layer.MaxPool2D(
                kernel_size=2, stride=2, padding=0, ceil_mode=True
            )
D
Double_V 已提交
248
            result = max_pool2d_dg(input)
249
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
250

251 252 253 254
    def check_max_dygraph_stride_is_none(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
            result, indices = max_pool2d(
                input,
                kernel_size=2,
                stride=None,
                padding="SAME",
                return_mask=True,
            )

            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='max',
                padding_algorithm="SAME",
            )
271
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
272

273 274 275
            max_pool2d_dg = paddle.nn.layer.MaxPool2D(
                kernel_size=2, stride=2, padding=0
            )
276
            result = max_pool2d_dg(input)
277
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
278 279 280 281 282

    def check_avg_dygraph_stride_is_none(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
283 284 285 286 287 288 289 290 291 292 293 294
            result = avg_pool2d(
                input, kernel_size=2, stride=None, padding="SAME"
            )

            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='avg',
                padding_algorithm="SAME",
            )
295
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
296

297 298 299
            avg_pool2d_dg = paddle.nn.layer.AvgPool2D(
                kernel_size=2, stride=2, padding=0
            )
300
            result = avg_pool2d_dg(input)
301
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
302 303 304 305 306 307

    def check_max_dygraph_padding(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
            padding = [[0, 0], [0, 0], [0, 0], [0, 0]]
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
            result = max_pool2d(
                input,
                kernel_size=2,
                stride=2,
                padding=padding,
                return_mask=False,
            )

            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='max',
            )
323
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
324

325 326 327
            max_pool2d_dg = paddle.nn.layer.MaxPool2D(
                kernel_size=2, stride=2, padding=0
            )
328
            result = max_pool2d_dg(input)
329
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
330 331 332 333 334 335

    def check_avg_divisor(self, place):
        with fluid.dygraph.guard(place):
            input_np = np.random.random([2, 3, 32, 32]).astype("float32")
            input = fluid.dygraph.to_variable(input_np)
            padding = [[0, 0], [0, 0], [0, 0], [0, 0]]
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
            result = avg_pool2d(
                input,
                kernel_size=2,
                stride=2,
                padding=padding,
                divisor_override=4,
            )

            result_np = pool2D_forward_naive(
                input_np,
                ksize=[2, 2],
                strides=[2, 2],
                paddings=[0, 0],
                pool_type='avg',
            )
351
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
352

353 354 355
            avg_pool2d_dg = paddle.nn.layer.AvgPool2D(
                kernel_size=2, stride=2, padding=0
            )
356
            result = avg_pool2d_dg(input)
357
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
358 359 360 361 362 363 364 365 366 367 368 369

    def test_pool2d(self):
        for place in self.places:

            self.check_max_dygraph_results(place)
            self.check_avg_dygraph_results(place)
            self.check_max_static_results(place)
            self.check_avg_static_results(place)
            self.check_max_dygraph_stride_is_none(place)
            self.check_avg_dygraph_stride_is_none(place)
            self.check_max_dygraph_padding(place)
            self.check_avg_divisor(place)
D
Double_V 已提交
370 371 372
            self.check_max_dygraph_padding_results(place)
            self.check_max_dygraph_ceilmode_results(place)
            self.check_max_dygraph_nhwc_results(place)
373 374


C
cnn 已提交
375
class TestPool2DError_API(unittest.TestCase):
376 377 378
    def test_error_api(self):
        def run1():
            with fluid.dygraph.guard():
379 380 381
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
382 383
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = [[0, 1], [0, 0], [0, 0], [0, 0]]
384 385 386
                res_pd = max_pool2d(
                    input_pd, kernel_size=2, stride=2, padding=padding
                )
387 388 389 390 391

        self.assertRaises(ValueError, run1)

        def run2():
            with fluid.dygraph.guard():
392 393 394
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
395 396
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = [[0, 1], [0, 0], [0, 0], [0, 0]]
397 398 399 400 401 402 403
                res_pd = max_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    data_format='NHWC',
                )
404 405 406 407 408

        self.assertRaises(ValueError, run2)

        def run3():
            with fluid.dygraph.guard():
409 410 411
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
412 413
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "padding"
414 415 416 417 418 419 420
                res_pd = max_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    data_format='NHWC',
                )
421 422 423 424 425

        self.assertRaises(ValueError, run3)

        def run3_avg():
            with fluid.dygraph.guard():
426 427 428
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
429 430
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "padding"
431 432 433 434 435 436 437
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    data_format='NHWC',
                )
438 439 440 441 442

        self.assertRaises(ValueError, run3_avg)

        def run4():
            with fluid.dygraph.guard():
443 444 445
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
446 447
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "VALID"
448 449 450 451 452 453 454 455
                res_pd = max_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    ceil_mode=True,
                    data_format='NHWC',
                )
456 457 458 459 460

        self.assertRaises(ValueError, run4)

        def run4_avg():
            with fluid.dygraph.guard():
461 462 463
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
464 465
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "VALID"
466 467 468 469 470 471 472 473
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    ceil_mode=True,
                    data_format='NHWC',
                )
474 475 476 477 478

        self.assertRaises(ValueError, run4_avg)

        def run5():
            with fluid.dygraph.guard():
479 480 481
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
482 483
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "padding"
484 485 486 487 488 489 490
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    data_format='NHWC',
                )
491 492 493 494 495

        self.assertRaises(ValueError, run5)

        def run6():
            with fluid.dygraph.guard():
496 497 498
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
499 500
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "VALID"
501 502 503 504 505 506 507 508
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    ceil_mode=True,
                    data_format='NHWC',
                )
509 510 511 512 513

        self.assertRaises(ValueError, run6)

        def run7():
            with fluid.dygraph.guard():
514 515 516
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
517 518
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "VALID"
519 520 521 522 523 524 525 526
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    ceil_mode=False,
                    data_format='NNNN',
                )
527 528 529 530 531

        self.assertRaises(ValueError, run7)

        def run8():
            with fluid.dygraph.guard():
532 533 534
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
535 536
                input_pd = fluid.dygraph.to_variable(input_np)
                padding = "VALID"
537 538 539 540 541 542 543 544
                res_pd = max_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=padding,
                    ceil_mode=False,
                    data_format='NNNN',
                )
545 546 547

        self.assertRaises(ValueError, run8)

D
Double_V 已提交
548 549
        def run9():
            with fluid.dygraph.guard():
550 551 552
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
D
Double_V 已提交
553
                input_pd = fluid.dygraph.to_variable(input_np)
554 555 556 557 558 559 560 561 562
                res_pd = max_pool2d(
                    input_pd,
                    kernel_size=2,
                    stride=2,
                    padding=0,
                    ceil_mode=False,
                    data_format='NHWC',
                    return_mask=True,
                )
D
Double_V 已提交
563 564 565

        self.assertRaises(ValueError, run9)

D
Double_V 已提交
566 567
        def run_kernel_out_of_range():
            with fluid.dygraph.guard():
568 569 570
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
D
Double_V 已提交
571
                input_pd = fluid.dygraph.to_variable(input_np)
572 573 574 575 576 577 578 579
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=[-1, 2],
                    stride=2,
                    padding=0,
                    ceil_mode=False,
                    data_format='NHWC',
                )
D
Double_V 已提交
580 581 582 583 584

        self.assertRaises(ValueError, run_kernel_out_of_range)

        def run_stride_out_of_range():
            with fluid.dygraph.guard():
585 586 587
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
D
Double_V 已提交
588
                input_pd = fluid.dygraph.to_variable(input_np)
589 590 591 592 593 594 595 596
                res_pd = avg_pool2d(
                    input_pd,
                    kernel_size=3,
                    stride=[0, 2],
                    padding=0,
                    ceil_mode=False,
                    data_format='NHWC',
                )
D
Double_V 已提交
597 598 599

        self.assertRaises(ValueError, run_stride_out_of_range)

600 601 602

if __name__ == '__main__':
    unittest.main()