blob: 243d946174b40bddc4366ed735b5cb7c67ae6309 [file] [log] [blame]
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Functional tests for quantized operations."""
import numpy as np
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.ops import array_ops
from tensorflow.python.platform import test
class QuantizedOpsTest(test.TestCase):
def __init__(self, method_name="runTest"):
super(QuantizedOpsTest, self).__init__(method_name)
def testQuantizeOp(self):
expected_output = [1, 1, 2, 127, 255, 255]
with self.session(use_gpu=False) as sess:
x = constant_op.constant(
[1.0, 1.25, 1.75, 127.0, 255.0, 500.0],
shape=[6],
dtype=dtypes.float32)
x_min = 0.0
x_max = 255.0
op = array_ops.quantize(x, x_min, x_max, dtypes.quint8, mode="MIN_FIRST")
value = self.evaluate(op)
self.assertArrayNear(expected_output, value.output, 0.1)
def testDequantizeOp(self):
expected_output = [1.0, 2.0, 4.0, 8.0, 16.0, 255.0]
inp = np.array([1, 2, 4, 8, 16, 255]).astype(np.uint8)
with self.session(use_gpu=False) as sess:
x = constant_op.constant(inp, shape=[6], dtype=dtypes.quint8)
x_min = 0.0
x_max = 255.0
op = array_ops.dequantize(x, x_min, x_max, mode="MIN_FIRST")
value = self.evaluate(op)
self.assertArrayNear(expected_output, value, 0.1)
def testAxis(self):
# Generates a tensor of the specified `shape` using values from `values`
# scaled by (slice_idx + 1) along `axis` dimension.
def scale_per_slice(shape, axis, values):
# Note: repeats the values if the shape is larger than values.
out = np.take(values, np.remainder(np.arange(np.prod(shape)),
len(values))).reshape(shape)
if axis is not None:
scale_shape = [1] * len(shape)
scale_shape[axis] = shape[axis]
out *= np.arange(1, shape[axis] + 1).reshape(scale_shape)
return out
shape = np.array([2, 3, 4, 5])
values = np.array([-1, -0.5, 0, 0.3, 0.8, 0.555, 0.5], dtype=np.float32)
quant_values = np.array([-128, -64, 0, 38, 102, 71, 64], dtype=np.int32)
for axis in [None, 0, 1, 2, 3]:
inputs = constant_op.constant(scale_per_slice(shape, axis, values))
expected_quantized = scale_per_slice(shape, None, quant_values)
if axis is None:
min_range, max_range = -1.0, 0.8
else:
num_slices = shape[axis]
min_range, max_range = [], []
for slice_idx in range(num_slices):
min_range.append(-1.0 * (slice_idx + 1))
max_range.append(0.8 * (slice_idx + 1))
quantized = self.evaluate(
array_ops.quantize(
inputs,
min_range,
max_range,
T=dtypes.qint8,
mode="SCALED",
round_mode="HALF_TO_EVEN",
axis=axis)).output
self.assertAllEqual(quantized, expected_quantized)
if axis is not None:
quantized = self.evaluate(
array_ops.quantize(
inputs,
min_range,
max_range,
T=dtypes.qint8,
mode="SCALED",
round_mode="HALF_TO_EVEN",
axis=(axis - 4))).output
self.assertAllClose(quantized, expected_quantized)
if __name__ == "__main__":
test.main()