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)