pooling_ops_test.py revision bed8383c27a0a7225e6fc7ff59a2cd6388fb4d09
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 numpy as np 22 23from tensorflow.python.framework import constant_op 24from tensorflow.python.framework import dtypes 25from tensorflow.python.framework import errors_impl 26from tensorflow.python.framework import ops 27from tensorflow.python.framework import test_util 28from tensorflow.python.ops import array_ops 29from tensorflow.python.ops import gen_nn_ops 30from tensorflow.python.ops import gradient_checker 31from tensorflow.python.ops import nn_ops 32import tensorflow.python.ops.nn_grad # pylint: disable=unused-import 33from tensorflow.python.platform import test 34 35 36def NHWCToNCHW(input_tensor): 37 """Convert the input from NHWC format to NCHW. 38 39 Args: 40 input_tensor: a 4-D tensor, or a 4-element array representing the same. 41 42 Returns: 43 the converted tensor or a shape array 44 """ 45 if isinstance(input_tensor, ops.Tensor): 46 return array_ops.transpose(input_tensor, [0, 3, 1, 2]) 47 else: 48 return [input_tensor[0], input_tensor[3], input_tensor[1], input_tensor[2]] 49 50 51def NCHWToNHWC(input_tensor): 52 """Convert the input from NCHW format to NHWC. 53 54 Args: 55 input_tensor: a 4-D tensor, or a 4-element array representing the same. 56 57 Returns: 58 the converted tensor or a shape array 59 """ 60 if isinstance(input_tensor, ops.Tensor): 61 return array_ops.transpose(input_tensor, [0, 2, 3, 1]) 62 else: 63 return [input_tensor[0], input_tensor[2], input_tensor[3], input_tensor[1]] 64 65 66def GetTestConfigs(): 67 """Get all the valid tests configs to run. 68 69 Returns: 70 all the valid test configs as tuples of data_format and use_gpu. 71 """ 72 test_configs = [("NHWC", False), ("NHWC", True)] 73 if test.is_gpu_available(cuda_only=True): 74 # "NCHW" format is currently supported exclusively on CUDA GPUs. 75 test_configs += [("NCHW", True)] 76 return test_configs 77 78 79def GetShrunkInceptionMaxPoolShapes(shrink=30): 80 """Iterator for some of the max pool ops in the Inception 2015 model. 81 82 Args: 83 shrink: Factor to shrink depth relative to Inception. 84 85 Yields: 86 Tuple (name, input_size, filter_size, out_size, strides, padding) 87 """ 88 names = ["maxpool2", "maxpool3", "maxpool4", "maxpool5"] 89 input_sizes = [[32, 71, 71, 192], [32, 35, 35, 288], [32, 17, 17, 1248], 90 [32, 8, 8, 2048]] 91 filter_sizes = [[1, 3, 3, 1], [1, 3, 3, 1], [1, 3, 3, 1], [1, 3, 3, 1]] 92 output_sizes = [[32, 35, 35, 192], [32, 17, 17, 288], [32, 8, 8, 1248], 93 [32, 8, 8, 2048]] 94 strides = [[1, 2, 2, 1], [1, 2, 2, 1], [1, 2, 2, 1], [1, 1, 1, 1]] 95 # Shrink each depth value 96 for i in input_sizes: 97 i[3] //= shrink 98 for o in output_sizes: 99 o[3] //= shrink 100 paddings = ["VALID", "VALID", "VALID", "SAME"] 101 for n, i, f, o, s, p in zip(names, input_sizes, filter_sizes, output_sizes, 102 strides, paddings): 103 yield n, i, f, o, s, p 104 105 106class PoolingTest(test.TestCase): 107 108 def _VerifyOneType(self, pool_func, input_sizes, ksize, strides, padding, 109 data_format, data_type, expected, use_gpu): 110 """Verifies the output values of the pooling function. 111 112 Args: 113 pool_func: Function to be called, co.MaxPool, co.AvgPool, 114 or the Lua version. 115 input_sizes: Input tensor dimensions. 116 ksize: The kernel size dimensions 117 strides: The stride dimensions 118 padding: Padding type. 119 data_format: The data format we use to run the pooling operation. 120 data_type: The data type to use to run the pooling operation. 121 expected: An array containing the expected operation outputs. 122 use_gpu: Whether we are running on GPU. 123 """ 124 total_size = 1 125 for s in input_sizes: 126 total_size *= s 127 # Initializes the input tensor with array containing incrementing 128 # numbers from 1. 129 x = [f * 1.0 for f in range(1, total_size + 1)] 130 with self.test_session(use_gpu=use_gpu) as sess: 131 t = constant_op.constant(x, shape=input_sizes, dtype=data_type) 132 if data_format == "NCHW": 133 t = NHWCToNCHW(t) 134 ksize = NHWCToNCHW(ksize) 135 strides = NHWCToNCHW(strides) 136 t = pool_func( 137 t, 138 ksize=ksize, 139 strides=strides, 140 padding=padding, 141 data_format=data_format) 142 if data_format == "NCHW": 143 t = NCHWToNHWC(t) 144 actual = t.eval() 145 self.assertAllCloseAccordingToType(expected, actual.flatten()) 146 self.assertShapeEqual(actual, t) 147 148 def _VerifyOneTest(self, pool_func, input_sizes, ksize, strides, padding, 149 data_format, expected, use_gpu): 150 """Verifies the output values of the pooling function. 151 152 Args: 153 pool_func: Function to be called, co.MaxPool, co.AvgPool, 154 or the Lua version. 155 input_sizes: Input tensor dimensions. 156 ksize: The kernel size dimensions 157 strides: The stride dimensions 158 padding: Padding type. 159 data_format: The data format we use to run the pooling operation. 160 expected: An array containing the expected operation outputs. 161 use_gpu: Whether we are running on GPU. 162 """ 163 self._VerifyOneType(pool_func, input_sizes, ksize, strides, padding, 164 data_format, dtypes.float32, expected, use_gpu) 165 166 if not use_gpu or test_util.CudaSupportsHalfMatMulAndConv(): 167 self._VerifyOneType(pool_func, input_sizes, ksize, strides, padding, 168 data_format, dtypes.float16, expected, use_gpu) 169 170 def _VerifyValues(self, pool_func, input_sizes, ksize, strides, padding, 171 expected, use_gpu): 172 """Verifies the output values of the pooling function. 173 174 Args: 175 pool_func: Function to be called, co.MaxPool, co.AvgPool, 176 or the Lua version. 177 input_sizes: Input tensor dimensions. 178 ksize: The kernel size dimensions 179 strides: The stride dimensions 180 padding: Padding type. 181 expected: An array containing the expected operation outputs. 182 use_gpu: Whether we are running on GPU. 183 """ 184 for (data_format, use_gpu_2) in GetTestConfigs(): 185 if use_gpu_2 == use_gpu: 186 self._VerifyOneTest(pool_func, input_sizes, ksize, strides, padding, 187 data_format, expected, use_gpu) 188 189 def _testAvgPoolValidPadding(self, use_gpu): 190 expected_output = [7.0, 8.0, 9.0] 191 self._VerifyValues( 192 nn_ops.avg_pool, 193 input_sizes=[1, 3, 3, 3], 194 ksize=[1, 2, 2, 1], 195 strides=[1, 2, 2, 1], 196 padding="VALID", 197 expected=expected_output, 198 use_gpu=use_gpu) 199 200 def _testAvgPoolSamePadding(self, use_gpu): 201 expected_output = [8.5, 9.5, 10.5, 14.5, 15.5, 16.5] 202 self._VerifyValues( 203 nn_ops.avg_pool, 204 input_sizes=[1, 2, 4, 3], 205 ksize=[1, 2, 2, 1], 206 strides=[1, 2, 2, 1], 207 padding="SAME", 208 expected=expected_output, 209 use_gpu=use_gpu) 210 211 def _testAvgPoolSamePaddingNonSquareWindow(self, use_gpu): 212 # input is: 213 # [1.0, 2.0 214 # 3.0 4.0] 215 # 216 # Window of [x, x] should do: 217 # [avg(1.0, 2.0), avg(2.0, padded0), 218 # avg(3.0, 4.0), avg(4.0, padded0)] 219 self._VerifyValues( 220 nn_ops.avg_pool, 221 input_sizes=[1, 2, 2, 1], 222 ksize=[1, 1, 2, 1], 223 strides=[1, 1, 1, 1], 224 padding="SAME", 225 expected=[1.5, 2.0, 3.5, 4.0], 226 use_gpu=use_gpu) 227 228 # Window of [x, 229 # x] should do: 230 # [avg(1.0, 3.0), avg(2.0, 4.0) 231 # avg(3.0, padded0), avg(4.0, padded0)] 232 self._VerifyValues( 233 nn_ops.avg_pool, 234 input_sizes=[1, 2, 2, 1], 235 ksize=[1, 2, 1, 1], 236 strides=[1, 1, 1, 1], 237 padding="SAME", 238 expected=[2.0, 3.0, 3.0, 4.0], 239 use_gpu=use_gpu) 240 241 def _testAvgPoolSamePaddingNonSquareWindowMultiBatch(self, use_gpu): 242 self._VerifyValues( 243 nn_ops.avg_pool, 244 input_sizes=[2, 2, 2, 2], 245 ksize=[1, 1, 2, 1], 246 strides=[1, 1, 1, 1], 247 padding="SAME", 248 expected=[ 249 2.0, 3.0, 3.0, 4.0, 6.0, 7.0, 7.0, 8.0, 10.0, 11.0, 11.0, 12.0, 250 14.0, 15.0, 15.0, 16.0 251 ], 252 use_gpu=use_gpu) 253 self._VerifyValues( 254 nn_ops.avg_pool, 255 input_sizes=[2, 2, 2, 2], 256 ksize=[1, 2, 1, 1], 257 strides=[1, 1, 1, 1], 258 padding="SAME", 259 expected=[ 260 3.0, 4.0, 5.0, 6.0, 5.0, 6.0, 7.0, 8.0, 11.0, 12.0, 13.0, 14.0, 261 13.0, 14.0, 15.0, 16.0 262 ], 263 use_gpu=use_gpu) 264 265 def _testAvgPoolValidPaddingUnevenStride(self, use_gpu): 266 self._VerifyValues( 267 nn_ops.avg_pool, 268 input_sizes=[1, 3, 3, 3], 269 ksize=[1, 2, 2, 1], 270 strides=[1, 1, 2, 1], 271 padding="VALID", 272 expected=[7.0, 8.0, 9.0, 16.0, 17.0, 18.0], 273 use_gpu=use_gpu) 274 self._VerifyValues( 275 nn_ops.avg_pool, 276 input_sizes=[1, 3, 3, 3], 277 ksize=[1, 2, 2, 1], 278 strides=[1, 2, 1, 1], 279 padding="VALID", 280 expected=[7.0, 8.0, 9.0, 10.0, 11.0, 12.0], 281 use_gpu=use_gpu) 282 283 def _testAvgPoolSamePadding4(self, use_gpu): 284 expected_output = [ 285 11.0, 12.0, 13.0, 14.0, 19.0, 20.0, 21.0, 22.0, 43.0, 44.0, 45.0, 46.0, 286 51.0, 52.0, 53.0, 54.0 287 ] 288 self._VerifyValues( 289 nn_ops.avg_pool, 290 input_sizes=[1, 4, 4, 4], 291 ksize=[1, 2, 2, 1], 292 strides=[1, 2, 2, 1], 293 padding="SAME", 294 expected=expected_output, 295 use_gpu=use_gpu) 296 297 def _testAvgPoolSamePaddingPacket4(self, use_gpu): 298 expected_output = [ 299 21.0, 22.0, 23.0, 24.0, 27.0, 28.0, 29.0, 30.0, 45.0, 46.0, 47.0, 48.0, 300 51.0, 52.0, 53.0, 54.0 301 ] 302 self._VerifyValues( 303 nn_ops.avg_pool, 304 input_sizes=[1, 4, 4, 4], 305 ksize=[1, 3, 3, 1], 306 strides=[1, 2, 2, 1], 307 padding="SAME", 308 expected=expected_output, 309 use_gpu=use_gpu) 310 311 def _testAvgPoolSamePaddingPacket8(self, use_gpu): 312 expected_output = [ 313 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 89.0, 90.0, 91.0, 92.0, 314 93.0, 94.0, 95.0, 96.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0, 315 112.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, 124.0, 201.0, 316 202.0, 203.0, 204.0, 205.0, 206.0, 207.0, 208.0, 217.0, 218.0, 219.0, 317 220.0, 221.0, 222.0, 223.0, 224.0, 233.0, 234.0, 235.0, 236.0, 237.0, 318 238.0, 239.0, 240.0, 245.0, 246.0, 247.0, 248.0, 249.0, 250.0, 251.0, 319 252.0, 329.0, 330.0, 331.0, 332.0, 333.0, 334.0, 335.0, 336.0, 345.0, 320 346.0, 347.0, 348.0, 349.0, 350.0, 351.0, 352.0, 361.0, 362.0, 363.0, 321 364.0, 365.0, 366.0, 367.0, 368.0, 373.0, 374.0, 375.0, 376.0, 377.0, 322 378.0, 379.0, 380.0, 425.0, 426.0, 427.0, 428.0, 429.0, 430.0, 431.0, 323 432.0, 441.0, 442.0, 443.0, 444.0, 445.0, 446.0, 447.0, 448.0, 457.0, 324 458.0, 459.0, 460.0, 461.0, 462.0, 463.0, 464.0, 469.0, 470.0, 471.0, 325 472.0, 473.0, 474.0, 475.0, 476.0 326 ] 327 self._VerifyValues( 328 nn_ops.avg_pool, 329 input_sizes=[1, 8, 8, 8], 330 ksize=[1, 3, 3, 1], 331 strides=[1, 2, 2, 1], 332 padding="SAME", 333 expected=expected_output, 334 use_gpu=use_gpu) 335 336 def testAvgPooling(self): 337 for use_gpu in True, False: 338 self._testAvgPoolValidPadding(use_gpu) 339 self._testAvgPoolSamePadding(use_gpu) 340 self._testAvgPoolSamePaddingNonSquareWindow(use_gpu) 341 self._testAvgPoolSamePaddingNonSquareWindowMultiBatch(use_gpu) 342 self._testAvgPoolValidPaddingUnevenStride(use_gpu) 343 self._testAvgPoolSamePadding4(use_gpu) 344 self._testAvgPoolSamePaddingPacket4(use_gpu) 345 self._testAvgPoolSamePaddingPacket8(use_gpu) 346 347 def _testMaxPoolValidPadding(self, use_gpu): 348 expected_output = [13.0, 14.0, 15.0] 349 self._VerifyValues( 350 nn_ops.max_pool, 351 input_sizes=[1, 3, 3, 3], 352 ksize=[1, 2, 2, 1], 353 strides=[1, 2, 2, 1], 354 padding="VALID", 355 expected=expected_output, 356 use_gpu=use_gpu) 357 358 def _testMaxPoolSamePadding(self, use_gpu): 359 expected_output = [13.0, 14.0, 15.0, 16.0, 17.0, 18.0] 360 self._VerifyValues( 361 nn_ops.max_pool, 362 input_sizes=[1, 2, 3, 3], 363 ksize=[1, 2, 2, 1], 364 strides=[1, 2, 2, 1], 365 padding="SAME", 366 expected=expected_output, 367 use_gpu=use_gpu) 368 369 def _testMaxPoolSamePaddingNonSquareWindow(self, use_gpu): 370 # input is: 371 # [1.0, 2.0 372 # 3.0 4.0] 373 # 374 # Window of [x, x] should do: 375 # 376 # [max(1.0, 2.0), max(2.0, padded0), 377 # max(3.0, 4.0), max(4.0, padded0)] 378 self._VerifyValues( 379 nn_ops.max_pool, 380 input_sizes=[1, 2, 2, 1], 381 ksize=[1, 1, 2, 1], 382 strides=[1, 1, 1, 1], 383 padding="SAME", 384 expected=[2.0, 2.0, 4.0, 4.0], 385 use_gpu=use_gpu) 386 387 def _testMaxPoolValidPaddingUnevenStride(self, use_gpu): 388 self._VerifyValues( 389 nn_ops.max_pool, 390 input_sizes=[1, 4, 4, 1], 391 ksize=[1, 2, 2, 1], 392 strides=[1, 1, 2, 1], 393 padding="VALID", 394 expected=[6.0, 8.0, 10.0, 12.0, 14.0, 16.0], 395 use_gpu=use_gpu) 396 self._VerifyValues( 397 nn_ops.max_pool, 398 input_sizes=[1, 4, 4, 1], 399 ksize=[1, 2, 2, 1], 400 strides=[1, 2, 1, 1], 401 padding="VALID", 402 expected=[6.0, 7.0, 8.0, 14.0, 15.0, 16.0], 403 use_gpu=use_gpu) 404 405 def _testMaxPoolSamePaddingPacket4(self, use_gpu): 406 expected_output = [ 407 21.0, 22.0, 23.0, 24.0, 29.0, 30.0, 31.0, 32.0, 53.0, 54.0, 55.0, 56.0, 408 61.0, 62.0, 63.0, 64.0 409 ] 410 self._VerifyValues( 411 nn_ops.max_pool, 412 input_sizes=[1, 4, 4, 4], 413 ksize=[1, 2, 2, 1], 414 strides=[1, 2, 2, 1], 415 padding="SAME", 416 expected=expected_output, 417 use_gpu=use_gpu) 418 419 def _testMaxPoolSamePaddingPacket8(self, use_gpu): 420 expected_output = [ 421 145.0, 146.0, 147.0, 148.0, 149.0, 150.0, 151.0, 152.0, 161.0, 162.0, 422 163.0, 164.0, 165.0, 166.0, 167.0, 168.0, 177.0, 178.0, 179.0, 180.0, 423 181.0, 182.0, 183.0, 184.0, 185.0, 186.0, 187.0, 188.0, 189.0, 190.0, 424 191.0, 192.0, 273.0, 274.0, 275.0, 276.0, 277.0, 278.0, 279.0, 280.0, 425 289.0, 290.0, 291.0, 292.0, 293.0, 294.0, 295.0, 296.0, 305.0, 306.0, 426 307.0, 308.0, 309.0, 310.0, 311.0, 312.0, 313.0, 314.0, 315.0, 316.0, 427 317.0, 318.0, 319.0, 320.0, 401.0, 402.0, 403.0, 404.0, 405.0, 406.0, 428 407.0, 408.0, 417.0, 418.0, 419.0, 420.0, 421.0, 422.0, 423.0, 424.0, 429 433.0, 434.0, 435.0, 436.0, 437.0, 438.0, 439.0, 440.0, 441.0, 442.0, 430 443.0, 444.0, 445.0, 446.0, 447.0, 448.0, 465.0, 466.0, 467.0, 468.0, 431 469.0, 470.0, 471.0, 472.0, 481.0, 482.0, 483.0, 484.0, 485.0, 486.0, 432 487.0, 488.0, 497.0, 498.0, 499.0, 500.0, 501.0, 502.0, 503.0, 504.0, 433 505.0, 506.0, 507.0, 508.0, 509.0, 510.0, 511.0, 512.0 434 ] 435 self._VerifyValues( 436 nn_ops.max_pool, 437 input_sizes=[1, 8, 8, 8], 438 ksize=[1, 3, 3, 1], 439 strides=[1, 2, 2, 1], 440 padding="SAME", 441 expected=expected_output, 442 use_gpu=use_gpu) 443 444 def testMaxPooling(self): 445 for use_gpu in True, False: 446 self._testMaxPoolValidPadding(use_gpu) 447 self._testMaxPoolSamePadding(use_gpu) 448 self._testMaxPoolSamePaddingNonSquareWindow(use_gpu) 449 self._testMaxPoolValidPaddingUnevenStride(use_gpu) 450 self._testMaxPoolSamePaddingPacket4(use_gpu) 451 self._testMaxPoolSamePaddingPacket8(use_gpu) 452 453 # Tests for DepthwiseMaxPooling on CPU only. 454 def testDepthwiseMaxPool1x1DepthWindow1(self): 455 # input is: 456 # [1.0, ..., 10.0] along depth, 457 # 458 # We maxpool by depth in patches of 2. 459 self._VerifyValues( 460 nn_ops.max_pool, 461 input_sizes=[1, 1, 1, 10], 462 ksize=[1, 1, 1, 2], 463 strides=[1, 1, 1, 2], 464 padding="SAME", 465 expected=[2.0, 4.0, 6.0, 8.0, 10.0], 466 use_gpu=False) 467 468 def testDepthwiseMaxPool2x2DepthWindow3(self): 469 # input is: 470 # 471 # a 2x2x6 cube, and we depthwise max across 3 to produce a 2x2x2 472 # output. Each node has contiguous values, so the depthwise max 473 # should be multiples of 3.0. 474 self._VerifyValues( 475 nn_ops.max_pool, 476 input_sizes=[1, 2, 2, 6], 477 ksize=[1, 1, 1, 3], 478 strides=[1, 1, 1, 3], 479 padding="SAME", 480 expected=[3.0, 6.0, 9.0, 12.0, 15.0, 18.0, 21.0, 24.0], 481 use_gpu=False) 482 483 def testKernelSmallerThanStrideValid(self): 484 for use_gpu in [True, False]: 485 self._VerifyValues( 486 nn_ops.max_pool, 487 input_sizes=[1, 7, 7, 1], 488 ksize=[1, 2, 2, 1], 489 strides=[1, 3, 3, 1], 490 padding="VALID", 491 expected=[9, 12, 30, 33], 492 use_gpu=use_gpu) 493 494 self._VerifyValues( 495 nn_ops.avg_pool, 496 input_sizes=[1, 7, 7, 1], 497 ksize=[1, 2, 2, 1], 498 strides=[1, 3, 3, 1], 499 padding="VALID", 500 expected=[5, 8, 26, 29], 501 use_gpu=use_gpu) 502 503 def testKernelSmallerThanStrideSame(self): 504 for use_gpu in [True, False]: 505 for pool_func in [nn_ops.max_pool, nn_ops.avg_pool]: 506 self._VerifyValues( 507 pool_func, 508 input_sizes=[1, 3, 3, 1], 509 ksize=[1, 1, 1, 1], 510 strides=[1, 2, 2, 1], 511 padding="SAME", 512 expected=[1, 3, 7, 9], 513 use_gpu=use_gpu) 514 515 self._VerifyValues( 516 pool_func, 517 input_sizes=[1, 4, 4, 1], 518 ksize=[1, 1, 1, 1], 519 strides=[1, 2, 2, 1], 520 padding="SAME", 521 expected=[1, 3, 9, 11], 522 use_gpu=use_gpu) 523 524 def _testDepthwiseMaxPoolInvalidConfig(self, 525 in_size, 526 ksize, 527 strides, 528 error_msg, 529 use_gpu=False): 530 with self.test_session(use_gpu=use_gpu) as sess: 531 t = constant_op.constant(1.0, shape=in_size) 532 with self.assertRaisesRegexp(errors_impl.UnimplementedError, error_msg): 533 t = nn_ops.max_pool( 534 t, ksize=ksize, strides=strides, padding="SAME").eval() 535 536 def testDepthwiseMaxPoolInvalidConfigs(self): 537 self._testDepthwiseMaxPoolInvalidConfig( 538 [1, 2, 2, 4], [1, 2, 2, 2], [1, 1, 1, 2], 539 "exactly one of pooling across depth") 540 self._testDepthwiseMaxPoolInvalidConfig( 541 [1, 2, 2, 4], [1, 1, 1, 2], [1, 1, 1, 1], 542 "depth window to equal the depth stride") 543 self._testDepthwiseMaxPoolInvalidConfig([1, 2, 2, 4], [1, 1, 1, 3], 544 [1, 1, 1, 3], "evenly divide") 545 if test.is_gpu_available(): 546 with self.test_session(use_gpu=True): 547 t = constant_op.constant(1.0, shape=[1, 2, 2, 4]) 548 with self.assertRaisesOpError("for CPU devices"): 549 nn_ops.max_pool( 550 t, ksize=[1, 1, 1, 2], strides=[1, 1, 1, 2], 551 padding="SAME").eval() 552 553 # The following are tests that verify that the CPU and GPU implementations 554 # produce the same resuts. 555 def _CompareMaxPoolingFwd(self, input_shape, ksize, strides, padding): 556 for dtype in np.float32, np.float16: 557 tensor_input = np.random.rand(*input_shape).astype(dtype) 558 with self.test_session(use_gpu=True): 559 t = constant_op.constant(tensor_input, shape=input_shape) 560 out_op, _ = nn_ops.max_pool_with_argmax(t, ksize, strides, padding) 561 gpu_val = out_op.eval() 562 with self.test_session(use_gpu=False): 563 t = constant_op.constant(tensor_input, shape=input_shape) 564 out_op = nn_ops.max_pool(t, ksize, strides, padding) 565 cpu_val = out_op.eval() 566 self.assertAllCloseAccordingToType(cpu_val, gpu_val) 567 568 def _CompareMaxPoolingBk(self, input_shape, output_shape, ksize, strides, 569 padding): 570 for dtype in np.float32, np.float16: 571 # Generate numbers in a narrow range, so that there are many duplicates 572 # in the input. 573 tensor_input = np.random.random_integers(0, 3, input_shape).astype(dtype) 574 tensor_output = np.random.rand(*output_shape).astype(dtype) 575 with self.test_session(use_gpu=True): 576 t = constant_op.constant(tensor_input, shape=input_shape) 577 _, argmax_op = nn_ops.max_pool_with_argmax(t, ksize, strides, padding) 578 argmax = argmax_op.eval() 579 grad_in = constant_op.constant(tensor_output, shape=output_shape) 580 out_op = gen_nn_ops._max_pool_grad_with_argmax(t, grad_in, argmax, 581 ksize, strides, padding) 582 gpu_val = out_op.eval() 583 self.assertShapeEqual(gpu_val, out_op) 584 with self.test_session(use_gpu=False): 585 t = constant_op.constant(tensor_input, shape=input_shape) 586 out_op = nn_ops.max_pool(t, ksize, strides, padding) 587 orig_out = out_op.eval() 588 grad_in = constant_op.constant(tensor_output, shape=output_shape) 589 out_op = gen_nn_ops._max_pool_grad(t, orig_out, grad_in, ksize, strides, 590 padding) 591 cpu_val = out_op.eval() 592 self.assertShapeEqual(cpu_val, out_op) 593 if dtype == np.float16: 594 # The CPU version accumulates its gradient on fp16, so it's less 595 # accurate than the GPU version that does the accumulation on fp32 596 self.assertAllClose(cpu_val, gpu_val, rtol=0.01, atol=0.01) 597 else: 598 self.assertAllClose(cpu_val, gpu_val) 599 600 def testMaxPoolingWithArgmax(self): 601 # MaxPoolWithArgMax is implemented only on CUDA. 602 if not test.is_gpu_available(cuda_only=True): 603 return 604 tensor_input = [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0] 605 with self.test_session(use_gpu=True) as sess: 606 t = constant_op.constant(tensor_input, shape=[1, 3, 3, 1]) 607 out_op, argmax_op = nn_ops.max_pool_with_argmax( 608 t, 609 ksize=[1, 2, 2, 1], 610 strides=[1, 1, 1, 1], 611 Targmax=dtypes.int64, 612 padding="VALID") 613 out, argmax = sess.run([out_op, argmax_op]) 614 self.assertShapeEqual(out, out_op) 615 self.assertShapeEqual(argmax, argmax_op) 616 self.assertAllClose(out.ravel(), [1.0, 1.0, 1.0, 1.0]) 617 self.assertAllEqual(argmax.ravel(), [0, 1, 3, 5]) 618 619 def testMaxPoolingGradWithArgmax(self): 620 # MaxPoolWithArgMax is implemented only on CUDA. 621 if not test.is_gpu_available(cuda_only=True): 622 return 623 orig_input = [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0] 624 tensor_input = [11.0, 12.0, 13.0, 14.0] 625 tensor_argmax = list(np.array([0, 1, 3, 5], dtype=np.int64)) 626 with self.test_session(use_gpu=True) as sess: 627 orig_in = constant_op.constant(orig_input, shape=[1, 3, 3, 1]) 628 t = constant_op.constant(tensor_input, shape=[1, 2, 2, 1]) 629 argmax = constant_op.constant( 630 tensor_argmax, shape=[1, 2, 2, 1], dtype=dtypes.int64) 631 out_op = gen_nn_ops._max_pool_grad_with_argmax( 632 orig_in, 633 t, 634 argmax, 635 ksize=[1, 2, 2, 1], 636 strides=[1, 1, 1, 1], 637 padding="VALID") 638 out = out_op.eval().flatten() 639 self.assertAllClose(out, 640 [11.0, 12.0, 0.0, 13.0, 0.0, 14.0, 0.0, 0.0, 0.0]) 641 642 def _ConstructAndTestGradient(self, 643 pool_func, 644 input_sizes, 645 output_sizes, 646 window_rows, 647 window_cols, 648 row_stride, 649 col_stride, 650 padding, 651 data_format, 652 use_gpu, 653 x_init_value=None): 654 """Verifies the gradients of the avg pooling function. 655 656 Args: 657 pool_func: Function to be called, co.MaxPool, co.AvgPool, 658 or the Lua version. 659 input_sizes: Input tensor dimensions. 660 output_sizes: Output tensor dimensions. 661 window_rows: kernel size in row dim 662 window_cols: kernel size in col dim 663 row_stride: Row Stride. 664 col_stride: Col Stride. 665 padding: Padding type. 666 data_format: Data format. 667 use_gpu: whether we are running on GPU 668 x_init_value: Values to be passed to the gradient checker. 669 """ 670 assert input_sizes[0] == output_sizes[0] 671 assert input_sizes[3] == output_sizes[3] 672 total_size = 1 673 for s in input_sizes: 674 total_size *= s 675 # Initializes the input tensor with array containing incrementing 676 # numbers from 1. 677 x = [f * 1.0 for f in range(1, total_size + 1)] 678 with self.test_session(use_gpu=use_gpu): 679 input_tensor = constant_op.constant(x, shape=input_sizes, name="input") 680 if pool_func == nn_ops.avg_pool: 681 func_name = "avg_pool" 682 err_margin = 1e-4 683 else: 684 if x_init_value is None: 685 x_init_value = np.asfarray( 686 np.arange(1, total_size + 1), 687 dtype=np.float32).reshape(input_sizes) 688 func_name = "max_pool" 689 err_margin = 1e-3 690 if data_format == "NCHW": 691 ksize = [1, 1, window_rows, window_rows] 692 strides = [1, 1, row_stride, col_stride] 693 t = NHWCToNCHW(input_tensor) 694 else: 695 ksize = [1, window_rows, window_rows, 1] 696 strides = [1, row_stride, col_stride, 1] 697 t = input_tensor 698 t = pool_func( 699 t, 700 ksize=ksize, 701 strides=strides, 702 padding=padding, 703 data_format=data_format, 704 name=func_name) 705 if data_format == "NCHW": 706 t = NCHWToNHWC(t) 707 708 err = gradient_checker.compute_gradient_error( 709 input_tensor, 710 input_sizes, 711 t, 712 output_sizes, 713 x_init_value=x_init_value, 714 delta=1e-2) 715 print("%s gradient error = " % func_name, err) 716 self.assertLess(err, err_margin) 717 718 def _testMaxPoolGradValidPadding1_1(self, data_format, use_gpu): 719 self._ConstructAndTestGradient( 720 nn_ops.max_pool, 721 input_sizes=[1, 3, 3, 1], 722 output_sizes=[1, 3, 3, 1], 723 window_rows=1, 724 window_cols=1, 725 row_stride=1, 726 col_stride=1, 727 padding="VALID", 728 data_format=data_format, 729 use_gpu=use_gpu) 730 731 def _testMaxPoolGradValidPadding2_1_6(self, data_format, use_gpu): 732 self._ConstructAndTestGradient( 733 nn_ops.max_pool, 734 input_sizes=[2, 6, 6, 3], 735 output_sizes=[2, 5, 5, 3], 736 window_rows=2, 737 window_cols=2, 738 row_stride=1, 739 col_stride=1, 740 padding="VALID", 741 data_format=data_format, 742 use_gpu=use_gpu) 743 744 def _testMaxPoolGradValidPadding2_1_7(self, data_format, use_gpu): 745 self._ConstructAndTestGradient( 746 nn_ops.max_pool, 747 input_sizes=[2, 7, 7, 3], 748 output_sizes=[2, 6, 6, 3], 749 window_rows=2, 750 window_cols=2, 751 row_stride=1, 752 col_stride=1, 753 padding="VALID", 754 data_format=data_format, 755 use_gpu=use_gpu) 756 757 def _testMaxPoolGradValidPadding2_2(self, data_format, use_gpu): 758 self._ConstructAndTestGradient( 759 nn_ops.max_pool, 760 input_sizes=[2, 2, 2, 3], 761 output_sizes=[2, 1, 1, 3], 762 window_rows=2, 763 window_cols=2, 764 row_stride=2, 765 col_stride=2, 766 padding="VALID", 767 data_format=data_format, 768 use_gpu=use_gpu) 769 770 def _testMaxPoolGradSamePadding1_1(self, data_format, use_gpu): 771 self._ConstructAndTestGradient( 772 nn_ops.max_pool, 773 input_sizes=[2, 2, 4, 3], 774 output_sizes=[2, 2, 4, 3], 775 window_rows=1, 776 window_cols=1, 777 row_stride=1, 778 col_stride=1, 779 padding="SAME", 780 data_format=data_format, 781 use_gpu=use_gpu) 782 783 def _testMaxPoolGradSamePadding2_1(self, data_format, use_gpu): 784 self._ConstructAndTestGradient( 785 nn_ops.max_pool, 786 input_sizes=[2, 2, 4, 3], 787 output_sizes=[2, 2, 4, 3], 788 window_rows=2, 789 window_cols=2, 790 row_stride=1, 791 col_stride=1, 792 padding="SAME", 793 data_format=data_format, 794 use_gpu=use_gpu) 795 796 def _testMaxPoolGradSamePadding2_2(self, data_format, use_gpu): 797 self._ConstructAndTestGradient( 798 nn_ops.max_pool, 799 input_sizes=[2, 2, 4, 3], 800 output_sizes=[2, 1, 2, 3], 801 window_rows=2, 802 window_cols=2, 803 row_stride=2, 804 col_stride=2, 805 padding="SAME", 806 data_format=data_format, 807 use_gpu=use_gpu) 808 809 def _testMaxPoolGradSamePadding3_1(self, data_format, use_gpu): 810 self._ConstructAndTestGradient( 811 nn_ops.max_pool, 812 input_sizes=[1, 7, 7, 1], 813 output_sizes=[1, 7, 7, 1], 814 window_rows=3, 815 window_cols=3, 816 row_stride=1, 817 col_stride=1, 818 padding="SAME", 819 data_format=data_format, 820 use_gpu=use_gpu) 821 822 def testMaxPoolGrad(self): 823 for (data_format, use_gpu) in GetTestConfigs(): 824 self._testMaxPoolGradValidPadding1_1(data_format, use_gpu) 825 self._testMaxPoolGradValidPadding2_1_6(data_format, use_gpu) 826 self._testMaxPoolGradValidPadding2_1_7(data_format, use_gpu) 827 self._testMaxPoolGradValidPadding2_2(data_format, use_gpu) 828 self._testMaxPoolGradSamePadding1_1(data_format, use_gpu) 829 self._testMaxPoolGradSamePadding2_1(data_format, use_gpu) 830 self._testMaxPoolGradSamePadding2_2(data_format, use_gpu) 831 self._testMaxPoolGradSamePadding3_1(data_format, use_gpu) 832 833 def _MaxPoolGrad(self, orig_input, orig_output, grad, window_rows, 834 window_cols, row_stride, col_stride, padding): 835 """Max Pooling Gradient. 836 837 Args: 838 orig_input: A float Tensor. The original input tensor. 839 orig_output: A float Tensor. The original output tensor. 840 grad: A float Tensor. 841 The 4D (batch x rows x cols x depth) output backprop. 842 window_rows: integer. Kernel size along rows dimension. 843 window_cols: integer. Kernel size along cols dimension. 844 row_stride: integer. Stride along rows dimension 845 col_stride: integer. Stride along cols dimension 846 padding: PoolingOpDef.Padding. Padding type. 847 848 Returns: 849 A Tensor. 850 """ 851 return gen_nn_ops._max_pool_grad(orig_input, orig_output, grad, 852 [1, window_rows, window_cols, 1], 853 [1, row_stride, col_stride, 1], padding) 854 855 def _testMaxPoolGradDirect(self, input_data, output_backprop, 856 expected_input_backprop, input_sizes, output_sizes, 857 window_rows, window_cols, row_stride, col_stride, 858 padding, use_gpu): 859 with self.test_session(use_gpu=use_gpu) as sess: 860 input_tensor = constant_op.constant(input_data, shape=input_sizes) 861 output_tensor = nn_ops.max_pool(input_tensor, 862 [1, window_rows, window_cols, 1], 863 [1, row_stride, col_stride, 1], padding) 864 output_backprop_tensor = constant_op.constant( 865 output_backprop, shape=output_sizes) 866 867 input_backprop_tensor = self._MaxPoolGrad(input_tensor, output_tensor, 868 output_backprop_tensor, 869 window_rows, window_cols, 870 row_stride, col_stride, padding) 871 872 actual_input_backprop = input_backprop_tensor.eval() 873 self.assertShapeEqual(actual_input_backprop, input_backprop_tensor) 874 actual_input_backprop = actual_input_backprop.flatten() 875 actual_input_backprop = self._GetNdArray(actual_input_backprop) 876 877 actual_output = output_tensor.eval().flatten() 878 actual_output = self._GetNdArray(actual_output) 879 880 self.assertAllClose( 881 expected_input_backprop, actual_input_backprop, rtol=1e-6, atol=1e-6) 882 883 def _testMaxPoolGradDirect1_1(self): 884 input_data = [ 885 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, 886 1.0, 1.0 887 ] 888 output_backprop = [11.0, 12.0, 13.0, 15.0, 16.0, 17.0, 19.0, 20.0, 21.0] 889 expected_input_backprop = [ 890 11.0, 12.0, 13.0, 0.0, 15.0, 16.0, 17.0, 0.0, 19.0, 20.0, 21.0, 0.0, 891 0.0, 0.0, 0.0, 0.0 892 ] 893 894 for use_gpu in True, False: 895 self._testMaxPoolGradDirect( 896 input_data, 897 output_backprop, 898 expected_input_backprop, 899 input_sizes=[1, 4, 4, 1], 900 output_sizes=[1, 3, 3, 1], 901 window_rows=2, 902 window_cols=2, 903 row_stride=1, 904 col_stride=1, 905 padding="VALID", 906 use_gpu=use_gpu) 907 908 def _testMaxPoolGradDirect1_2(self): 909 input_data = [ 910 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, 911 0.0, 1.0 912 ] 913 output_backprop = [11.0, 12.0, 13.0, 15.0, 16.0, 17.0, 19.0, 20.0, 21.0] 914 expected_input_backprop = [ 915 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, 916 0.0, 0.0, 0.0 917 ] 918 919 for use_gpu in True, False: 920 self._testMaxPoolGradDirect( 921 input_data, 922 output_backprop, 923 expected_input_backprop, 924 input_sizes=[1, 4, 4, 1], 925 output_sizes=[1, 3, 3, 1], 926 window_rows=2, 927 window_cols=2, 928 row_stride=1, 929 col_stride=1, 930 padding="VALID", 931 use_gpu=use_gpu) 932 933 def _testMaxPoolGradDirect1_3(self): 934 input_data = [ 935 1.0, 936 0.0, 937 1.0, 938 0.0, 939 0.0, 940 1.0, 941 0.0, 942 1.0, 943 1.0, 944 0.0, 945 1.0, 946 0.0, 947 0.0, 948 1.0, 949 0.0, 950 1.0, 951 ] 952 output_backprop = [ 953 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 954 23.0, 24.0, 25.0, 26.0 955 ] 956 expected_input_backprop = [ 957 54, 958 0.0, 959 62, 960 0.0, 961 0.0, 962 60, 963 0.0, 964 22.0, 965 47, 966 0.0, 967 51, 968 0.0, 969 0.0, 970 0.0, 971 0.0, 972 0.0, 973 ] 974 975 for use_gpu in True, False: 976 self._testMaxPoolGradDirect( 977 input_data, 978 output_backprop, 979 expected_input_backprop, 980 input_sizes=[1, 4, 4, 1], 981 output_sizes=[1, 4, 4, 1], 982 window_rows=3, 983 window_cols=3, 984 row_stride=1, 985 col_stride=1, 986 padding="SAME", 987 use_gpu=use_gpu) 988 989 def _testMaxPoolGradDirectWithNans2_1(self): 990 input_data = [float("nan")] * 16 991 output_backprop = [11.0, 12.0, 13.0, 15.0, 16.0, 17.0, 19.0, 20.0, 21.0] 992 # Test the CPU implementation, which propagates diffs in case of NaN 993 expected_input_backprop_tf_cpu = [ 994 11.0, 12.0, 13.0, 0.0, 15.0, 16.0, 17.0, 0.0, 19.0, 20.0, 21.0, 0.0, 995 0.0, 0.0, 0.0, 0.0 996 ] 997 self._testMaxPoolGradDirect( 998 input_data, 999 output_backprop, 1000 expected_input_backprop_tf_cpu, 1001 input_sizes=[1, 4, 4, 1], 1002 output_sizes=[1, 3, 3, 1], 1003 window_rows=2, 1004 window_cols=2, 1005 row_stride=1, 1006 col_stride=1, 1007 padding="VALID", 1008 use_gpu=False) 1009 1010 if not test.is_gpu_available(): 1011 return 1012 1013 # Test the GPU implementation that uses cudnn for now. 1014 # It does not propagate the diff in cases of NaNs 1015 expected_input_backprop_cudnn = [ 1016 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, 1017 0.0, 0.0 1018 ] 1019 self._testMaxPoolGradDirect( 1020 input_data, 1021 output_backprop, 1022 expected_input_backprop_cudnn, 1023 input_sizes=[1, 4, 4, 1], 1024 output_sizes=[1, 3, 3, 1], 1025 window_rows=2, 1026 window_cols=2, 1027 row_stride=1, 1028 col_stride=1, 1029 padding="VALID", 1030 use_gpu=True) 1031 1032 def _testMaxPoolGradDirectWithNans2_2(self): 1033 input_data = [float("nan")] * 16 1034 output_backprop = [ 1035 float("nan"), 12.0, 13.0, 15.0, float("nan"), 17.0, 19.0, 20.0, 1036 float("nan") 1037 ] 1038 # Test the CPU implementation, which propagates diffs in case of NaN 1039 expected_input_backprop_tf_cpu = [ 1040 float("nan"), 12.0, 13.0, 0.0, 15.0, float("nan"), 17.0, 0.0, 19.0, 1041 20.0, float("nan"), 0.0, 0.0, 0.0, 0.0, 0.0 1042 ] 1043 self._testMaxPoolGradDirect( 1044 input_data, 1045 output_backprop, 1046 expected_input_backprop_tf_cpu, 1047 input_sizes=[1, 4, 4, 1], 1048 output_sizes=[1, 3, 3, 1], 1049 window_rows=2, 1050 window_cols=2, 1051 row_stride=1, 1052 col_stride=1, 1053 padding="VALID", 1054 use_gpu=False) 1055 1056 if not test.is_gpu_available(): 1057 return 1058 1059 # Test the GPU implementation that uses cudnn for now. 1060 # It does not propagate the diff in cases of NaNs 1061 expected_input_backprop_cudnn = [ 1062 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, 1063 0.0, 0.0 1064 ] 1065 self._testMaxPoolGradDirect( 1066 input_data, 1067 output_backprop, 1068 expected_input_backprop_cudnn, 1069 input_sizes=[1, 4, 4, 1], 1070 output_sizes=[1, 3, 3, 1], 1071 window_rows=2, 1072 window_cols=2, 1073 row_stride=1, 1074 col_stride=1, 1075 padding="VALID", 1076 use_gpu=True) 1077 1078 def testMaxPoolGradDirect(self): 1079 self._testMaxPoolGradDirect1_1() 1080 self._testMaxPoolGradDirect1_2() 1081 self._testMaxPoolGradDirect1_3() 1082 self._testMaxPoolGradDirectWithNans2_1() 1083 self._testMaxPoolGradDirectWithNans2_2() 1084 1085 def testAvgPoolGrad(self): 1086 for (data_format, use_gpu) in GetTestConfigs(): 1087 self._testAvgPoolGradValidPadding1_1(data_format, use_gpu) 1088 self._testAvgPoolGradValidPadding2_1(data_format, use_gpu) 1089 self._testAvgPoolGradValidPadding2_2(data_format, use_gpu) 1090 self._testAvgPoolGradSamePadding1_1(data_format, use_gpu) 1091 self._testAvgPoolGradSamePadding2_1(data_format, use_gpu) 1092 self._testAvgPoolGradSamePadding2_2(data_format, use_gpu) 1093 self._testAvgPoolGradSamePadding3_1(data_format, use_gpu) 1094 1095 def _testAvgPoolGradValidPadding1_1(self, data_format, use_gpu): 1096 self._ConstructAndTestGradient( 1097 nn_ops.avg_pool, 1098 input_sizes=[2, 3, 3, 3], 1099 output_sizes=[2, 3, 3, 3], 1100 window_rows=1, 1101 window_cols=1, 1102 row_stride=1, 1103 col_stride=1, 1104 padding="VALID", 1105 data_format=data_format, 1106 use_gpu=use_gpu) 1107 1108 def _testAvgPoolGradValidPadding2_1(self, data_format, use_gpu): 1109 self._ConstructAndTestGradient( 1110 nn_ops.avg_pool, 1111 input_sizes=[2, 3, 3, 3], 1112 output_sizes=[2, 2, 2, 3], 1113 window_rows=2, 1114 window_cols=2, 1115 row_stride=1, 1116 col_stride=1, 1117 padding="VALID", 1118 data_format=data_format, 1119 use_gpu=use_gpu) 1120 1121 def _testAvgPoolGradValidPadding2_2(self, data_format, use_gpu): 1122 self._ConstructAndTestGradient( 1123 nn_ops.avg_pool, 1124 input_sizes=[2, 2, 2, 3], 1125 output_sizes=[2, 1, 1, 3], 1126 window_rows=2, 1127 window_cols=2, 1128 row_stride=2, 1129 col_stride=2, 1130 padding="VALID", 1131 data_format=data_format, 1132 use_gpu=use_gpu) 1133 1134 def _testAvgPoolGradSamePadding1_1(self, data_format, use_gpu): 1135 self._ConstructAndTestGradient( 1136 nn_ops.avg_pool, 1137 input_sizes=[2, 2, 4, 3], 1138 output_sizes=[2, 2, 4, 3], 1139 window_rows=1, 1140 window_cols=1, 1141 row_stride=1, 1142 col_stride=1, 1143 padding="SAME", 1144 data_format=data_format, 1145 use_gpu=use_gpu) 1146 1147 def _testAvgPoolGradSamePadding2_1(self, data_format, use_gpu): 1148 self._ConstructAndTestGradient( 1149 nn_ops.avg_pool, 1150 input_sizes=[2, 2, 4, 3], 1151 output_sizes=[2, 2, 4, 3], 1152 window_rows=2, 1153 window_cols=2, 1154 row_stride=1, 1155 col_stride=1, 1156 padding="SAME", 1157 data_format=data_format, 1158 use_gpu=use_gpu) 1159 1160 def _testAvgPoolGradSamePadding2_2(self, data_format, use_gpu): 1161 self._ConstructAndTestGradient( 1162 nn_ops.avg_pool, 1163 input_sizes=[2, 2, 4, 3], 1164 output_sizes=[2, 1, 2, 3], 1165 window_rows=2, 1166 window_cols=2, 1167 row_stride=2, 1168 col_stride=2, 1169 padding="SAME", 1170 data_format=data_format, 1171 use_gpu=use_gpu) 1172 1173 def _testAvgPoolGradSamePadding3_1(self, data_format, use_gpu): 1174 self._ConstructAndTestGradient( 1175 nn_ops.avg_pool, 1176 input_sizes=[1, 7, 7, 1], 1177 output_sizes=[1, 7, 7, 1], 1178 window_rows=3, 1179 window_cols=3, 1180 row_stride=1, 1181 col_stride=1, 1182 padding="SAME", 1183 data_format=data_format, 1184 use_gpu=use_gpu) 1185 1186 def testShapeFunctionEdgeCases(self): 1187 # All shapes unknown. 1188 for pool_func in [nn_ops.max_pool, nn_ops.avg_pool]: 1189 p = pool_func( 1190 array_ops.placeholder(dtypes.float32), 1191 ksize=[1, 1, 1, 1], 1192 strides=[1, 1, 1, 1], 1193 padding="SAME") 1194 self.assertEqual([None, None, None, None], p.get_shape().as_list()) 1195 p, am = nn_ops.max_pool_with_argmax( 1196 array_ops.placeholder(dtypes.float32), 1197 ksize=[1, 1, 1, 1], 1198 strides=[1, 1, 1, 1], 1199 padding="SAME") 1200 self.assertEqual([None, None, None, None], p.get_shape().as_list()) 1201 self.assertEqual([None, None, None, None], am.get_shape().as_list()) 1202 1203 # Incorrect input shape. 1204 for pool_func in [ 1205 nn_ops.max_pool, nn_ops.avg_pool, nn_ops.max_pool_with_argmax 1206 ]: 1207 with self.assertRaises(ValueError): 1208 pool_func( 1209 array_ops.placeholder( 1210 dtypes.float32, shape=[1, 3]), 1211 ksize=[1, 1, 1, 1], 1212 strides=[1, 1, 1, 1], 1213 padding="SAME") 1214 1215 def testOpEdgeCases(self): 1216 with self.test_session() as sess: 1217 pool_funcs = [nn_ops.max_pool, nn_ops.avg_pool] 1218 if test.is_gpu_available(): 1219 pool_funcs.append(nn_ops.max_pool_with_argmax) 1220 for pool_func in pool_funcs: 1221 # Illegal strides. 1222 with self.assertRaisesRegexp( 1223 errors_impl.UnimplementedError, 1224 "Pooling is not yet supported on the batch"): 1225 sess.run( 1226 pool_func( 1227 array_ops.placeholder(dtypes.float32), 1228 ksize=[1, 1, 1, 1], 1229 strides=[2, 1, 1, 1], 1230 padding="SAME")) 1231 1232 # Filter too large. 1233 with self.assertRaisesRegexp(ValueError, "Negative dimension size"): 1234 sess.run( 1235 pool_func( 1236 array_ops.placeholder( 1237 dtypes.float32, shape=[32, 20, 20, 3]), 1238 ksize=[1, 20, 21, 1], 1239 strides=[1, 1, 1, 1], 1240 padding="VALID")) 1241 with self.assertRaisesRegexp(ValueError, "Negative dimension size"): 1242 pool_func( 1243 array_ops.placeholder( 1244 dtypes.float32, shape=[32, 20, 20, 3]), 1245 ksize=[1, 21, 20, 1], 1246 strides=[1, 1, 1, 1], 1247 padding="VALID") 1248 1249 1250def GetMaxPoolFwdTest(input_size, filter_size, strides, padding): 1251 1252 def Test(self): 1253 # MaxPoolWithArgMax is implemented only on CUDA. 1254 if not test.is_gpu_available(cuda_only=True): 1255 return 1256 self._CompareMaxPoolingFwd(input_size, filter_size, strides, padding) 1257 1258 return Test 1259 1260 1261def GetMaxPoolGradTest(input_size, filter_size, output_size, strides, padding): 1262 1263 def Test(self): 1264 # MaxPoolWithArgMax is implemented only on CUDA. 1265 if not test.is_gpu_available(cuda_only=True): 1266 return 1267 self._CompareMaxPoolingBk(input_size, output_size, filter_size, strides, 1268 padding) 1269 1270 return Test 1271 1272 1273if __name__ == "__main__": 1274 for (name_, input_size_, filter_size_, output_size_, stride_, 1275 padding_) in GetShrunkInceptionMaxPoolShapes(): 1276 setattr(PoolingTest, "testMaxPoolFwd_" + name_, 1277 GetMaxPoolFwdTest(input_size_, filter_size_, stride_, padding_)) 1278 setattr(PoolingTest, "testMaxPoolGrad_" + name_, 1279 GetMaxPoolGradTest(input_size_, filter_size_, output_size_, stride_, 1280 padding_)) 1281 test.main() 1282