• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 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"""Test configs for pool operators."""
16import tensorflow.compat.v1 as tf
17from tensorflow.lite.testing.zip_test_utils import create_tensor_data
18from tensorflow.lite.testing.zip_test_utils import make_zip_of_tests
19from tensorflow.lite.testing.zip_test_utils import register_make_test_function
20
21
22def make_pool_tests(pool_op_in, allow_fully_quantize=False):
23  """Make a set of tests to do average pooling.
24
25  Args:
26    pool_op_in: TensorFlow pooling operation to test  i.e. `tf.nn.avg_pool2d`.
27    allow_fully_quantize: bool, whether fully_quantize is allowed.
28
29  Returns:
30    A function representing the true generator (after curried pool_op_in).
31  """
32
33  pool_op = pool_op_in
34
35  def f(options, expected_tf_failures=0):
36    """Actual function that generates examples.
37
38    Args:
39      options: An Options instance.
40      expected_tf_failures: number of expected tensorflow failures.
41    """
42
43    # Chose a set of parameters
44    test_parameters = [
45        {
46            "ksize": [[2, 1, 1, 2], [1, 1, 1, 1], [1, 1, 2, 1], [1, 10, 11, 1]],
47            "strides": [[2, 1, 1, 2], [1, 1, 1, 1], [1, 1, 2, 1],
48                        [1, 10, 11, 1]],
49            # TODO(aselle): should add a degenerate shape (e.g. [1, 0, 1, 1]).
50            "input_shape": [[], [1, 1, 1, 1], [1, 15, 14, 1], [3, 15, 14, 3]],
51            "padding": ["SAME", "VALID"],
52            "data_format": ["NHWC"],  # TODO(aselle): NCHW  would be good
53            "fully_quantize": [False],
54            "quant_16x8": [False]
55        },
56        {
57            "ksize": [[2, 1, 1, 2], [1, 1, 1, 1], [1, 1, 2, 1], [1, 10, 11, 1]],
58            "strides": [[2, 1, 1, 2], [1, 1, 1, 1], [1, 1, 2, 1],
59                        [1, 10, 11, 1]],
60            # TODO(aselle): should add a degenerate shape (e.g. [1, 0, 1, 1]).
61            "input_shape": [[], [1, 1, 1, 1], [1, 15, 14, 1], [3, 15, 14, 3]],
62            "padding": ["SAME", "VALID"],
63            "data_format": ["NHWC"],  # TODO(aselle): NCHW  would be good
64            "fully_quantize": [True],
65            "quant_16x8": [False]
66        },
67        {
68            "ksize": [[1, 1, 1, 1]],
69            "strides": [[1, 1, 1, 1]],
70            "input_shape": [[1, 1, 1, 1]],
71            "padding": ["SAME", "VALID"],
72            "data_format": ["NHWC"],
73            "fully_quantize": [True],
74            "quant_16x8": [True]
75        }
76    ]
77    # test_parameters include fully_quantize option only when
78    # allow_fully_quantize is True.
79    if not allow_fully_quantize:
80      test_parameters = [
81          test_parameter for test_parameter in test_parameters
82          if True not in test_parameter["fully_quantize"]
83      ]
84
85    def build_graph(parameters):
86      input_tensor = tf.compat.v1.placeholder(
87          dtype=tf.float32, name="input", shape=parameters["input_shape"])
88      out = pool_op(
89          input_tensor,
90          ksize=parameters["ksize"],
91          strides=parameters["strides"],
92          data_format=parameters["data_format"],
93          padding=parameters["padding"])
94      return [input_tensor], [out]
95
96    def build_inputs(parameters, sess, inputs, outputs):
97      if allow_fully_quantize:
98        input_values = create_tensor_data(
99            tf.float32, parameters["input_shape"], min_value=-1, max_value=1)
100      else:
101        input_values = create_tensor_data(tf.float32, parameters["input_shape"])
102      return [input_values], sess.run(
103          outputs, feed_dict=dict(zip(inputs, [input_values])))
104
105    make_zip_of_tests(
106        options,
107        test_parameters,
108        build_graph,
109        build_inputs,
110        expected_tf_failures=expected_tf_failures)
111
112  return f
113
114
115def make_l2_pool(input_tensor, ksize, strides, padding, data_format):
116  """Given an input perform a sequence of TensorFlow ops to produce l2pool."""
117  return tf.sqrt(
118      tf.nn.avg_pool(
119          tf.square(input_tensor),
120          ksize=ksize,
121          strides=strides,
122          padding=padding,
123          data_format=data_format))
124
125
126@register_make_test_function()
127def make_l2_pool_tests(options):
128  make_pool_tests(make_l2_pool)(options, expected_tf_failures=80)
129
130
131@register_make_test_function()
132def make_avg_pool_tests(options):
133  make_pool_tests(
134      tf.nn.avg_pool, allow_fully_quantize=True)(
135          options, expected_tf_failures=160)
136
137
138@register_make_test_function()
139def make_max_pool_tests(options):
140  make_pool_tests(
141      tf.nn.max_pool, allow_fully_quantize=True)(
142          options, expected_tf_failures=160)
143