aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2017-09-01 14:42:46 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-09-01 14:46:48 -0700
commitfe8905ed992e29467bcf69053dfce07b77f906d3 (patch)
treeb2f5a15efb91a9ac4ba45a851b1831143f17d084 /tensorflow
parentef1286ea349d362e8a214f0e98951586791e0719 (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.cc5
-rw-r--r--tensorflow/core/kernels/ops_util_test.cc38
-rw-r--r--tensorflow/python/kernel_tests/pooling_ops_3d_test.py36
-rw-r--r--tensorflow/python/kernel_tests/pooling_ops_test.py58
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,