def testLargePoolingRatioThroughGradientError(self): input_shape = (1, 17, 23, 1) input_data = self._GenerateRandomInputTensor(input_shape) pooling_ratio = (1, math.sqrt(13), math.sqrt(7), 1) output_shape = [int(a / b) for a, b in zip(input_shape, pooling_ratio)] overlapping = True pseudo_random = False with self.cached_session() as _: input_tensor = constant_op.constant(input_data, shape=input_shape) output_tensor, unused_a, unused_b = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random=pseudo_random, overlapping=overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) # error_margin and delta setting is similar to avg_pool_grad. error_margin = 1e-4 gradient_error = gradient_checker.compute_gradient_error( input_tensor, input_shape, output_tensor, output_shape, x_init_value=input_data.reshape(input_shape), delta=1e-2) self.assertLess(gradient_error, error_margin)
def testAllInputOptionsThroughGradientError(self): input_shape = (1, 7, 13, 1) input_data = self._GenerateRandomInputTensor(input_shape) pooling_ratio = [1, math.sqrt(2), math.sqrt(3), 1] for pseudo_random in True, False: for overlapping in True, False: with self.cached_session() as _: input_tensor = constant_op.constant(input_data, shape=input_shape) output_tensor, unused_a, unused_b = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random=pseudo_random, overlapping=overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) output_data = output_tensor.eval() output_shape = output_data.shape # error_margin and delta setting is similar to avg_pool_grad. error_margin = 1e-4 gradient_error = gradient_checker.compute_gradient_error( input_tensor, input_shape, output_tensor, output_shape, x_init_value=input_data.reshape(input_shape), delta=1e-2) self.assertLess(gradient_error, error_margin)
def testDifferentTensorShapesThroughGradientError(self): pseudo_random = True overlapping = True pooling_ratio = [1, math.sqrt(3), math.sqrt(2), 1] for num_batches in [1, 2]: for num_rows in [5, 13]: for num_cols in [5, 11]: for num_channels in [1, 3]: input_shape = (num_batches, num_rows, num_cols, num_channels) input_data = self._GenerateRandomInputTensor( input_shape) with self.cached_session() as _: input_tensor = constant_op.constant( input_data, shape=input_shape) output_tensor, unused_a, unused_b = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random=pseudo_random, overlapping=overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) output_data = output_tensor.eval() output_shape = output_data.shape # error_margin and delta setting is similar to avg_pool_grad. error_margin = 1e-4 gradient_error = gradient_checker.compute_gradient_error( input_tensor, input_shape, output_tensor, output_shape, x_init_value=input_data.reshape(input_shape), delta=1e-2) self.assertLess(gradient_error, error_margin)
def _ValidateFractionalAvgPoolResult(self, input_tensor, pooling_ratio, pseudo_random, overlapping): """Validate FractionalAvgPool's result against expected. Expected result is computed given input_tensor, and pooling region defined by row_seq and col_seq. Args: input_tensor: A tensor or numpy ndarray. pooling_ratio: A list or tuple of length 4, first and last element be 1. pseudo_random: Use pseudo random method to generate pooling sequence. overlapping: Use overlapping when pooling. Returns: None """ with self.cached_session() as sess: p, r, c = nn_ops.fractional_avg_pool(input_tensor, pooling_ratio, pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) actual, row_seq, col_seq = sess.run([p, r, c]) expected = self._GetExpectedFractionalAvgPoolResult( input_tensor, row_seq, col_seq, overlapping) self.assertShapeEqual(expected, p) self.assertAllClose(expected, actual)
def testDifferentInputTensorShape(self): """Runs the operation in one session with different input tensor shapes.""" with self.cached_session() as sess: input_holder = array_ops.placeholder(dtypes.float32, [None, None, None, 3]) pooling_ratio = [1, 1.5, 1.5, 1] pseudo_random = False overlapping = False p, r, c = nn_ops.fractional_avg_pool(input_holder, pooling_ratio, pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) # First run. input_a = np.zeros([3, 32, 32, 3]) actual, row_seq, col_seq = sess.run([p, r, c], {input_holder: input_a}) expected = self._GetExpectedFractionalAvgPoolResult( input_a, row_seq, col_seq, overlapping) self.assertSequenceEqual(expected.shape, actual.shape) # Second run. input_b = np.zeros([4, 60, 60, 3]) actual, row_seq, col_seq = sess.run([p, r, c], {input_holder: input_b}) expected = self._GetExpectedFractionalAvgPoolResult( input_b, row_seq, col_seq, overlapping) self.assertSequenceEqual(expected.shape, actual.shape)
def testDifferentTensorShapesThroughGradientError(self): pseudo_random = True overlapping = True pooling_ratio = [1, math.sqrt(3), math.sqrt(2), 1] for num_batches in [1, 2]: for num_rows in [5, 13]: for num_cols in [5, 11]: for num_channels in [1, 3]: input_shape = (num_batches, num_rows, num_cols, num_channels) input_data = self._GenerateRandomInputTensor(input_shape) with self.cached_session() as _: input_tensor = constant_op.constant(input_data, shape=input_shape) output_tensor, unused_a, unused_b = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random=pseudo_random, overlapping=overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) output_data = output_tensor.eval() output_shape = output_data.shape # error_margin and delta setting is similar to avg_pool_grad. error_margin = 1e-4 gradient_error = gradient_checker.compute_gradient_error( input_tensor, input_shape, output_tensor, output_shape, x_init_value=input_data.reshape(input_shape), delta=1e-2) self.assertLess(gradient_error, error_margin)
def testLargePoolingRatioThroughGradientError(self): input_shape = (1, 17, 23, 1) input_data = self._GenerateRandomInputTensor(input_shape) pooling_ratio = (1, math.sqrt(13), math.sqrt(7), 1) output_shape = [int(a / b) for a, b in zip(input_shape, pooling_ratio)] overlapping = True pseudo_random = False with self.cached_session() as _: input_tensor = constant_op.constant(input_data, shape=input_shape) output_tensor, unused_a, unused_b = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random=pseudo_random, overlapping=overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) # error_margin and delta setting is similar to avg_pool_grad. error_margin = 1e-4 gradient_error = gradient_checker.compute_gradient_error( input_tensor, input_shape, output_tensor, output_shape, x_init_value=input_data.reshape(input_shape), delta=1e-2) self.assertLess(gradient_error, error_margin)
def testAllInputOptionsThroughGradientError(self): input_shape = (1, 7, 13, 1) input_data = self._GenerateRandomInputTensor(input_shape) pooling_ratio = [1, math.sqrt(2), math.sqrt(3), 1] for pseudo_random in True, False: for overlapping in True, False: with self.cached_session() as _: input_tensor = constant_op.constant(input_data, shape=input_shape) output_tensor, unused_a, unused_b = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random=pseudo_random, overlapping=overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) output_data = output_tensor.eval() output_shape = output_data.shape # error_margin and delta setting is similar to avg_pool_grad. error_margin = 1e-4 gradient_error = gradient_checker.compute_gradient_error( input_tensor, input_shape, output_tensor, output_shape, x_init_value=input_data.reshape(input_shape), delta=1e-2) self.assertLess(gradient_error, error_margin)
def testDifferentInputTensorShape(self): """Runs the operation in one session with different input tensor shapes.""" with self.cached_session() as sess: input_holder = array_ops.placeholder(dtypes.float32, [None, None, None, 3]) pooling_ratio = [1, 1.5, 1.5, 1] pseudo_random = False overlapping = False p, r, c = nn_ops.fractional_avg_pool( input_holder, pooling_ratio, pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) # First run. input_a = np.zeros([3, 32, 32, 3]) actual, row_seq, col_seq = sess.run([p, r, c], {input_holder: input_a}) expected = self._GetExpectedFractionalAvgPoolResult( input_a, row_seq, col_seq, overlapping) self.assertSequenceEqual(expected.shape, actual.shape) # Second run. input_b = np.zeros([4, 60, 60, 3]) actual, row_seq, col_seq = sess.run([p, r, c], {input_holder: input_b}) expected = self._GetExpectedFractionalAvgPoolResult( input_b, row_seq, col_seq, overlapping) self.assertSequenceEqual(expected.shape, actual.shape)
def _ValidateFractionalAvgPoolResult(self, input_tensor, pooling_ratio, pseudo_random, overlapping): """Validate FractionalAvgPool's result against expected. Expected result is computed given input_tensor, and pooling region defined by row_seq and col_seq. Args: input_tensor: A tensor or numpy ndarray. pooling_ratio: A list or tuple of length 4, first and last element be 1. pseudo_random: Use pseudo random method to generate pooling sequence. overlapping: Use overlapping when pooling. Returns: None """ with self.cached_session() as sess: p, r, c = nn_ops.fractional_avg_pool( input_tensor, pooling_ratio, pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) actual, row_seq, col_seq = sess.run([p, r, c]) expected = self._GetExpectedFractionalAvgPoolResult(input_tensor, row_seq, col_seq, overlapping) self.assertShapeEqual(expected, p) self.assertAllClose(expected, actual)
def _testVisually(self): """Manual test by printing out intermediate result of a small random tensor. Since _GetExpectedFractionalAvgPoolResult is 'automated', it feels safer to have a test case that you can see what's happening. This test will generate a small, random, int 2D matrix, and feed it to FractionalAvgPool and _GetExpectedFractionalAvgPoolResult. """ num_rows = 6 num_cols = 6 tensor_shape = (1, num_rows, num_cols, 1) pseudo_random = False for overlapping in True, False: print("-" * 70) print("Testing FractionalAvgPool with overlapping = {}".format( overlapping)) rand_mat = self._PRNG.randint(10, size=tensor_shape) pooling_ratio = [1, math.sqrt(2), math.sqrt(2), 1] with self.cached_session() as sess: p, r, c = nn_ops.fractional_avg_pool(rand_mat.astype( np.float32), pooling_ratio, pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) tensor_output, row_seq, col_seq = sess.run([p, r, c]) expected_result = self._GetExpectedFractionalAvgPoolResult( rand_mat.astype(np.float32), row_seq, col_seq, overlapping) print("row sequence:") print(row_seq) print("column sequence:") print(col_seq) print("Input:") # Print input with pooling region marked. for i in range(num_rows): row_to_print = [] for j in range(num_cols): if j in col_seq: row_to_print.append("|") row_to_print.append(str(rand_mat[0, i, j, 0])) row_to_print.append("|") if i in row_seq: print("-" * 2 * len(row_to_print)) print(" ".join(row_to_print)) print("-" * 2 * len(row_to_print)) print("Output from FractionalAvgPool:") print(tensor_output[0, :, :, 0]) print("Expected result:") print(expected_result[0, :, :, 0])
def _testVisually(self): """Manual test by printing out intermediate result of a small random tensor. Since _GetExpectedFractionalAvgPoolResult is 'automated', it feels safer to have a test case that you can see what's happening. This test will generate a small, random, int 2D matrix, and feed it to FractionalAvgPool and _GetExpectedFractionalAvgPoolResult. """ num_rows = 6 num_cols = 6 tensor_shape = (1, num_rows, num_cols, 1) pseudo_random = False for overlapping in True, False: print("-" * 70) print("Testing FractionalAvgPool with overlapping = {}".format( overlapping)) rand_mat = self._PRNG.randint(10, size=tensor_shape) pooling_ratio = [1, math.sqrt(2), math.sqrt(2), 1] with self.cached_session() as sess: p, r, c = nn_ops.fractional_avg_pool( rand_mat.astype(np.float32), pooling_ratio, pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) tensor_output, row_seq, col_seq = sess.run([p, r, c]) expected_result = self._GetExpectedFractionalAvgPoolResult( rand_mat.astype(np.float32), row_seq, col_seq, overlapping) print("row sequence:") print(row_seq) print("column sequence:") print(col_seq) print("Input:") # Print input with pooling region marked. for i in range(num_rows): row_to_print = [] for j in range(num_cols): if j in col_seq: row_to_print.append("|") row_to_print.append(str(rand_mat[0, i, j, 0])) row_to_print.append("|") if i in row_seq: print("-" * 2 * len(row_to_print)) print(" ".join(row_to_print)) print("-" * 2 * len(row_to_print)) print("Output from FractionalAvgPool:") print(tensor_output[0, :, :, 0]) print("Expected result:") print(expected_result[0, :, :, 0])
def testIntegerTensorInput(self): """Test FractionalAvgPool works fine when input tensor is integer type. I would have used _ValidateFractionalAvgPoolResult function to automate this process, however, there's rounding issue. It is caused by numpy.mean cast integer input to numpy.float64 for intermediate use. While for fractional_avg_pool, the mean operation is integer division (trucated). So, for this test case, I will hard code a simple matrix. """ pseudo_random = True overlapping = True tensor_shape = (1, 6, 6, 1) # pyformat: disable mat = np.array([ [2, 6, 4, 1, 3, 6], [8, 9, 1, 6, 6, 8], [3, 9, 8, 2, 5, 6], [2, 7, 9, 5, 4, 5], [8, 5, 0, 5, 7, 4], [4, 4, 5, 9, 7, 2] ]) # pyformat: enable with self.cached_session() as sess: # Since deterministic = True, seed and seed2 are fixed. Therefore r, and c # are the same each time. We can have an expected result precomputed. # r = [0, 2, 4, 6] # c = [0, 1, 3, 4, 6] # pyformat: disable expected = np.array([ [6, 5, 3, 5], [5, 5, 4, 5], [5, 4, 7, 5] ]).reshape((1, 3, 4, 1)) # pyformat: enable p, unused_r, unused_c = nn_ops.fractional_avg_pool( mat.reshape(tensor_shape), [1, math.sqrt(3), math.sqrt(2), 1], pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) actual = sess.run(p) self.assertShapeEqual(expected, p) self.assertAllClose(expected, actual)
def testIntegerTensorInput(self): """Test FractionalAvgPool works fine when input tensor is integer type. I would have used _ValidateFractionalAvgPoolResult function to automate this process, however, there's rounding issue. It is caused by numpy.mean cast integer input to numpy.float64 for intermediate use. While for fractional_avg_pool, the mean operation is integer division (trucated). So, for this test case, I will hard code a simple matrix. """ pseudo_random = True overlapping = True tensor_shape = (1, 6, 6, 1) # pyformat: disable mat = np.array([[2, 6, 4, 1, 3, 6], [8, 9, 1, 6, 6, 8], [3, 9, 8, 2, 5, 6], [2, 7, 9, 5, 4, 5], [8, 5, 0, 5, 7, 4], [4, 4, 5, 9, 7, 2]]) # pyformat: enable with self.cached_session() as sess: # Since deterministic = True, seed and seed2 are fixed. Therefore r, and c # are the same each time. We can have an expected result precomputed. # r = [0, 2, 4, 6] # c = [0, 1, 3, 4, 6] # pyformat: disable expected = np.array([[6, 5, 3, 5], [5, 5, 4, 5], [5, 4, 7, 5]]).reshape((1, 3, 4, 1)) # pyformat: enable p, unused_r, unused_c = nn_ops.fractional_avg_pool( mat.reshape(tensor_shape), [1, math.sqrt(3), math.sqrt(2), 1], pseudo_random, overlapping, deterministic=True, seed=self._SEED, seed2=self._SEED2) actual = sess.run(p) self.assertShapeEqual(expected, p) self.assertAllClose(expected, actual)