diff options
author | A. Unique TensorFlower <gardener@tensorflow.org> | 2017-09-01 14:42:46 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2017-09-01 14:46:48 -0700 |
commit | fe8905ed992e29467bcf69053dfce07b77f906d3 (patch) | |
tree | b2f5a15efb91a9ac4ba45a851b1831143f17d084 /tensorflow | |
parent | ef1286ea349d362e8a214f0e98951586791e0719 (diff) |
Fix issue where some pooling op gradients on the CPU would fail when strides > ksize.
RELNOTES: Enable support for strides > ksize for pooling operations.
PiperOrigin-RevId: 167327007
Diffstat (limited to 'tensorflow')
-rw-r--r-- | tensorflow/core/kernels/ops_util.cc | 5 | ||||
-rw-r--r-- | tensorflow/core/kernels/ops_util_test.cc | 38 | ||||
-rw-r--r-- | tensorflow/python/kernel_tests/pooling_ops_3d_test.py | 36 | ||||
-rw-r--r-- | tensorflow/python/kernel_tests/pooling_ops_test.py | 58 |
4 files changed, 126 insertions, 11 deletions
diff --git a/tensorflow/core/kernels/ops_util.cc b/tensorflow/core/kernels/ops_util.cc index 130939263b..efacd05dd3 100644 --- a/tensorflow/core/kernels/ops_util.cc +++ b/tensorflow/core/kernels/ops_util.cc @@ -37,11 +37,6 @@ Eigen::PaddingType BrainPadding2EigenPadding(Padding padding) { Status GetBroadcastSize(const int index, const int in_size, const int ksize, const int stride, const int pad_size, int* bindex, int* bsize) { - // Cannot have strides larger than the patch size. - if (stride > ksize) { - return errors::InvalidArgument( - "stride must be less than or equal to kernel size"); - } // Cannot have index beyond the input size. if (index * stride > in_size) { return errors::InvalidArgument( diff --git a/tensorflow/core/kernels/ops_util_test.cc b/tensorflow/core/kernels/ops_util_test.cc index 42ffef6735..9d53882dee 100644 --- a/tensorflow/core/kernels/ops_util_test.cc +++ b/tensorflow/core/kernels/ops_util_test.cc @@ -173,12 +173,6 @@ TEST_F(OpsUtilTest, Get2dOutputSizeVerbose) { VerifyGet2dOutputVerboseSizeValues(pad_struct2, error::OK); } -// Test stride > ksize fails with INVALID_ARGUMENT. -TEST_F(OpsUtilTest, GetBroadcastTest3_1_2_0) { - bcast_struct bcast = {{0, 3, 1, 2, 0}, {0, 3}}; - VerifyBoundaries(bcast, error::INVALID_ARGUMENT); -} - // Test index * stride > in_size fails with INVALID_ARGUMENT. TEST_F(OpsUtilTest, GetBroadcastTestBadIndex) { bcast_struct bcast = {{2, 3, 1, 2, 0}, {0, 3}}; @@ -281,6 +275,38 @@ TEST_F(OpsUtilTest, GetBroadcastTest3_3_3_2) { } } +// in_size = 3, ksize = 1, stride = 2, pad_size = 0 +TEST_F(OpsUtilTest, GetBroadcastTest3_1_2_0) { + bcast_struct bcast[] = { + {{0, 3, 1, 2, 0}, {0, 1}}, + {{1, 3, 1, 2, 0}, {2, 1}}, + }; + for (size_t i = 0; i < sizeof(bcast) / sizeof(bcast[0]); ++i) { + VerifyBcastValues(bcast[i]); + } +} + +// in_size = 3, ksize = 2, stride = 3, pad_size = 0 +TEST_F(OpsUtilTest, GetBroadcastTest3_2_3_0) { + bcast_struct bcast[] = { + {{0, 3, 2, 3, 0}, {0, 2}}, + }; + for (size_t i = 0; i < sizeof(bcast) / sizeof(bcast[0]); ++i) { + VerifyBcastValues(bcast[i]); + } +} + +// in_size = 3, ksize = 2, stride = 3, pad_size = 1 +TEST_F(OpsUtilTest, GetBroadcastTest3_2_3_1) { + bcast_struct bcast[] = { + {{0, 3, 2, 3, 1}, {0, 1}}, + {{1, 3, 2, 3, 1}, {2, 1}}, + }; + for (size_t i = 0; i < sizeof(bcast) / sizeof(bcast[0]); ++i) { + VerifyBcastValues(bcast[i]); + } +} + TEST_F(OpsUtilTest, SanitizeThreadSuffix) { EXPECT_EQ("_aBc123_-___", SanitizeThreadSuffix("/aBc123_- /")); } diff --git a/tensorflow/python/kernel_tests/pooling_ops_3d_test.py b/tensorflow/python/kernel_tests/pooling_ops_3d_test.py index fa1553a3f6..b01fc12953 100644 --- a/tensorflow/python/kernel_tests/pooling_ops_3d_test.py +++ b/tensorflow/python/kernel_tests/pooling_ops_3d_test.py @@ -321,6 +321,15 @@ class PoolingTest(test.TestCase): strides=(1, 1, 1), padding="VALID") + def testMaxPoolGradValidPadding1_2_3d(self): + self._ConstructAndTestGradient( + nn_ops.max_pool3d, + input_sizes=[1, 3, 3, 3, 1], + output_sizes=[1, 2, 2, 2, 1], + window=(1, 1, 1), + strides=(2, 2, 2), + padding="VALID") + def testMaxPoolGradValidPadding2_2_3d(self): self._ConstructAndTestGradient( nn_ops.max_pool3d, @@ -339,6 +348,15 @@ class PoolingTest(test.TestCase): strides=(1, 1, 1), padding="SAME") + def testMaxPoolGradSamePadding1_2_3d(self): + self._ConstructAndTestGradient( + nn_ops.max_pool3d, + input_sizes=[1, 3, 2, 4, 1], + output_sizes=[1, 2, 1, 2, 1], + window=(1, 1, 1), + strides=(2, 2, 2), + padding="SAME") + def testMaxPoolGradSamePadding2_1_3d(self): self._ConstructAndTestGradient( nn_ops.max_pool3d, @@ -375,6 +393,15 @@ class PoolingTest(test.TestCase): strides=(1, 1, 1), padding="VALID") + def testAvgPoolGradValidPadding1_2_3d(self): + self._ConstructAndTestGradient( + nn_ops.avg_pool3d, + input_sizes=[1, 3, 3, 3, 1], + output_sizes=[1, 2, 2, 2, 1], + window=(1, 1, 1), + strides=(2, 2, 2), + padding="VALID") + def testAvgPoolGradValidPadding2_1_3d(self): self._ConstructAndTestGradient( nn_ops.avg_pool3d, @@ -402,6 +429,15 @@ class PoolingTest(test.TestCase): strides=(1, 1, 1), padding="SAME") + def testAvgPoolGradSamePadding1_2_3d(self): + self._ConstructAndTestGradient( + nn_ops.avg_pool3d, + input_sizes=[1, 3, 2, 4, 2], + output_sizes=[1, 2, 1, 2, 2], + window=(1, 1, 1), + strides=(2, 2, 2), + padding="SAME") + def testAvgPoolGradSamePadding2_1_3d(self): self._ConstructAndTestGradient( nn_ops.avg_pool3d, diff --git a/tensorflow/python/kernel_tests/pooling_ops_test.py b/tensorflow/python/kernel_tests/pooling_ops_test.py index da14871c87..9eb1fea803 100644 --- a/tensorflow/python/kernel_tests/pooling_ops_test.py +++ b/tensorflow/python/kernel_tests/pooling_ops_test.py @@ -998,6 +998,20 @@ class PoolingTest(test.TestCase): data_format=data_format, use_gpu=use_gpu) + def _testMaxPoolGradValidPadding1_2(self, data_format, use_gpu): + for pool_func in [gen_nn_ops._max_pool_v2, nn_ops.max_pool]: + self._ConstructAndTestGradient( + pool_func, + input_sizes=[1, 3, 3, 1], + output_sizes=[1, 2, 2, 1], + window_rows=1, + window_cols=1, + row_stride=2, + col_stride=2, + padding="VALID", + data_format=data_format, + use_gpu=use_gpu) + def _testMaxPoolGradValidPadding2_2(self, data_format, use_gpu): for pool_func in [gen_nn_ops._max_pool_v2, nn_ops.max_pool]: self._ConstructAndTestGradient( @@ -1026,6 +1040,20 @@ class PoolingTest(test.TestCase): data_format=data_format, use_gpu=use_gpu) + def _testMaxPoolGradSamePadding1_2(self, data_format, use_gpu): + for pool_func in [gen_nn_ops._max_pool_v2, nn_ops.max_pool]: + self._ConstructAndTestGradient( + pool_func, + input_sizes=[2, 2, 4, 3], + output_sizes=[2, 1, 2, 3], + window_rows=1, + window_cols=1, + row_stride=2, + col_stride=2, + padding="SAME", + data_format=data_format, + use_gpu=use_gpu) + def _testMaxPoolGradSamePadding2_1(self, data_format, use_gpu): for pool_func in [gen_nn_ops._max_pool_v2, nn_ops.max_pool]: self._ConstructAndTestGradient( @@ -1071,10 +1099,12 @@ class PoolingTest(test.TestCase): def testMaxPoolGrad(self): for (data_format, use_gpu) in GetTestConfigs(): self._testMaxPoolGradValidPadding1_1(data_format, use_gpu) + self._testMaxPoolGradValidPadding1_2(data_format, use_gpu) self._testMaxPoolGradValidPadding2_1_6(data_format, use_gpu) self._testMaxPoolGradValidPadding2_1_7(data_format, use_gpu) self._testMaxPoolGradValidPadding2_2(data_format, use_gpu) self._testMaxPoolGradSamePadding1_1(data_format, use_gpu) + self._testMaxPoolGradSamePadding1_2(data_format, use_gpu) self._testMaxPoolGradSamePadding2_1(data_format, use_gpu) self._testMaxPoolGradSamePadding2_2(data_format, use_gpu) self._testMaxPoolGradSamePadding3_1(data_format, use_gpu) @@ -1497,9 +1527,11 @@ class PoolingTest(test.TestCase): def testAvgPoolGrad(self): for (data_format, use_gpu) in GetTestConfigs(): self._testAvgPoolGradValidPadding1_1(data_format, use_gpu) + self._testAvgPoolGradValidPadding1_2(data_format, use_gpu) self._testAvgPoolGradValidPadding2_1(data_format, use_gpu) self._testAvgPoolGradValidPadding2_2(data_format, use_gpu) self._testAvgPoolGradSamePadding1_1(data_format, use_gpu) + self._testAvgPoolGradSamePadding1_2(data_format, use_gpu) self._testAvgPoolGradSamePadding2_1(data_format, use_gpu) self._testAvgPoolGradSamePadding2_2(data_format, use_gpu) self._testAvgPoolGradSamePadding3_1(data_format, use_gpu) @@ -1517,6 +1549,19 @@ class PoolingTest(test.TestCase): data_format=data_format, use_gpu=use_gpu) + def _testAvgPoolGradValidPadding1_2(self, data_format, use_gpu): + self._ConstructAndTestGradient( + nn_ops.avg_pool, + input_sizes=[2, 3, 3, 3], + output_sizes=[2, 2, 2, 3], + window_rows=1, + window_cols=1, + row_stride=2, + col_stride=2, + padding="VALID", + data_format=data_format, + use_gpu=use_gpu) + def _testAvgPoolGradValidPadding2_1(self, data_format, use_gpu): self._ConstructAndTestGradient( nn_ops.avg_pool, @@ -1556,6 +1601,19 @@ class PoolingTest(test.TestCase): data_format=data_format, use_gpu=use_gpu) + def _testAvgPoolGradSamePadding1_2(self, data_format, use_gpu): + self._ConstructAndTestGradient( + nn_ops.avg_pool, + input_sizes=[2, 2, 4, 3], + output_sizes=[2, 1, 2, 3], + window_rows=1, + window_cols=1, + row_stride=2, + col_stride=2, + padding="SAME", + data_format=data_format, + use_gpu=use_gpu) + def _testAvgPoolGradSamePadding2_1(self, data_format, use_gpu): self._ConstructAndTestGradient( nn_ops.avg_pool, |