# 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()