test_pool2d_api.py 21.1 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
F
From00 已提交
16
import paddle
17
import numpy as np
F
From00 已提交
18
import paddle.fluid as fluid
19
import paddle.fluid.core as core
F
From00 已提交
20
from paddle.fluid.framework import _test_eager_guard
X
xiaoting 已提交
21
from paddle.nn.functional import avg_pool2d, max_pool2d
22 23 24 25 26
from test_pool2d_op import (
    avg_pool2D_forward_naive,
    max_pool2D_forward_naive,
    pool2D_forward_naive,
)
27 28


C
cnn 已提交
29
class TestPool2D_API(unittest.TestCase):
30 31 32 33 34 35 36 37
    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()):
38 39 40
            input = fluid.data(
                name="input", shape=[2, 3, 32, 32], dtype="float32"
            )
41 42 43
            result = avg_pool2d(input, kernel_size=2, stride=2, padding=0)

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

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

    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)

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

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

D
Double_V 已提交
81 82 83 84
    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)
85 86 87 88 89 90 91 92 93 94 95 96
            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,
            )
97
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
98

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

    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)
109 110 111 112 113 114 115 116 117 118 119
            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,
            )
120
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
121

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

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

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

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

    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)
156 157 158 159 160 161 162 163 164 165 166
            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',
            )
167
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
168

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

D
Double_V 已提交
175 176 177 178
    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(
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
                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 已提交
202 203 204 205 206

    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)
207 208 209 210 211 212 213 214 215 216 217 218
            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,
            )
219
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
220

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

    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)
231 232 233 234 235 236 237 238 239 240 241
            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,
            )
242
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
D
Double_V 已提交
243

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

250 251 252 253
    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)
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
            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",
            )
270
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
271

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

    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)
282 283 284 285 286 287 288 289 290 291 292 293
            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",
            )
294
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
295

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

    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]]
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
            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',
            )
322
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
323

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

    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]]
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
            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',
            )
350
            np.testing.assert_allclose(result.numpy(), result_np, rtol=1e-05)
351

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

    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 已提交
369 370 371
            self.check_max_dygraph_padding_results(place)
            self.check_max_dygraph_ceilmode_results(place)
            self.check_max_dygraph_nhwc_results(place)
372

373
    def test_dygraph_api(self):
F
From00 已提交
374 375 376
        with _test_eager_guard():
            self.test_pool2d()

377

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

        self.assertRaises(ValueError, run1)

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

        self.assertRaises(ValueError, run2)

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

        self.assertRaises(ValueError, run3)

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

        self.assertRaises(ValueError, run3_avg)

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

        self.assertRaises(ValueError, run4)

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

        self.assertRaises(ValueError, run4_avg)

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

        self.assertRaises(ValueError, run5)

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

        self.assertRaises(ValueError, run6)

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

        self.assertRaises(ValueError, run7)

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

        self.assertRaises(ValueError, run8)

D
Double_V 已提交
551 552
        def run9():
            with fluid.dygraph.guard():
553 554 555
                input_np = np.random.uniform(-1, 1, [2, 3, 32, 32]).astype(
                    np.float32
                )
D
Double_V 已提交
556
                input_pd = fluid.dygraph.to_variable(input_np)
557 558 559 560 561 562 563 564 565
                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 已提交
566 567 568

        self.assertRaises(ValueError, run9)

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

        self.assertRaises(ValueError, run_kernel_out_of_range)

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

        self.assertRaises(ValueError, run_stride_out_of_range)

603
    def test_dygraph_api(self):
F
From00 已提交
604 605 606
        with _test_eager_guard():
            self.test_error_api()

607 608 609

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