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