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