1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Functional tests for pooling operations.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21import collections 22import os 23import numpy as np 24 25from tensorflow.python.eager import context 26from tensorflow.python.framework import constant_op 27from tensorflow.python.framework import dtypes 28from tensorflow.python.framework import errors_impl 29from tensorflow.python.framework import ops 30from tensorflow.python.framework import test_util 31from tensorflow.python.ops import array_ops 32from tensorflow.python.ops import gen_array_ops 33from tensorflow.python.ops import gen_nn_ops 34from tensorflow.python.ops import gradient_checker 35from tensorflow.python.ops import gradients_impl 36from tensorflow.python.ops import nn_ops 37from tensorflow.python.ops import variables 38import tensorflow.python.ops.nn_grad # pylint: disable=unused-import 39from tensorflow.python.platform import test 40from tensorflow.python.platform import tf_logging 41 42 43def GetDeviceScope(self, use_gpu=False): 44 if context.executing_eagerly(): 45 if use_gpu and test.is_gpu_available(): 46 return ops.device("GPU:0") 47 return ops.device("CPU:0") 48 else: 49 return self.session(use_gpu=use_gpu) 50 51 52def GetTestConfigs(include_nchw_vect_c=False): 53 """Get all the valid tests configs to run. 54 55 Args: 56 include_nchw_vect_c: Whether to include NCHW_VECT_C in the test configs. 57 58 Returns: 59 all the valid test configs as tuples of data_format and use_gpu. 60 """ 61 test_configs = [("NHWC", False), ("NHWC", True)] 62 if not test.is_gpu_available(cuda_only=True): 63 tf_logging.info("NCHW and NCHW_VECT_C tests skipped because not run with " 64 "--config=cuda or no GPUs available.") 65 return test_configs 66 # "NCHW" format is currently supported exclusively on CUDA GPUs. 67 test_configs += [("NCHW", True)] 68 if include_nchw_vect_c: 69 if test.is_gpu_available( 70 cuda_only=True, min_cuda_compute_capability=(6, 1)): 71 test_configs += [("NCHW_VECT_C", True)] 72 else: 73 tf_logging.info("NCHW_VECT_C test skipped because no GPUs with " 74 "compute capability >= 6.1 are available.") 75 76 return test_configs 77 78 79def GetShrunkInceptionMaxPoolShapes(shrink=30): 80 """Iterator for some of the max pool ops in the Inception 2015 model. 81 82 Args: 83 shrink: Factor to shrink depth relative to Inception. 84 85 Yields: 86 Tuple (name, input_size, filter_size, out_size, strides, padding) 87 """ 88 names = ["maxpool2", "maxpool3", "maxpool4", "maxpool5"] 89 input_sizes = [[32, 71, 71, 192], [32, 35, 35, 288], [32, 17, 17, 1248], 90 [32, 8, 8, 2048]] 91 filter_sizes = [[1, 3, 3, 1], [1, 3, 3, 1], [1, 3, 3, 1], [1, 3, 3, 1]] 92 output_sizes = [[32, 35, 35, 192], [32, 17, 17, 288], [32, 8, 8, 1248], 93 [32, 8, 8, 2048]] 94 strides = [[1, 2, 2, 1], [1, 2, 2, 1], [1, 2, 2, 1], [1, 1, 1, 1]] 95 # Shrink each depth value 96 for i in input_sizes: 97 i[3] //= shrink 98 for o in output_sizes: 99 o[3] //= shrink 100 paddings = ["VALID", "VALID", "VALID", "SAME"] 101 for n, i, f, o, s, p in zip(names, input_sizes, filter_sizes, output_sizes, 102 strides, paddings): 103 yield n, i, f, o, s, p 104 105 106class PoolingTest(test.TestCase): 107 108 def _VerifyOneType(self, pool_func, input_sizes, ksize, strides, padding, 109 data_format, data_type, expected, use_gpu, v2): 110 """Verifies the output values of the pooling function. 111 112 Args: 113 pool_func: Function to be called, co.MaxPool, co.AvgPool, 114 or the Lua version. 115 input_sizes: Input tensor dimensions. 116 ksize: The kernel size dimensions 117 strides: The stride dimensions 118 padding: Padding type. 119 data_format: The data format we use to run the pooling operation. 120 data_type: The data type to use to run the pooling operation. 121 expected: An array containing the expected operation outputs. 122 use_gpu: Whether we are running on GPU. 123 """ 124 total_size = 1 125 for s in input_sizes: 126 total_size *= s 127 if v2 and data_format != "NHWC": 128 tf_logging.info("v2 not supported for %s", data_format) 129 return 130 if data_format == "NCHW_VECT_C": 131 if data_type != dtypes.float32: 132 tf_logging.info("quantization to qint8 not implemented for %r", 133 data_type) 134 return 135 if input_sizes[-1] % 4 != 0: 136 tf_logging.info("Skipping test for depth %d", input_sizes[-1]) 137 return 138 tf_logging.info("Running %s test. %r %r %d %r %r %r %s", data_format, v2, 139 input_sizes, total_size, pool_func, ksize, strides, 140 data_type) 141 # Initializes the input tensor with array containing incrementing 142 # numbers from 1, wrapping round to -127 after 127 to support int8. 143 x = [((f + 128) % 255) - 127 for f in range(total_size)] 144 with self.cached_session(use_gpu=use_gpu): 145 t = constant_op.constant(x, shape=input_sizes, dtype=data_type) 146 if data_format in ("NCHW", "NCHW_VECT_C"): 147 if data_format == "NCHW_VECT_C": 148 t = test_util.NHWCToNCHW_VECT_C(t) 149 t, _, _ = gen_array_ops.quantize_v2(t, -128.0, 127.0, dtypes.qint8) 150 else: 151 t = test_util.NHWCToNCHW(t) 152 ksize = test_util.NHWCToNCHW(ksize) 153 strides = test_util.NHWCToNCHW(strides) 154 ksize_placeholder = array_ops.placeholder(dtypes.int32, shape=[4]) 155 strides_placeholder = array_ops.placeholder(dtypes.int32, shape=[4]) 156 if v2: 157 t = pool_func( 158 t, 159 ksize=ksize_placeholder, 160 strides=strides_placeholder, 161 padding=padding, 162 data_format=data_format) 163 else: 164 t = pool_func( 165 t, 166 ksize=ksize, 167 strides=strides, 168 padding=padding, 169 data_format=data_format) 170 if data_format == "NCHW_VECT_C": 171 t = gen_array_ops.dequantize(t, -128, 127) 172 t = test_util.NCHW_VECT_CToNHWC(t) 173 elif data_format == "NCHW": 174 t = test_util.NCHWToNHWC(t) 175 if v2: 176 actual = t.eval(feed_dict={ 177 ksize_placeholder: ksize, 178 strides_placeholder: strides 179 }) 180 else: 181 actual = self.evaluate(t) 182 self.assertShapeEqual(actual, t) 183 self.assertAllCloseAccordingToType(expected, actual.flatten()) 184 185 def _VerifyOneTest(self, pool_func, input_sizes, ksize, strides, padding, 186 data_format, expected, use_gpu, v2): 187 """Verifies the output values of the pooling function. 188 189 Args: 190 pool_func: Function to be called, co.MaxPool, co.AvgPool, 191 or the Lua version. 192 input_sizes: Input tensor dimensions. 193 ksize: The kernel size dimensions 194 strides: The stride dimensions 195 padding: Padding type. 196 data_format: The data format we use to run the pooling operation. 197 expected: An array containing the expected operation outputs. 198 use_gpu: Whether we are running on GPU. 199 """ 200 if data_format == "NCHW_VECT_C": 201 avg_pool_func = nn_ops.avg_pool 202 tf_logging.info("pool_func=%s", pool_func) 203 if pool_func == avg_pool_func: 204 tf_logging.info("NCHW_VECT_C not yet implemented for avg_pool") 205 return 206 207 self._VerifyOneType(pool_func, input_sizes, ksize, strides, padding, 208 data_format, dtypes.float32, expected, use_gpu, v2) 209 self._VerifyOneType(pool_func, input_sizes, ksize, strides, padding, 210 data_format, dtypes.float64, expected, use_gpu, v2) 211 212 if not use_gpu or test_util.CudaSupportsHalfMatMulAndConv(): 213 self._VerifyOneType(pool_func, input_sizes, ksize, strides, padding, 214 data_format, dtypes.float16, expected, use_gpu, v2) 215 216 def _VerifyValues(self, 217 pool_func, 218 input_sizes, 219 ksize, 220 strides, 221 padding, 222 expected, 223 use_gpu, 224 v2=False): 225 """Verifies the output values of the pooling function. 226 227 Args: 228 pool_func: Function to be called, co.MaxPool, co.AvgPool, 229 or the Lua version. 230 input_sizes: Input tensor dimensions. 231 ksize: The kernel size dimensions 232 strides: The stride dimensions 233 padding: Padding type. 234 expected: An array containing the expected operation outputs. 235 use_gpu: Whether we are running on GPU. 236 """ 237 for (data_format, use_gpu_2) in GetTestConfigs(True): 238 if use_gpu_2 == use_gpu: 239 self._VerifyOneTest(pool_func, input_sizes, ksize, strides, padding, 240 data_format, expected, use_gpu, v2) 241 242 def _testAvgPoolValidPadding(self, use_gpu): 243 expected_output = [7.0, 8.0, 9.0] 244 self._VerifyValues( 245 nn_ops.avg_pool, 246 input_sizes=[1, 3, 3, 3], 247 ksize=[1, 2, 2, 1], 248 strides=[1, 2, 2, 1], 249 padding="VALID", 250 expected=expected_output, 251 use_gpu=use_gpu) 252 253 def _testAvgPoolSamePadding(self, use_gpu): 254 expected_output = [8.5, 9.5, 10.5, 14.5, 15.5, 16.5] 255 self._VerifyValues( 256 nn_ops.avg_pool, 257 input_sizes=[1, 2, 4, 3], 258 ksize=[1, 2, 2, 1], 259 strides=[1, 2, 2, 1], 260 padding="SAME", 261 expected=expected_output, 262 use_gpu=use_gpu) 263 264 def _testAvgPoolSamePaddingNonSquareWindow(self, use_gpu): 265 # input is: 266 # [1.0, 2.0 267 # 3.0 4.0] 268 # 269 # Window of [x, x] should do: 270 # [avg(1.0, 2.0), avg(2.0, padded0), 271 # avg(3.0, 4.0), avg(4.0, padded0)] 272 self._VerifyValues( 273 nn_ops.avg_pool, 274 input_sizes=[1, 2, 2, 1], 275 ksize=[1, 1, 2, 1], 276 strides=[1, 1, 1, 1], 277 padding="SAME", 278 expected=[1.5, 2.0, 3.5, 4.0], 279 use_gpu=use_gpu) 280 281 # Window of [x, 282 # x] should do: 283 # [avg(1.0, 3.0), avg(2.0, 4.0) 284 # avg(3.0, padded0), avg(4.0, padded0)] 285 self._VerifyValues( 286 nn_ops.avg_pool, 287 input_sizes=[1, 2, 2, 1], 288 ksize=[1, 2, 1, 1], 289 strides=[1, 1, 1, 1], 290 padding="SAME", 291 expected=[2.0, 3.0, 3.0, 4.0], 292 use_gpu=use_gpu) 293 294 def _testAvgPoolSamePaddingNonSquareWindowMultiBatch(self, use_gpu): 295 self._VerifyValues( 296 nn_ops.avg_pool, 297 input_sizes=[2, 2, 2, 2], 298 ksize=[1, 1, 2, 1], 299 strides=[1, 1, 1, 1], 300 padding="SAME", 301 expected=[ 302 2.0, 3.0, 3.0, 4.0, 6.0, 7.0, 7.0, 8.0, 10.0, 11.0, 11.0, 12.0, 303 14.0, 15.0, 15.0, 16.0 304 ], 305 use_gpu=use_gpu) 306 self._VerifyValues( 307 nn_ops.avg_pool, 308 input_sizes=[2, 2, 2, 2], 309 ksize=[1, 2, 1, 1], 310 strides=[1, 1, 1, 1], 311 padding="SAME", 312 expected=[ 313 3.0, 4.0, 5.0, 6.0, 5.0, 6.0, 7.0, 8.0, 11.0, 12.0, 13.0, 14.0, 314 13.0, 14.0, 15.0, 16.0 315 ], 316 use_gpu=use_gpu) 317 318 def _testAvgPoolValidPaddingUnevenStride(self, use_gpu): 319 self._VerifyValues( 320 nn_ops.avg_pool, 321 input_sizes=[1, 3, 3, 3], 322 ksize=[1, 2, 2, 1], 323 strides=[1, 1, 2, 1], 324 padding="VALID", 325 expected=[7.0, 8.0, 9.0, 16.0, 17.0, 18.0], 326 use_gpu=use_gpu) 327 self._VerifyValues( 328 nn_ops.avg_pool, 329 input_sizes=[1, 3, 3, 3], 330 ksize=[1, 2, 2, 1], 331 strides=[1, 2, 1, 1], 332 padding="VALID", 333 expected=[7.0, 8.0, 9.0, 10.0, 11.0, 12.0], 334 use_gpu=use_gpu) 335 336 def _testAvgPoolSamePadding4(self, use_gpu): 337 expected_output = [ 338 11.0, 12.0, 13.0, 14.0, 19.0, 20.0, 21.0, 22.0, 43.0, 44.0, 45.0, 46.0, 339 51.0, 52.0, 53.0, 54.0 340 ] 341 self._VerifyValues( 342 nn_ops.avg_pool, 343 input_sizes=[1, 4, 4, 4], 344 ksize=[1, 2, 2, 1], 345 strides=[1, 2, 2, 1], 346 padding="SAME", 347 expected=expected_output, 348 use_gpu=use_gpu) 349 350 def _testAvgPoolSamePaddingPacket4(self, use_gpu): 351 expected_output = [ 352 21.0, 22.0, 23.0, 24.0, 27.0, 28.0, 29.0, 30.0, 45.0, 46.0, 47.0, 48.0, 353 51.0, 52.0, 53.0, 54.0 354 ] 355 self._VerifyValues( 356 nn_ops.avg_pool, 357 input_sizes=[1, 4, 4, 4], 358 ksize=[1, 3, 3, 1], 359 strides=[1, 2, 2, 1], 360 padding="SAME", 361 expected=expected_output, 362 use_gpu=use_gpu) 363 364 def _testAvgPoolSamePaddingPacket8(self, use_gpu): 365 expected_output = [ 366 -12.0, -11.0, -10.0, -9.0, -8.0, -7.0, -6.0, -5.0, 4.0, 5.0, 6.0, 7.0, 367 8.0, 9.0, 10.0, 11.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 368 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, -3.5, -54.0, -53.0, -52.0, 369 -51.0, -50.0, -49.0, -48.0, -47.0, -38.0, -37.0, -36.0, -35.0, -34.0, 370 -33.0, -32.0, -31.0, -22.0, -21.0, -20.0, -19.0, -18.0, -17.0, -16.0, 371 -15.0, -10.0, -9.0, -8.0, -7.0, -6.0, -5.0, -4.0, -3.0, -11.0, -10.0, 372 -9.0, -8.0, -7.0, -6.0, -5.0, -4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 373 12.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 33.0, 34.0, 35.0, 374 36.0, 37.0, 38.0, -3.5, -2.5, -85.0, -84.0, -83.0, -82.0, -81.0, -80.0, 375 -79.0, -78.0, -69.0, -68.0, -67.0, -66.0, -65.0, -64.0, -63.0, -62.0, 376 -53.0, -52.0, -51.0, -50.0, -49.0, -48.0, -47.0, -46.0, -41.0, -40.0, 377 -39.0, -38.0, -37.0, -36.0, -35.0, -34.0 378 ] 379 380 self._VerifyValues( 381 nn_ops.avg_pool, 382 input_sizes=[1, 8, 8, 8], 383 ksize=[1, 3, 3, 1], 384 strides=[1, 2, 2, 1], 385 padding="SAME", 386 expected=expected_output, 387 use_gpu=use_gpu) 388 389 def _testAvgPoolEmptyInput(self, use_gpu): 390 self._VerifyValues( 391 nn_ops.avg_pool, 392 input_sizes=[0, 8, 8, 8], 393 ksize=[1, 3, 3, 1], 394 strides=[1, 2, 2, 1], 395 padding="SAME", 396 expected=[], 397 use_gpu=use_gpu) 398 399 @test_util.run_deprecated_v1 400 def testAvgPooling(self): 401 for use_gpu in True, False: 402 self._testAvgPoolValidPadding(use_gpu) 403 self._testAvgPoolSamePadding(use_gpu) 404 self._testAvgPoolSamePaddingNonSquareWindow(use_gpu) 405 self._testAvgPoolSamePaddingNonSquareWindowMultiBatch(use_gpu) 406 self._testAvgPoolValidPaddingUnevenStride(use_gpu) 407 self._testAvgPoolSamePadding4(use_gpu) 408 self._testAvgPoolSamePaddingPacket4(use_gpu) 409 self._testAvgPoolSamePaddingPacket8(use_gpu) 410 self._testAvgPoolEmptyInput(use_gpu) 411 412 def _testMaxPoolValidPadding(self, use_gpu): 413 expected_output = [13.0, 14.0, 15.0] 414 self._VerifyValues( 415 nn_ops.max_pool, 416 input_sizes=[1, 3, 3, 3], 417 ksize=[1, 2, 2, 1], 418 strides=[1, 2, 2, 1], 419 padding="VALID", 420 expected=expected_output, 421 use_gpu=use_gpu) 422 423 for v2 in [True, False]: 424 self._VerifyValues( 425 gen_nn_ops.max_pool_v2, 426 input_sizes=[1, 3, 3, 3], 427 ksize=[1, 2, 2, 1], 428 strides=[1, 2, 2, 1], 429 padding="VALID", 430 expected=expected_output, 431 use_gpu=use_gpu, 432 v2=v2) 433 434 def _testMaxPoolSamePadding(self, use_gpu): 435 expected_output = [13.0, 14.0, 15.0, 16.0, 17.0, 18.0] 436 self._VerifyValues( 437 nn_ops.max_pool, 438 input_sizes=[1, 2, 3, 3], 439 ksize=[1, 2, 2, 1], 440 strides=[1, 2, 2, 1], 441 padding="SAME", 442 expected=expected_output, 443 use_gpu=use_gpu) 444 445 for v2 in [True, False]: 446 self._VerifyValues( 447 gen_nn_ops.max_pool_v2, 448 input_sizes=[1, 2, 3, 3], 449 ksize=[1, 2, 2, 1], 450 strides=[1, 2, 2, 1], 451 padding="SAME", 452 expected=expected_output, 453 use_gpu=use_gpu, 454 v2=v2) 455 456 def _testMaxPoolSamePaddingNonSquareWindow(self, use_gpu): 457 # input is: 458 # [1.0, 2.0 459 # 3.0 4.0] 460 # 461 # Window of [x, x] should do: 462 # 463 # [max(1.0, 2.0), max(2.0, padded0), 464 # max(3.0, 4.0), max(4.0, padded0)] 465 self._VerifyValues( 466 nn_ops.max_pool, 467 input_sizes=[1, 2, 2, 1], 468 ksize=[1, 1, 2, 1], 469 strides=[1, 1, 1, 1], 470 padding="SAME", 471 expected=[2.0, 2.0, 4.0, 4.0], 472 use_gpu=use_gpu) 473 474 for v2 in [True, False]: 475 self._VerifyValues( 476 gen_nn_ops.max_pool_v2, 477 input_sizes=[1, 2, 2, 1], 478 ksize=[1, 1, 2, 1], 479 strides=[1, 1, 1, 1], 480 padding="SAME", 481 expected=[2.0, 2.0, 4.0, 4.0], 482 use_gpu=use_gpu, 483 v2=v2) 484 485 def _testMaxPoolValidPaddingUnevenStride(self, use_gpu): 486 self._VerifyValues( 487 nn_ops.max_pool, 488 input_sizes=[1, 4, 4, 1], 489 ksize=[1, 2, 2, 1], 490 strides=[1, 1, 2, 1], 491 padding="VALID", 492 expected=[6.0, 8.0, 10.0, 12.0, 14.0, 16.0], 493 use_gpu=use_gpu) 494 self._VerifyValues( 495 nn_ops.max_pool, 496 input_sizes=[1, 4, 4, 1], 497 ksize=[1, 2, 2, 1], 498 strides=[1, 2, 1, 1], 499 padding="VALID", 500 expected=[6.0, 7.0, 8.0, 14.0, 15.0, 16.0], 501 use_gpu=use_gpu) 502 503 for v2 in [True, False]: 504 self._VerifyValues( 505 gen_nn_ops.max_pool_v2, 506 input_sizes=[1, 4, 4, 1], 507 ksize=[1, 2, 2, 1], 508 strides=[1, 1, 2, 1], 509 padding="VALID", 510 expected=[6.0, 8.0, 10.0, 12.0, 14.0, 16.0], 511 use_gpu=use_gpu, 512 v2=v2) 513 self._VerifyValues( 514 gen_nn_ops.max_pool_v2, 515 input_sizes=[1, 4, 4, 1], 516 ksize=[1, 2, 2, 1], 517 strides=[1, 2, 1, 1], 518 padding="VALID", 519 expected=[6.0, 7.0, 8.0, 14.0, 15.0, 16.0], 520 use_gpu=use_gpu, 521 v2=v2) 522 523 def _testMaxPoolSamePaddingPacket4(self, use_gpu): 524 expected_output = [ 525 21.0, 22.0, 23.0, 24.0, 29.0, 30.0, 31.0, 32.0, 53.0, 54.0, 55.0, 56.0, 526 61.0, 62.0, 63.0, 64.0 527 ] 528 self._VerifyValues( 529 nn_ops.max_pool, 530 input_sizes=[1, 4, 4, 4], 531 ksize=[1, 2, 2, 1], 532 strides=[1, 2, 2, 1], 533 padding="SAME", 534 expected=expected_output, 535 use_gpu=use_gpu) 536 537 for v2 in [True, False]: 538 self._VerifyValues( 539 gen_nn_ops.max_pool_v2, 540 input_sizes=[1, 4, 4, 4], 541 ksize=[1, 2, 2, 1], 542 strides=[1, 2, 2, 1], 543 padding="SAME", 544 expected=expected_output, 545 use_gpu=use_gpu, 546 v2=v2) 547 548 def _testMaxPoolSamePaddingPacket8(self, use_gpu): 549 expected_output = [ 550 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 97.0, 98.0, 99.0, 100.0, 551 101.0, 102.0, 103.0, 104.0, 113.0, 114.0, 115.0, 116.0, 117.0, 118.0, 552 119.0, 120.0, 121.0, 122.0, 123.0, 124.0, 125.0, 126.0, 127.0, 120.0, 553 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 34.0, 35.0, 36.0, 37.0, 554 38.0, 39.0, 40.0, 41.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 555 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 82.0, 83.0, 84.0, 85.0, 556 86.0, 87.0, 88.0, 89.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 557 105.0, 114.0, 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 558 123.0, 124.0, 125.0, 126.0, 127.0, 120.0, 121.0, -45.0, -44.0, -43.0, 559 -42.0, -41.0, -40.0, -39.0, -38.0, -29.0, -28.0, -27.0, -26.0, -25.0, 560 -24.0, -23.0, -22.0, -13.0, -12.0, -11.0, -10.0, -9.0, -8.0, -7.0, -6.0, 561 -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0 562 ] 563 self._VerifyValues( 564 nn_ops.max_pool, 565 input_sizes=[1, 8, 8, 8], 566 ksize=[1, 3, 3, 1], 567 strides=[1, 2, 2, 1], 568 padding="SAME", 569 expected=expected_output, 570 use_gpu=use_gpu) 571 572 for v2 in [True, False]: 573 self._VerifyValues( 574 gen_nn_ops.max_pool_v2, 575 input_sizes=[1, 8, 8, 8], 576 ksize=[1, 3, 3, 1], 577 strides=[1, 2, 2, 1], 578 padding="SAME", 579 expected=expected_output, 580 use_gpu=use_gpu, 581 v2=v2) 582 583 def _testMaxPoolEmptyInput(self, use_gpu): 584 self._VerifyValues( 585 gen_nn_ops.max_pool_v2, 586 input_sizes=[0, 8, 8, 8], 587 ksize=[1, 3, 3, 1], 588 strides=[1, 2, 2, 1], 589 padding="SAME", 590 expected=[], 591 use_gpu=use_gpu) 592 593 @test_util.run_deprecated_v1 594 def testMaxPooling(self): 595 for use_gpu in True, False: 596 self._testMaxPoolValidPadding(use_gpu) 597 self._testMaxPoolSamePadding(use_gpu) 598 self._testMaxPoolSamePaddingNonSquareWindow(use_gpu) 599 self._testMaxPoolValidPaddingUnevenStride(use_gpu) 600 self._testMaxPoolSamePaddingPacket4(use_gpu) 601 self._testMaxPoolSamePaddingPacket8(use_gpu) 602 self._testMaxPoolEmptyInput(use_gpu) 603 604 # Tests for DepthwiseMaxPooling on CPU only. 605 @test_util.run_deprecated_v1 606 def testDepthwiseMaxPool1x1DepthWindow1(self): 607 # input is: 608 # [1.0, ..., 10.0] along depth, 609 # 610 # We maxpool by depth in patches of 2. 611 self._VerifyValues( 612 nn_ops.max_pool, 613 input_sizes=[1, 1, 1, 10], 614 ksize=[1, 1, 1, 2], 615 strides=[1, 1, 1, 2], 616 padding="SAME", 617 expected=[2.0, 4.0, 6.0, 8.0, 10.0], 618 use_gpu=False) 619 620 for v2 in [True, False]: 621 self._VerifyValues( 622 gen_nn_ops.max_pool_v2, 623 input_sizes=[1, 1, 1, 10], 624 ksize=[1, 1, 1, 2], 625 strides=[1, 1, 1, 2], 626 padding="SAME", 627 expected=[2.0, 4.0, 6.0, 8.0, 10.0], 628 use_gpu=False, 629 v2=v2) 630 631 @test_util.run_deprecated_v1 632 def testDepthwiseMaxPool2x2DepthWindow3(self): 633 # input is: 634 # 635 # a 2x2x6 cube, and we depthwise max across 3 to produce a 2x2x2 636 # output. Each node has contiguous values, so the depthwise max 637 # should be multiples of 3.0. 638 self._VerifyValues( 639 nn_ops.max_pool, 640 input_sizes=[1, 2, 2, 6], 641 ksize=[1, 1, 1, 3], 642 strides=[1, 1, 1, 3], 643 padding="SAME", 644 expected=[3.0, 6.0, 9.0, 12.0, 15.0, 18.0, 21.0, 24.0], 645 use_gpu=False) 646 647 for v2 in [True, False]: 648 self._VerifyValues( 649 gen_nn_ops.max_pool_v2, 650 input_sizes=[1, 2, 2, 6], 651 ksize=[1, 1, 1, 3], 652 strides=[1, 1, 1, 3], 653 padding="SAME", 654 expected=[3.0, 6.0, 9.0, 12.0, 15.0, 18.0, 21.0, 24.0], 655 use_gpu=False, 656 v2=v2) 657 658 @test_util.run_deprecated_v1 659 def testKernelSmallerThanStrideValid(self): 660 for use_gpu in [True, False]: 661 self._VerifyValues( 662 nn_ops.max_pool, 663 input_sizes=[1, 7, 7, 1], 664 ksize=[1, 2, 2, 1], 665 strides=[1, 3, 3, 1], 666 padding="VALID", 667 expected=[9, 12, 30, 33], 668 use_gpu=use_gpu) 669 670 for v2 in [True, False]: 671 self._VerifyValues( 672 gen_nn_ops.max_pool_v2, 673 input_sizes=[1, 7, 7, 1], 674 ksize=[1, 2, 2, 1], 675 strides=[1, 3, 3, 1], 676 padding="VALID", 677 expected=[9, 12, 30, 33], 678 use_gpu=use_gpu, 679 v2=v2) 680 681 self._VerifyValues( 682 nn_ops.avg_pool, 683 input_sizes=[1, 7, 7, 1], 684 ksize=[1, 2, 2, 1], 685 strides=[1, 3, 3, 1], 686 padding="VALID", 687 expected=[5, 8, 26, 29], 688 use_gpu=use_gpu) 689 690 @test_util.run_deprecated_v1 691 def testKernelSmallerThanStrideSame(self): 692 for use_gpu in [True, False]: 693 for pool_func in [nn_ops.max_pool, nn_ops.avg_pool]: 694 self._VerifyValues( 695 pool_func, 696 input_sizes=[1, 3, 3, 1], 697 ksize=[1, 1, 1, 1], 698 strides=[1, 2, 2, 1], 699 padding="SAME", 700 expected=[1, 3, 7, 9], 701 use_gpu=use_gpu) 702 703 self._VerifyValues( 704 pool_func, 705 input_sizes=[1, 4, 4, 1], 706 ksize=[1, 1, 1, 1], 707 strides=[1, 2, 2, 1], 708 padding="SAME", 709 expected=[1, 3, 9, 11], 710 use_gpu=use_gpu) 711 712 for v2 in [True, False]: 713 self._VerifyValues( 714 gen_nn_ops.max_pool_v2, 715 input_sizes=[1, 3, 3, 1], 716 ksize=[1, 1, 1, 1], 717 strides=[1, 2, 2, 1], 718 padding="SAME", 719 expected=[1, 3, 7, 9], 720 use_gpu=use_gpu, 721 v2=v2) 722 723 self._VerifyValues( 724 gen_nn_ops.max_pool_v2, 725 input_sizes=[1, 4, 4, 1], 726 ksize=[1, 1, 1, 1], 727 strides=[1, 2, 2, 1], 728 padding="SAME", 729 expected=[1, 3, 9, 11], 730 use_gpu=use_gpu, 731 v2=v2) 732 733 def _testDepthwiseMaxPoolInvalidConfig(self, 734 in_size, 735 ksize, 736 strides, 737 error_msg, 738 use_gpu=False): 739 with self.cached_session(use_gpu=use_gpu): 740 t = constant_op.constant(1.0, shape=in_size) 741 with self.assertRaisesRegexp(errors_impl.UnimplementedError, error_msg): 742 t = nn_ops.max_pool( 743 t, ksize=ksize, strides=strides, padding="SAME").eval() 744 745 @test_util.disable_xla("b/123338077") # Passes with XLA 746 def testDepthwiseMaxPoolInvalidConfigs(self): 747 self._testDepthwiseMaxPoolInvalidConfig( 748 [1, 2, 2, 4], [1, 2, 2, 2], [1, 1, 1, 2], 749 "exactly one of pooling across depth") 750 self._testDepthwiseMaxPoolInvalidConfig( 751 [1, 2, 2, 4], [1, 1, 1, 2], [1, 1, 1, 1], 752 "depth window to equal the depth stride") 753 self._testDepthwiseMaxPoolInvalidConfig([1, 2, 2, 4], [1, 1, 1, 3], 754 [1, 1, 1, 3], "evenly divide") 755 if test.is_gpu_available(): 756 with self.session(use_gpu=True): 757 t = variables.Variable(np.ones([1, 2, 2, 4])) 758 self.evaluate(variables.global_variables_initializer()) 759 with self.assertRaisesOpError("for CPU devices"): 760 nn_ops.max_pool( 761 t, ksize=[1, 1, 1, 2], strides=[1, 1, 1, 2], 762 padding="SAME").eval() 763 764 # The following are tests that verify that the CPU and GPU implementations 765 # produce the same results. 766 def _CompareMaxPoolingFwd(self, input_shape, ksize, strides, padding): 767 for dtype in np.float64, np.float32, np.float16: 768 tensor_input = np.random.rand(*input_shape).astype(dtype) 769 with self.cached_session(use_gpu=True): 770 t = constant_op.constant(tensor_input, shape=input_shape) 771 out_op, _ = nn_ops.max_pool_with_argmax(t, ksize, strides, padding) 772 gpu_val = self.evaluate(out_op) 773 with self.cached_session(use_gpu=False): 774 t = constant_op.constant(tensor_input, shape=input_shape) 775 out_op = nn_ops.max_pool(t, ksize, strides, padding) 776 cpu_val = self.evaluate(out_op) 777 self.assertAllCloseAccordingToType(cpu_val, gpu_val) 778 779 def _CompareMaxPoolingBk(self, input_shape, output_shape, ksize, strides, 780 padding): 781 for dtype in np.float64, np.float32, np.float16: 782 # Generate numbers in a narrow range, so that there are many duplicates 783 # in the input. 784 tensor_input = np.random.random_integers(0, 3, input_shape).astype(dtype) 785 tensor_output = np.random.rand(*output_shape).astype(dtype) 786 with self.cached_session(use_gpu=True): 787 t = constant_op.constant(tensor_input, shape=input_shape) 788 _, argmax_op = nn_ops.max_pool_with_argmax(t, ksize, strides, padding) 789 argmax = self.evaluate(argmax_op) 790 grad_in = constant_op.constant(tensor_output, shape=output_shape) 791 out_op = gen_nn_ops.max_pool_grad_with_argmax(t, grad_in, argmax, ksize, 792 strides, padding) 793 gpu_val = self.evaluate(out_op) 794 self.assertShapeEqual(gpu_val, out_op) 795 with self.cached_session(use_gpu=False): 796 t = constant_op.constant(tensor_input, shape=input_shape) 797 out_op = nn_ops.max_pool(t, ksize, strides, padding) 798 orig_out = self.evaluate(out_op) 799 grad_in = constant_op.constant(tensor_output, shape=output_shape) 800 out_op = gen_nn_ops.max_pool_grad(t, orig_out, grad_in, ksize, strides, 801 padding) 802 cpu_val = self.evaluate(out_op) 803 self.assertShapeEqual(cpu_val, out_op) 804 # The CPU version accumulates its gradient on fp16, so it's less 805 # accurate than the GPU version that does the accumulation on fp32 806 self.assertAllCloseAccordingToType( 807 cpu_val, gpu_val, half_rtol=0.01, half_atol=0.01) 808 809 def _CompareMaxPoolingGradBk(self, input_shape, output_shape, ksize, strides, 810 padding): 811 for dtype in np.float64, np.float32, np.float16: 812 # Generate numbers in a narrow range, so that there are many duplicates 813 # in the input. 814 tensor_input = np.random.random_integers(0, 3, input_shape).astype(dtype) 815 with self.cached_session(use_gpu=False): 816 t = constant_op.constant(tensor_input, shape=input_shape) 817 _, argmax_op = nn_ops.max_pool_with_argmax(t, ksize, strides, padding) 818 argmax = self.evaluate(argmax_op) 819 grad_in = constant_op.constant(tensor_input, shape=input_shape) 820 out_op = gen_nn_ops.max_pool_grad_grad_with_argmax( 821 t, grad_in, argmax, ksize, strides, padding) 822 gpu_val = self.evaluate(out_op) 823 self.assertShapeEqual(gpu_val, out_op) 824 with self.cached_session(use_gpu=False): 825 t = constant_op.constant(tensor_input, shape=input_shape) 826 out_op = nn_ops.max_pool(t, ksize, strides, padding) 827 orig_out = self.evaluate(out_op) 828 grad_in = constant_op.constant(tensor_input, shape=input_shape) 829 out_op = gen_nn_ops.max_pool_grad_grad(t, orig_out, grad_in, ksize, 830 strides, padding) 831 cpu_val = self.evaluate(out_op) 832 self.assertShapeEqual(cpu_val, out_op) 833 # The CPU version accumulates its gradient on fp16, so it's less 834 # accurate than the GPU version that does the accumulation on fp32 835 self.assertAllCloseAccordingToType( 836 cpu_val, gpu_val, half_rtol=0.01, half_atol=0.01) 837 838 def testMaxPoolingWithArgmax(self): 839 tensor_input = [ 840 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 841 0.0, 1.0, 0.0, 1.0 842 ] 843 844 Config = collections.namedtuple( 845 "Config", ["use_gpu", "include_batch_in_index", "argmax"]) 846 configs = [ 847 Config(False, False, [0, 1, 3, 5, 0, 2, 6, 8]), 848 Config(False, True, [0, 1, 3, 5, 9, 11, 15, 17]), 849 Config(True, False, [0, 1, 3, 5, 0, 2, 6, 8]), 850 Config(True, True, [0, 1, 3, 5, 9, 11, 15, 17]) 851 ] 852 853 for config in configs: 854 with GetDeviceScope(self, use_gpu=config.use_gpu): 855 t = constant_op.constant(tensor_input, shape=[2, 3, 3, 1]) 856 out_op, argmax_op = nn_ops.max_pool_with_argmax( 857 t, 858 ksize=[1, 2, 2, 1], 859 strides=[1, 1, 1, 1], 860 Targmax=dtypes.int64, 861 padding="VALID", 862 include_batch_in_index=config.include_batch_in_index) 863 out, argmax = self.evaluate([out_op, argmax_op]) 864 self.assertShapeEqual(out, out_op) 865 self.assertShapeEqual(argmax, argmax_op) 866 self.assertAllClose(out.ravel(), 867 [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]) 868 self.assertAllEqual(argmax.ravel(), config.argmax) 869 870 def testMaxPoolingGradWithArgmax(self): 871 orig_input = [ 872 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 873 0.0, 1.0, 0.0, 1.0 874 ] 875 tensor_input = [11.0, 12.0, 13.0, 14.0, 21.0, 22.0, 23.0, 24.0] 876 877 Config = collections.namedtuple( 878 "Config", ["use_gpu", "include_batch_in_index", "argmax"]) 879 configs = [ 880 Config(False, False, [0, 1, 3, 5, 0, 2, 6, 8]), 881 Config(False, True, [0, 1, 3, 5, 9, 11, 15, 17]), 882 Config(True, False, [0, 1, 3, 5, 0, 2, 6, 8]), 883 Config(True, True, [0, 1, 3, 5, 9, 11, 15, 17]) 884 ] 885 886 for config in configs: 887 with GetDeviceScope(self, config.use_gpu): 888 orig_in = constant_op.constant(orig_input, shape=[2, 3, 3, 1]) 889 t = constant_op.constant(tensor_input, shape=[2, 2, 2, 1]) 890 argmax_t = constant_op.constant( 891 config.argmax, shape=[2, 2, 2, 1], dtype=dtypes.int64) 892 out_op = gen_nn_ops.max_pool_grad_with_argmax( 893 orig_in, 894 t, 895 argmax_t, 896 ksize=[1, 2, 2, 1], 897 strides=[1, 1, 1, 1], 898 padding="VALID", 899 include_batch_in_index=config.include_batch_in_index) 900 out = self.evaluate(out_op).flatten() 901 self.assertAllClose(out, [ 902 11.0, 12.0, 0.0, 13.0, 0.0, 14.0, 0.0, 0.0, 0.0, 21.0, 0.0, 22.0, 903 0.0, 0.0, 0.0, 23.0, 0.0, 24.0 904 ]) 905 906 def testMaxPoolingGradGradWithArgmax(self): 907 # MaxPoolWithArgMax is implemented only on CUDA. 908 if not test.is_gpu_available(cuda_only=True): 909 return 910 orig_input = [ 911 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 912 0.0, 1.0, 0.0, 1.0 913 ] 914 tensor_input = [ 915 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 21.0, 22.0, 23.0, 916 24.0, 25.0, 26.0, 27.0, 28.0, 29.0 917 ] 918 919 Config = collections.namedtuple( 920 "Config", ["use_gpu", "include_batch_in_index", "argmax"]) 921 configs = [ 922 Config(True, False, [0, 1, 3, 5, 0, 2, 6, 8]), 923 Config(True, True, [0, 1, 3, 5, 9, 11, 15, 17]) 924 ] 925 926 for config in configs: 927 with GetDeviceScope(self, config.use_gpu): 928 orig_in = constant_op.constant(orig_input, shape=[2, 3, 3, 1]) 929 t = constant_op.constant(tensor_input, shape=[2, 3, 3, 1]) 930 argmax_t = constant_op.constant( 931 config.argmax, shape=[2, 2, 2, 1], dtype=dtypes.int64) 932 out_op = gen_nn_ops.max_pool_grad_grad_with_argmax( 933 orig_in, 934 t, 935 argmax_t, 936 ksize=[1, 2, 2, 1], 937 strides=[1, 1, 1, 1], 938 padding="VALID", 939 include_batch_in_index=config.include_batch_in_index) 940 out = self.evaluate(out_op).flatten() 941 self.assertAllClose(out, 942 [11.0, 12.0, 14.0, 16.0, 21.0, 23.0, 27.0, 29.0]) 943 944 def _ConstructAndTestGradient(self, 945 pool_func, 946 input_sizes, 947 output_sizes, 948 window_rows, 949 window_cols, 950 row_stride, 951 col_stride, 952 padding, 953 data_format, 954 use_gpu, 955 x_init_value=None): 956 """Verifies the gradients of the avg pooling function. 957 958 Args: 959 pool_func: Function to be called, co.MaxPool, co.AvgPool, 960 or the Lua version. 961 input_sizes: Input tensor dimensions. 962 output_sizes: Output tensor dimensions. 963 window_rows: kernel size in row dim 964 window_cols: kernel size in col dim 965 row_stride: Row Stride. 966 col_stride: Col Stride. 967 padding: Padding type. 968 data_format: Data format. 969 use_gpu: whether we are running on GPU 970 x_init_value: Values to be passed to the gradient checker. 971 """ 972 assert input_sizes[0] == output_sizes[0] 973 assert input_sizes[3] == output_sizes[3] 974 total_size = 1 975 for s in input_sizes: 976 total_size *= s 977 # Initializes the input tensor with array containing incrementing 978 # numbers from 1. 979 x = [f * 1.0 for f in range(1, total_size + 1)] 980 with self.cached_session(use_gpu=use_gpu): 981 input_tensor = constant_op.constant(x, shape=input_sizes, name="input") 982 if pool_func == nn_ops.avg_pool: 983 func_name = "avg_pool" 984 err_tolerance = 1e-4 985 else: 986 if x_init_value is None: 987 x_init_value = np.asfarray( 988 np.arange(1, total_size + 1), 989 dtype=np.float32).reshape(input_sizes) 990 func_name = "max_pool" 991 err_tolerance = 1e-3 992 if data_format == "NCHW": 993 ksize = [1, 1, window_rows, window_rows] 994 strides = [1, 1, row_stride, col_stride] 995 t = test_util.NHWCToNCHW(input_tensor) 996 else: 997 ksize = [1, window_rows, window_rows, 1] 998 strides = [1, row_stride, col_stride, 1] 999 t = input_tensor 1000 t = pool_func( 1001 t, 1002 ksize=ksize, 1003 strides=strides, 1004 padding=padding, 1005 data_format=data_format, 1006 name=func_name) 1007 if data_format == "NCHW": 1008 t = test_util.NCHWToNHWC(t) 1009 1010 err = gradient_checker.compute_gradient_error( 1011 input_tensor, 1012 input_sizes, 1013 t, 1014 output_sizes, 1015 x_init_value=x_init_value, 1016 delta=1e-2) 1017 tf_logging.info("%s gradient error = " % func_name, err) 1018 self.assertLess(err, err_tolerance) 1019 1020 def _ConstructAndTestSecondGradient(self, 1021 pool_func, 1022 input_sizes, 1023 output_sizes, 1024 window_rows, 1025 window_cols, 1026 row_stride, 1027 col_stride, 1028 padding, 1029 data_format, 1030 use_gpu, 1031 x_init_value=None): 1032 """Verifies the second-order gradients of the pooling function. 1033 1034 Args: 1035 pool_func: Function to be called, co.MaxPool, co.AvgPool, 1036 or the Lua version. 1037 input_sizes: Input tensor dimensions. 1038 output_sizes: Output tensor dimensions. 1039 window_rows: kernel size in row dim 1040 window_cols: kernel size in col dim 1041 row_stride: Row Stride. 1042 col_stride: Col Stride. 1043 padding: Padding type. 1044 data_format: Data format. 1045 use_gpu: whether we are running on GPU 1046 x_init_value: Values to be passed to the gradient checker. 1047 """ 1048 assert input_sizes[0] == output_sizes[0] 1049 assert input_sizes[3] == output_sizes[3] 1050 total_size = 1 1051 for s in input_sizes: 1052 total_size *= s 1053 # Initializes the input tensor with array containing incrementing 1054 # numbers from 1. 1055 x = [f * 1.0 for f in range(1, total_size + 1)] 1056 with self.cached_session(use_gpu=use_gpu): 1057 input_tensor = constant_op.constant(x, shape=input_sizes, name="input") 1058 if pool_func == nn_ops.avg_pool: 1059 func_name = "avg_pool" 1060 err_tolerance = 1e-3 1061 else: 1062 if x_init_value is None: 1063 x_init_value = np.asfarray( 1064 np.arange(1, total_size + 1), 1065 dtype=np.float32).reshape(input_sizes) 1066 func_name = "max_pool" 1067 err_tolerance = 1e-2 1068 if data_format == "NCHW": 1069 ksize = [1, 1, window_rows, window_rows] 1070 strides = [1, 1, row_stride, col_stride] 1071 t = test_util.NHWCToNCHW(input_tensor) 1072 else: 1073 ksize = [1, window_rows, window_rows, 1] 1074 strides = [1, row_stride, col_stride, 1] 1075 t = input_tensor 1076 t = pool_func( 1077 t, 1078 ksize=ksize, 1079 strides=strides, 1080 padding=padding, 1081 data_format=data_format, 1082 name=func_name) 1083 if data_format == "NCHW": 1084 t = test_util.NHWCToNCHW(t) 1085 1086 t_g = gradients_impl.gradients(t**2, input_tensor)[0] 1087 err = gradient_checker.compute_gradient_error( 1088 input_tensor, 1089 input_sizes, 1090 t_g, 1091 input_sizes, 1092 x_init_value=x_init_value, 1093 delta=1e-2) 1094 tf_logging.info("%s second-order gradient error = " % func_name, err) 1095 self.assertLess(err, err_tolerance) 1096 1097 def _testMaxPoolGradValidPadding1_1(self, data_format, use_gpu): 1098 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1099 self._ConstructAndTestGradient( 1100 pool_func, 1101 input_sizes=[1, 3, 3, 1], 1102 output_sizes=[1, 3, 3, 1], 1103 window_rows=1, 1104 window_cols=1, 1105 row_stride=1, 1106 col_stride=1, 1107 padding="VALID", 1108 data_format=data_format, 1109 use_gpu=use_gpu) 1110 1111 def _testMaxPoolGradValidPadding2_1_6(self, data_format, use_gpu): 1112 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1113 self._ConstructAndTestGradient( 1114 pool_func, 1115 input_sizes=[2, 6, 6, 3], 1116 output_sizes=[2, 5, 5, 3], 1117 window_rows=2, 1118 window_cols=2, 1119 row_stride=1, 1120 col_stride=1, 1121 padding="VALID", 1122 data_format=data_format, 1123 use_gpu=use_gpu) 1124 1125 def _testMaxPoolGradValidPadding2_1_7(self, data_format, use_gpu): 1126 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1127 self._ConstructAndTestGradient( 1128 pool_func, 1129 input_sizes=[2, 7, 7, 3], 1130 output_sizes=[2, 6, 6, 3], 1131 window_rows=2, 1132 window_cols=2, 1133 row_stride=1, 1134 col_stride=1, 1135 padding="VALID", 1136 data_format=data_format, 1137 use_gpu=use_gpu) 1138 1139 def _testMaxPoolGradValidPadding1_2(self, data_format, use_gpu): 1140 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1141 self._ConstructAndTestGradient( 1142 pool_func, 1143 input_sizes=[1, 3, 3, 1], 1144 output_sizes=[1, 2, 2, 1], 1145 window_rows=1, 1146 window_cols=1, 1147 row_stride=2, 1148 col_stride=2, 1149 padding="VALID", 1150 data_format=data_format, 1151 use_gpu=use_gpu) 1152 1153 def _testMaxPoolGradValidPadding2_2(self, data_format, use_gpu): 1154 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1155 self._ConstructAndTestGradient( 1156 pool_func, 1157 input_sizes=[2, 2, 2, 3], 1158 output_sizes=[2, 1, 1, 3], 1159 window_rows=2, 1160 window_cols=2, 1161 row_stride=2, 1162 col_stride=2, 1163 padding="VALID", 1164 data_format=data_format, 1165 use_gpu=use_gpu) 1166 1167 def _testMaxPoolGradSamePadding1_1(self, data_format, use_gpu): 1168 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1169 self._ConstructAndTestGradient( 1170 pool_func, 1171 input_sizes=[2, 2, 4, 3], 1172 output_sizes=[2, 2, 4, 3], 1173 window_rows=1, 1174 window_cols=1, 1175 row_stride=1, 1176 col_stride=1, 1177 padding="SAME", 1178 data_format=data_format, 1179 use_gpu=use_gpu) 1180 1181 def _testMaxPoolGradSamePadding1_2(self, data_format, use_gpu): 1182 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1183 self._ConstructAndTestGradient( 1184 pool_func, 1185 input_sizes=[2, 2, 4, 3], 1186 output_sizes=[2, 1, 2, 3], 1187 window_rows=1, 1188 window_cols=1, 1189 row_stride=2, 1190 col_stride=2, 1191 padding="SAME", 1192 data_format=data_format, 1193 use_gpu=use_gpu) 1194 1195 def _testMaxPoolGradSamePadding2_1(self, data_format, use_gpu): 1196 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1197 self._ConstructAndTestGradient( 1198 pool_func, 1199 input_sizes=[2, 2, 4, 3], 1200 output_sizes=[2, 2, 4, 3], 1201 window_rows=2, 1202 window_cols=2, 1203 row_stride=1, 1204 col_stride=1, 1205 padding="SAME", 1206 data_format=data_format, 1207 use_gpu=use_gpu) 1208 1209 def _testMaxPoolGradSamePadding2_2(self, data_format, use_gpu): 1210 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1211 self._ConstructAndTestGradient( 1212 pool_func, 1213 input_sizes=[2, 2, 4, 3], 1214 output_sizes=[2, 1, 2, 3], 1215 window_rows=2, 1216 window_cols=2, 1217 row_stride=2, 1218 col_stride=2, 1219 padding="SAME", 1220 data_format=data_format, 1221 use_gpu=use_gpu) 1222 1223 def _testMaxPoolGradSamePadding3_1(self, data_format, use_gpu): 1224 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1225 self._ConstructAndTestGradient( 1226 pool_func, 1227 input_sizes=[1, 7, 7, 1], 1228 output_sizes=[1, 7, 7, 1], 1229 window_rows=3, 1230 window_cols=3, 1231 row_stride=1, 1232 col_stride=1, 1233 padding="SAME", 1234 data_format=data_format, 1235 use_gpu=use_gpu) 1236 1237 @test_util.run_deprecated_v1 1238 def testMaxPoolGrad(self): 1239 for (data_format, use_gpu) in GetTestConfigs(): 1240 self._testMaxPoolGradValidPadding1_1(data_format, use_gpu) 1241 self._testMaxPoolGradValidPadding1_2(data_format, use_gpu) 1242 self._testMaxPoolGradValidPadding2_1_6(data_format, use_gpu) 1243 self._testMaxPoolGradValidPadding2_1_7(data_format, use_gpu) 1244 self._testMaxPoolGradValidPadding2_2(data_format, use_gpu) 1245 self._testMaxPoolGradSamePadding1_1(data_format, use_gpu) 1246 self._testMaxPoolGradSamePadding1_2(data_format, use_gpu) 1247 self._testMaxPoolGradSamePadding2_1(data_format, use_gpu) 1248 self._testMaxPoolGradSamePadding2_2(data_format, use_gpu) 1249 self._testMaxPoolGradSamePadding3_1(data_format, use_gpu) 1250 1251 def _MaxPoolGrad(self, orig_input, orig_output, grad, window_rows, 1252 window_cols, row_stride, col_stride, padding, v2): 1253 """Max Pooling Gradient. 1254 1255 Args: 1256 orig_input: A float Tensor. The original input tensor. 1257 orig_output: A float Tensor. The original output tensor. 1258 grad: A float Tensor. 1259 The 4D (batch x rows x cols x depth) output backprop. 1260 window_rows: integer. Kernel size along rows dimension. 1261 window_cols: integer. Kernel size along cols dimension. 1262 row_stride: integer. Stride along rows dimension 1263 col_stride: integer. Stride along cols dimension 1264 padding: PoolingOpDef.Padding. Padding type. 1265 1266 Returns: 1267 A Tensor. 1268 """ 1269 pool_func = gen_nn_ops.max_pool_grad_v2 if v2 else gen_nn_ops.max_pool_grad 1270 return pool_func(orig_input, orig_output, grad, 1271 [1, window_rows, window_cols, 1], 1272 [1, row_stride, col_stride, 1], padding) 1273 1274 def _testMaxPoolGradDirect(self, input_data, output_backprop, 1275 expected_input_backprop, input_sizes, output_sizes, 1276 window_rows, window_cols, row_stride, col_stride, 1277 padding, use_gpu, v2): 1278 pool_func = gen_nn_ops.max_pool_v2 if v2 else nn_ops.max_pool 1279 with self.cached_session(use_gpu=use_gpu): 1280 input_tensor = variables.Variable( 1281 np.array(input_data, dtype=np.float32).reshape(input_sizes)) 1282 self.evaluate(variables.global_variables_initializer()) 1283 output_tensor = pool_func(input_tensor, [1, window_rows, window_cols, 1], 1284 [1, row_stride, col_stride, 1], padding) 1285 output_backprop_tensor = constant_op.constant( 1286 output_backprop, shape=output_sizes) 1287 1288 input_backprop_tensor = self._MaxPoolGrad( 1289 input_tensor, output_tensor, output_backprop_tensor, window_rows, 1290 window_cols, row_stride, col_stride, padding, v2) 1291 1292 actual_input_backprop = self.evaluate(input_backprop_tensor) 1293 self.assertShapeEqual(actual_input_backprop, input_backprop_tensor) 1294 actual_input_backprop = actual_input_backprop.flatten() 1295 actual_input_backprop = self._GetNdArray(actual_input_backprop) 1296 1297 actual_output = self.evaluate(output_tensor).flatten() 1298 actual_output = self._GetNdArray(actual_output) 1299 1300 self.assertAllClose( 1301 expected_input_backprop, actual_input_backprop, rtol=1e-6, atol=1e-6) 1302 1303 def _testMaxPoolGradDirect1_1(self): 1304 input_data = [ 1305 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1306 1.0, 1.0 1307 ] 1308 output_backprop = [11.0, 12.0, 13.0, 15.0, 16.0, 17.0, 19.0, 20.0, 21.0] 1309 expected_input_backprop = [ 1310 11.0, 12.0, 13.0, 0.0, 15.0, 16.0, 17.0, 0.0, 19.0, 20.0, 21.0, 0.0, 1311 0.0, 0.0, 0.0, 0.0 1312 ] 1313 1314 for use_gpu in True, False: 1315 for v2 in [True, False]: 1316 self._testMaxPoolGradDirect( 1317 input_data, 1318 output_backprop, 1319 expected_input_backprop, 1320 input_sizes=[1, 4, 4, 1], 1321 output_sizes=[1, 3, 3, 1], 1322 window_rows=2, 1323 window_cols=2, 1324 row_stride=1, 1325 col_stride=1, 1326 padding="VALID", 1327 use_gpu=use_gpu, 1328 v2=v2) 1329 1330 def _testMaxPoolGradDirect1_2(self): 1331 input_data = [ 1332 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1333 0.0, 1.0 1334 ] 1335 output_backprop = [11.0, 12.0, 13.0, 15.0, 16.0, 17.0, 19.0, 20.0, 21.0] 1336 expected_input_backprop = [ 1337 11.0, 0.0, 25.0, 0.0, 0.0, 31.0, 0.0, 17.0, 19.0, 0.0, 41.0, 0.0, 0.0, 1338 0.0, 0.0, 0.0 1339 ] 1340 1341 for use_gpu in True, False: 1342 for v2 in [True, False]: 1343 self._testMaxPoolGradDirect( 1344 input_data, 1345 output_backprop, 1346 expected_input_backprop, 1347 input_sizes=[1, 4, 4, 1], 1348 output_sizes=[1, 3, 3, 1], 1349 window_rows=2, 1350 window_cols=2, 1351 row_stride=1, 1352 col_stride=1, 1353 padding="VALID", 1354 use_gpu=use_gpu, 1355 v2=v2) 1356 1357 def _testMaxPoolGradDirect1_3(self): 1358 input_data = [ 1359 1.0, 1360 0.0, 1361 1.0, 1362 0.0, 1363 0.0, 1364 1.0, 1365 0.0, 1366 1.0, 1367 1.0, 1368 0.0, 1369 1.0, 1370 0.0, 1371 0.0, 1372 1.0, 1373 0.0, 1374 1.0, 1375 ] 1376 output_backprop = [ 1377 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 1378 23.0, 24.0, 25.0, 26.0 1379 ] 1380 expected_input_backprop = [ 1381 54, 1382 0.0, 1383 62, 1384 0.0, 1385 0.0, 1386 60, 1387 0.0, 1388 22.0, 1389 47, 1390 0.0, 1391 51, 1392 0.0, 1393 0.0, 1394 0.0, 1395 0.0, 1396 0.0, 1397 ] 1398 1399 for use_gpu in True, False: 1400 for v2 in [True, False]: 1401 self._testMaxPoolGradDirect( 1402 input_data, 1403 output_backprop, 1404 expected_input_backprop, 1405 input_sizes=[1, 4, 4, 1], 1406 output_sizes=[1, 4, 4, 1], 1407 window_rows=3, 1408 window_cols=3, 1409 row_stride=1, 1410 col_stride=1, 1411 padding="SAME", 1412 use_gpu=use_gpu, 1413 v2=v2) 1414 1415 @test_util.disable_xla("b/123923733") # NaNs handled differently 1416 def _testMaxPoolGradDirectWithNans2_1(self): 1417 input_data = [float("nan")] * 16 1418 output_backprop = [11.0, 12.0, 13.0, 15.0, 16.0, 17.0, 19.0, 20.0, 21.0] 1419 # Test the CPU implementation, which propagates diffs in case of NaN 1420 expected_input_backprop_tf_cpu = [ 1421 11.0, 12.0, 13.0, 0.0, 15.0, 16.0, 17.0, 0.0, 19.0, 20.0, 21.0, 0.0, 1422 0.0, 0.0, 0.0, 0.0 1423 ] 1424 for v2 in [True, False]: 1425 self._testMaxPoolGradDirect( 1426 input_data, 1427 output_backprop, 1428 expected_input_backprop_tf_cpu, 1429 input_sizes=[1, 4, 4, 1], 1430 output_sizes=[1, 3, 3, 1], 1431 window_rows=2, 1432 window_cols=2, 1433 row_stride=1, 1434 col_stride=1, 1435 padding="VALID", 1436 use_gpu=False, 1437 v2=v2) 1438 1439 if not test.is_gpu_available(): 1440 return 1441 1442 # Test the GPU implementation that uses cudnn for now. 1443 saved_nanprop = os.environ.get("TF_ENABLE_MAXPOOL_NANPROP") 1444 # Do not propagate the diff in cases of NaNs 1445 os.environ["TF_ENABLE_MAXPOOL_NANPROP"] = "0" 1446 expected_input_backprop_cudnn = [ 1447 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1448 0.0, 0.0 1449 ] 1450 1451 for v2 in [True, False]: 1452 self._testMaxPoolGradDirect( 1453 input_data, 1454 output_backprop, 1455 expected_input_backprop_cudnn, 1456 input_sizes=[1, 4, 4, 1], 1457 output_sizes=[1, 3, 3, 1], 1458 window_rows=2, 1459 window_cols=2, 1460 row_stride=1, 1461 col_stride=1, 1462 padding="VALID", 1463 use_gpu=True, 1464 v2=v2) 1465 1466 # Propagate the diff in cases of NaNs 1467 os.environ["TF_ENABLE_MAXPOOL_NANPROP"] = "1" 1468 expected_input_backprop_cudnn = expected_input_backprop_tf_cpu 1469 1470 for v2 in [True, False]: 1471 self._testMaxPoolGradDirect( 1472 input_data, 1473 output_backprop, 1474 expected_input_backprop_cudnn, 1475 input_sizes=[1, 4, 4, 1], 1476 output_sizes=[1, 3, 3, 1], 1477 window_rows=2, 1478 window_cols=2, 1479 row_stride=1, 1480 col_stride=1, 1481 padding="VALID", 1482 use_gpu=True, 1483 v2=v2) 1484 1485 if saved_nanprop: 1486 os.environ["TF_ENABLE_MAXPOOL_NANPROP"] = saved_nanprop 1487 else: 1488 del os.environ["TF_ENABLE_MAXPOOL_NANPROP"] 1489 1490 @test_util.disable_xla("b/123923733") # NaNs handled differently 1491 def _testMaxPoolGradDirectWithNans2_2(self): 1492 input_data = [float("nan")] * 16 1493 output_backprop = [ 1494 float("nan"), 12.0, 13.0, 15.0, 1495 float("nan"), 17.0, 19.0, 20.0, 1496 float("nan") 1497 ] 1498 # Test the CPU implementation, which propagates diffs in case of NaN 1499 expected_input_backprop_tf_cpu = [ 1500 float("nan"), 12.0, 13.0, 0.0, 15.0, 1501 float("nan"), 17.0, 0.0, 19.0, 20.0, 1502 float("nan"), 0.0, 0.0, 0.0, 0.0, 0.0 1503 ] 1504 for v2 in [True, False]: 1505 self._testMaxPoolGradDirect( 1506 input_data, 1507 output_backprop, 1508 expected_input_backprop_tf_cpu, 1509 input_sizes=[1, 4, 4, 1], 1510 output_sizes=[1, 3, 3, 1], 1511 window_rows=2, 1512 window_cols=2, 1513 row_stride=1, 1514 col_stride=1, 1515 padding="VALID", 1516 use_gpu=False, 1517 v2=v2) 1518 1519 if not test.is_gpu_available(): 1520 return 1521 1522 # Test the GPU implementation that uses cudnn for now. 1523 saved_nanprop = os.environ.get("TF_ENABLE_MAXPOOL_NANPROP") 1524 # Do not propagate the diff in cases of NaNs 1525 os.environ["TF_ENABLE_MAXPOOL_NANPROP"] = "0" 1526 expected_input_backprop_cudnn = [ 1527 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1528 0.0, 0.0 1529 ] 1530 1531 for v2 in [True, False]: 1532 self._testMaxPoolGradDirect( 1533 input_data, 1534 output_backprop, 1535 expected_input_backprop_cudnn, 1536 input_sizes=[1, 4, 4, 1], 1537 output_sizes=[1, 3, 3, 1], 1538 window_rows=2, 1539 window_cols=2, 1540 row_stride=1, 1541 col_stride=1, 1542 padding="VALID", 1543 use_gpu=True, 1544 v2=v2) 1545 1546 # Propagate the diff in cases of NaNs 1547 os.environ["TF_ENABLE_MAXPOOL_NANPROP"] = "1" 1548 expected_input_backprop_cudnn = expected_input_backprop_tf_cpu 1549 1550 for v2 in [True, False]: 1551 self._testMaxPoolGradDirect( 1552 input_data, 1553 output_backprop, 1554 expected_input_backprop_cudnn, 1555 input_sizes=[1, 4, 4, 1], 1556 output_sizes=[1, 3, 3, 1], 1557 window_rows=2, 1558 window_cols=2, 1559 row_stride=1, 1560 col_stride=1, 1561 padding="VALID", 1562 use_gpu=True, 1563 v2=v2) 1564 1565 if saved_nanprop: 1566 os.environ["TF_ENABLE_MAXPOOL_NANPROP"] = saved_nanprop 1567 else: 1568 del os.environ["TF_ENABLE_MAXPOOL_NANPROP"] 1569 1570 @test_util.run_deprecated_v1 1571 def testMaxPoolGradDirect(self): 1572 self._testMaxPoolGradDirect1_1() 1573 self._testMaxPoolGradDirect1_2() 1574 self._testMaxPoolGradDirect1_3() 1575 self._testMaxPoolGradDirectWithNans2_1() 1576 self._testMaxPoolGradDirectWithNans2_2() 1577 1578 def _testMaxPoolGradGradValidPadding1_1(self, data_format, use_gpu): 1579 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1580 self._ConstructAndTestSecondGradient( 1581 pool_func, 1582 input_sizes=[1, 3, 3, 1], 1583 output_sizes=[1, 3, 3, 1], 1584 window_rows=1, 1585 window_cols=1, 1586 row_stride=1, 1587 col_stride=1, 1588 padding="VALID", 1589 data_format=data_format, 1590 use_gpu=use_gpu) 1591 1592 def _testMaxPoolGradGradValidPadding2_1_6(self, data_format, use_gpu): 1593 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1594 self._ConstructAndTestSecondGradient( 1595 pool_func, 1596 input_sizes=[2, 6, 6, 3], 1597 output_sizes=[2, 5, 5, 3], 1598 window_rows=2, 1599 window_cols=2, 1600 row_stride=1, 1601 col_stride=1, 1602 padding="VALID", 1603 data_format=data_format, 1604 use_gpu=use_gpu) 1605 1606 def _testMaxPoolGradGradValidPadding2_1_7(self, data_format, use_gpu): 1607 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1608 self._ConstructAndTestSecondGradient( 1609 pool_func, 1610 input_sizes=[2, 7, 7, 3], 1611 output_sizes=[2, 6, 6, 3], 1612 window_rows=2, 1613 window_cols=2, 1614 row_stride=1, 1615 col_stride=1, 1616 padding="VALID", 1617 data_format=data_format, 1618 use_gpu=use_gpu) 1619 1620 def _testMaxPoolGradGradValidPadding2_2(self, data_format, use_gpu): 1621 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1622 self._ConstructAndTestSecondGradient( 1623 pool_func, 1624 input_sizes=[2, 2, 2, 3], 1625 output_sizes=[2, 1, 1, 3], 1626 window_rows=2, 1627 window_cols=2, 1628 row_stride=2, 1629 col_stride=2, 1630 padding="VALID", 1631 data_format=data_format, 1632 use_gpu=use_gpu) 1633 1634 def _testMaxPoolGradGradSamePadding1_1(self, data_format, use_gpu): 1635 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1636 self._ConstructAndTestSecondGradient( 1637 pool_func, 1638 input_sizes=[2, 2, 4, 3], 1639 output_sizes=[2, 2, 4, 3], 1640 window_rows=1, 1641 window_cols=1, 1642 row_stride=1, 1643 col_stride=1, 1644 padding="SAME", 1645 data_format=data_format, 1646 use_gpu=use_gpu) 1647 1648 def _testMaxPoolGradGradSamePadding2_1(self, data_format, use_gpu): 1649 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1650 self._ConstructAndTestSecondGradient( 1651 pool_func, 1652 input_sizes=[2, 2, 4, 3], 1653 output_sizes=[2, 2, 4, 3], 1654 window_rows=2, 1655 window_cols=2, 1656 row_stride=1, 1657 col_stride=1, 1658 padding="SAME", 1659 data_format=data_format, 1660 use_gpu=use_gpu) 1661 1662 def _testMaxPoolGradGradSamePadding2_2(self, data_format, use_gpu): 1663 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1664 self._ConstructAndTestSecondGradient( 1665 pool_func, 1666 input_sizes=[2, 2, 4, 3], 1667 output_sizes=[2, 1, 2, 3], 1668 window_rows=2, 1669 window_cols=2, 1670 row_stride=2, 1671 col_stride=2, 1672 padding="SAME", 1673 data_format=data_format, 1674 use_gpu=use_gpu) 1675 1676 def _testMaxPoolGradGradSamePadding3_1(self, data_format, use_gpu): 1677 for pool_func in [gen_nn_ops.max_pool_v2, nn_ops.max_pool]: 1678 self._ConstructAndTestSecondGradient( 1679 pool_func, 1680 input_sizes=[1, 7, 7, 1], 1681 output_sizes=[1, 7, 7, 1], 1682 window_rows=3, 1683 window_cols=3, 1684 row_stride=1, 1685 col_stride=1, 1686 padding="SAME", 1687 data_format=data_format, 1688 use_gpu=use_gpu) 1689 1690 @test_util.run_deprecated_v1 1691 def testMaxPoolGradGrad(self): 1692 for (data_format, use_gpu) in GetTestConfigs(): 1693 self._testMaxPoolGradGradValidPadding1_1(data_format, use_gpu) 1694 self._testMaxPoolGradGradValidPadding2_1_6(data_format, use_gpu) 1695 self._testMaxPoolGradGradValidPadding2_1_7(data_format, use_gpu) 1696 self._testMaxPoolGradGradValidPadding2_2(data_format, use_gpu) 1697 self._testMaxPoolGradGradSamePadding1_1(data_format, use_gpu) 1698 self._testMaxPoolGradGradSamePadding2_1(data_format, use_gpu) 1699 self._testMaxPoolGradGradSamePadding2_2(data_format, use_gpu) 1700 self._testMaxPoolGradGradSamePadding3_1(data_format, use_gpu) 1701 1702 def _MaxPoolGradGrad(self, orig_input, orig_output, grad, window_rows, 1703 window_cols, row_stride, col_stride, padding): 1704 """Max Pooling Second-Order Gradient. 1705 1706 Args: 1707 orig_input: A float Tensor. The original input tensor. 1708 orig_output: A float Tensor. The original output tensor. 1709 grad: A float Tensor. 1710 The 4D (batch x out_rows x out_cols x depth) output backprop. 1711 window_rows: integer. Kernel size along rows dimension. 1712 window_cols: integer. Kernel size along cols dimension. 1713 row_stride: integer. Stride along rows dimension 1714 col_stride: integer. Stride along cols dimension 1715 padding: PoolingOpDef.Padding. Padding type. 1716 1717 Returns: 1718 A Tensor. 1719 """ 1720 return gen_nn_ops.max_pool_grad_grad( 1721 orig_input, orig_output, grad, [1, window_rows, window_cols, 1], 1722 [1, row_stride, col_stride, 1], padding) 1723 1724 @test_util.run_deprecated_v1 1725 def testAvgPoolGrad(self): 1726 for (data_format, use_gpu) in GetTestConfigs(): 1727 self._testAvgPoolGradValidPadding1_1(data_format, use_gpu) 1728 self._testAvgPoolGradValidPadding1_2(data_format, use_gpu) 1729 self._testAvgPoolGradValidPadding2_1(data_format, use_gpu) 1730 self._testAvgPoolGradValidPadding2_2(data_format, use_gpu) 1731 self._testAvgPoolGradSamePadding1_1(data_format, use_gpu) 1732 self._testAvgPoolGradSamePadding1_2(data_format, use_gpu) 1733 self._testAvgPoolGradSamePadding2_1(data_format, use_gpu) 1734 self._testAvgPoolGradSamePadding2_2(data_format, use_gpu) 1735 self._testAvgPoolGradSamePadding3_1(data_format, use_gpu) 1736 1737 def _testAvgPoolGradValidPadding1_1(self, data_format, use_gpu): 1738 self._ConstructAndTestGradient( 1739 nn_ops.avg_pool, 1740 input_sizes=[2, 3, 3, 3], 1741 output_sizes=[2, 3, 3, 3], 1742 window_rows=1, 1743 window_cols=1, 1744 row_stride=1, 1745 col_stride=1, 1746 padding="VALID", 1747 data_format=data_format, 1748 use_gpu=use_gpu) 1749 1750 def _testAvgPoolGradValidPadding1_2(self, data_format, use_gpu): 1751 self._ConstructAndTestGradient( 1752 nn_ops.avg_pool, 1753 input_sizes=[2, 3, 3, 3], 1754 output_sizes=[2, 2, 2, 3], 1755 window_rows=1, 1756 window_cols=1, 1757 row_stride=2, 1758 col_stride=2, 1759 padding="VALID", 1760 data_format=data_format, 1761 use_gpu=use_gpu) 1762 1763 def _testAvgPoolGradValidPadding2_1(self, data_format, use_gpu): 1764 self._ConstructAndTestGradient( 1765 nn_ops.avg_pool, 1766 input_sizes=[2, 3, 3, 3], 1767 output_sizes=[2, 2, 2, 3], 1768 window_rows=2, 1769 window_cols=2, 1770 row_stride=1, 1771 col_stride=1, 1772 padding="VALID", 1773 data_format=data_format, 1774 use_gpu=use_gpu) 1775 1776 def _testAvgPoolGradValidPadding2_2(self, data_format, use_gpu): 1777 self._ConstructAndTestGradient( 1778 nn_ops.avg_pool, 1779 input_sizes=[2, 2, 2, 3], 1780 output_sizes=[2, 1, 1, 3], 1781 window_rows=2, 1782 window_cols=2, 1783 row_stride=2, 1784 col_stride=2, 1785 padding="VALID", 1786 data_format=data_format, 1787 use_gpu=use_gpu) 1788 1789 def _testAvgPoolGradSamePadding1_1(self, data_format, use_gpu): 1790 self._ConstructAndTestGradient( 1791 nn_ops.avg_pool, 1792 input_sizes=[2, 2, 4, 3], 1793 output_sizes=[2, 2, 4, 3], 1794 window_rows=1, 1795 window_cols=1, 1796 row_stride=1, 1797 col_stride=1, 1798 padding="SAME", 1799 data_format=data_format, 1800 use_gpu=use_gpu) 1801 1802 def _testAvgPoolGradSamePadding1_2(self, data_format, use_gpu): 1803 self._ConstructAndTestGradient( 1804 nn_ops.avg_pool, 1805 input_sizes=[2, 2, 4, 3], 1806 output_sizes=[2, 1, 2, 3], 1807 window_rows=1, 1808 window_cols=1, 1809 row_stride=2, 1810 col_stride=2, 1811 padding="SAME", 1812 data_format=data_format, 1813 use_gpu=use_gpu) 1814 1815 def _testAvgPoolGradSamePadding2_1(self, data_format, use_gpu): 1816 self._ConstructAndTestGradient( 1817 nn_ops.avg_pool, 1818 input_sizes=[2, 2, 4, 3], 1819 output_sizes=[2, 2, 4, 3], 1820 window_rows=2, 1821 window_cols=2, 1822 row_stride=1, 1823 col_stride=1, 1824 padding="SAME", 1825 data_format=data_format, 1826 use_gpu=use_gpu) 1827 1828 def _testAvgPoolGradSamePadding2_2(self, data_format, use_gpu): 1829 self._ConstructAndTestGradient( 1830 nn_ops.avg_pool, 1831 input_sizes=[2, 2, 4, 3], 1832 output_sizes=[2, 1, 2, 3], 1833 window_rows=2, 1834 window_cols=2, 1835 row_stride=2, 1836 col_stride=2, 1837 padding="SAME", 1838 data_format=data_format, 1839 use_gpu=use_gpu) 1840 1841 def _testAvgPoolGradSamePadding3_1(self, data_format, use_gpu): 1842 self._ConstructAndTestGradient( 1843 nn_ops.avg_pool, 1844 input_sizes=[1, 7, 7, 1], 1845 output_sizes=[1, 7, 7, 1], 1846 window_rows=3, 1847 window_cols=3, 1848 row_stride=1, 1849 col_stride=1, 1850 padding="SAME", 1851 data_format=data_format, 1852 use_gpu=use_gpu) 1853 1854 @test_util.run_deprecated_v1 1855 def testShapeFunctionEdgeCases(self): 1856 # All shapes unknown. 1857 for pool_func in [nn_ops.max_pool, nn_ops.avg_pool]: 1858 p = pool_func( 1859 array_ops.placeholder(dtypes.float32), 1860 ksize=[1, 1, 1, 1], 1861 strides=[1, 1, 1, 1], 1862 padding="SAME") 1863 self.assertEqual([None, None, None, None], p.get_shape().as_list()) 1864 p, am = nn_ops.max_pool_with_argmax( 1865 array_ops.placeholder(dtypes.float32), 1866 ksize=[1, 1, 1, 1], 1867 strides=[1, 1, 1, 1], 1868 padding="SAME") 1869 self.assertEqual([None, None, None, None], p.get_shape().as_list()) 1870 self.assertEqual([None, None, None, None], am.get_shape().as_list()) 1871 1872 # Incorrect input shape. 1873 for pool_func in [ 1874 nn_ops.max_pool, nn_ops.avg_pool, nn_ops.max_pool_with_argmax 1875 ]: 1876 with self.assertRaises(ValueError): 1877 pool_func( 1878 array_ops.placeholder(dtypes.float32, shape=[1, 3]), 1879 ksize=[1, 1, 1, 1], 1880 strides=[1, 1, 1, 1], 1881 padding="SAME") 1882 1883 @test_util.run_deprecated_v1 1884 @test_util.disable_xla("b/123337890") # Error messages differ 1885 def testOpEdgeCases(self): 1886 with self.session(use_gpu=test.is_gpu_available()) as sess: 1887 pool_funcs = [nn_ops.max_pool, nn_ops.avg_pool] 1888 if test.is_gpu_available(): 1889 pool_funcs.append(nn_ops.max_pool_with_argmax) 1890 for pool_func in pool_funcs: 1891 if pool_func != nn_ops.max_pool: 1892 # Illegal strides. 1893 with self.assertRaisesRegexp( 1894 errors_impl.UnimplementedError, 1895 "Pooling is not yet supported on the batch"): 1896 sess.run( 1897 pool_func( 1898 array_ops.placeholder(dtypes.float32), 1899 ksize=[1, 1, 1, 1], 1900 strides=[2, 1, 1, 1], 1901 padding="SAME")) 1902 1903 # Filter too large. 1904 with self.assertRaisesRegexp(ValueError, "Negative dimension size"): 1905 sess.run( 1906 pool_func( 1907 array_ops.placeholder(dtypes.float32, shape=[32, 20, 20, 3]), 1908 ksize=[1, 20, 21, 1], 1909 strides=[1, 1, 1, 1], 1910 padding="VALID")) 1911 with self.assertRaisesRegexp(ValueError, "Negative dimension size"): 1912 pool_func( 1913 array_ops.placeholder(dtypes.float32, shape=[32, 20, 20, 3]), 1914 ksize=[1, 21, 20, 1], 1915 strides=[1, 1, 1, 1], 1916 padding="VALID") 1917 1918 1919def GetMaxPoolFwdTest(input_size, filter_size, strides, padding): 1920 1921 def Test(self): 1922 # MaxPoolWithArgMax is implemented only on CUDA. 1923 if not test.is_gpu_available(cuda_only=True): 1924 return 1925 self._CompareMaxPoolingFwd(input_size, filter_size, strides, padding) 1926 1927 return Test 1928 1929 1930def GetMaxPoolGradTest(input_size, filter_size, output_size, strides, padding): 1931 1932 def Test(self): 1933 # MaxPoolWithArgMax is implemented only on CUDA. 1934 if not test.is_gpu_available(cuda_only=True): 1935 return 1936 self._CompareMaxPoolingBk(input_size, output_size, filter_size, strides, 1937 padding) 1938 1939 return Test 1940 1941 1942def GetMaxPoolGradGradTest(input_size, filter_size, output_size, strides, 1943 padding): 1944 1945 def Test(self): 1946 # MaxPoolWithArgMax is implemented only on CUDA. 1947 if not test.is_gpu_available(cuda_only=True): 1948 return 1949 self._CompareMaxPoolingGradBk(input_size, output_size, filter_size, strides, 1950 padding) 1951 1952 return Test 1953 1954 1955if __name__ == "__main__": 1956 for (name_, input_size_, filter_size_, output_size_, stride_, 1957 padding_) in GetShrunkInceptionMaxPoolShapes(): 1958 setattr(PoolingTest, "testMaxPoolFwd_" + name_, 1959 GetMaxPoolFwdTest(input_size_, filter_size_, stride_, padding_)) 1960 setattr(PoolingTest, "testMaxPoolGrad_" + name_, 1961 GetMaxPoolGradTest(input_size_, filter_size_, output_size_, stride_, 1962 padding_)) 1963 setattr(PoolingTest, "testMaxPoolGradGrad_" + name_, 1964 GetMaxPoolGradGradTest(input_size_, filter_size_, output_size_, 1965 stride_, padding_)) 1966 test.main() 1967