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