def test_invalid_inputs(self): inputs = constant_op.constant(value=[[1.0], [2.0], [4.0]], dtype=dtypes.float32) with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), "must be rank 1"): self.evaluate( array_ops.fake_quant_with_min_max_vars_per_channel( inputs=inputs, min=[[0.0]], max=[1.0])) with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), "Dimensions must be equal|incorrect size"): self.evaluate( array_ops.fake_quant_with_min_max_vars_per_channel( inputs=inputs, min=[0.0, 0.1], max=[1.0])) with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), "must be rank 1"): self.evaluate( array_ops.fake_quant_with_min_max_vars_per_channel( inputs=inputs, min=[1.0], max=[[1.0]])) with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), "Dimensions must be equal|incorrect size"): self.evaluate( array_ops.fake_quant_with_min_max_vars_per_channel( inputs=inputs, min=[0.0], max=[1.0, 1.1]))
def _FakeQuantWithMinMaxVars(inputs, min_var, max_var, per_channel, num_bits, narrow_range): """Adds a fake quantization operation. Depending on value of per_channel, this operation may do global quantization or per channel quantization. min_var and max_var should have corresponding shapes: [1] when per_channel == False and [d] when per_channel == True. Args: inputs: a tensor containing values to be quantized. min_var: a variable containing quantization range lower end(s). max_var: a variable containing quantization range upper end(s). per_channel: a boolean specifying whether to use per-channel quantization. num_bits: Number of bits to use for quantization, must be between 2 and 8. narrow_range: Whether to use the narrow quantization range [1; 2^num_bits - 1] or wide range [0; 2^num_bits - 1]. Returns: a tensor containing quantized values. """ if per_channel: assert len(min_var.get_shape()) == 1 assert len(max_var.get_shape()) == 1 return array_ops.fake_quant_with_min_max_vars_per_channel( inputs, min_var, max_var, num_bits=num_bits, narrow_range=narrow_range) else: assert min_var.get_shape() == [] # pylint: disable=g-explicit-bool-comparison assert max_var.get_shape() == [] # pylint: disable=g-explicit-bool-comparison return array_ops.fake_quant_with_min_max_vars( inputs, min_var, max_var, num_bits=num_bits, narrow_range=narrow_range)
def _TestOp(self, input_mins, input_maxs, num_bits, narrow_range, expected_nudged_input_mins, expected_nudged_input_maxs, expected_steps): num_channels = len(input_mins) inputs_list = [] expected_list = [] for i in range(num_channels): expected_nudged_input_min = expected_nudged_input_mins[i] expected_nudged_input_max = expected_nudged_input_maxs[i] expected_step = expected_steps[i] inputs_list.append([ expected_nudged_input_min - expected_step, expected_nudged_input_min - 0.01, expected_nudged_input_min, expected_nudged_input_min + 0.01, expected_nudged_input_min + expected_step - 0.01, expected_nudged_input_min + expected_step, expected_nudged_input_min + expected_step + 0.01, expected_nudged_input_max - 0.01, expected_nudged_input_max, expected_nudged_input_max + 0.01, expected_nudged_input_max + expected_step ]) expected_list.append([ expected_nudged_input_min, expected_nudged_input_min, expected_nudged_input_min, expected_nudged_input_min, expected_nudged_input_min + expected_step, expected_nudged_input_min + expected_step, expected_nudged_input_min + expected_step, expected_nudged_input_max, expected_nudged_input_max, expected_nudged_input_max, expected_nudged_input_max ]) inputs = np.transpose(np.array(inputs_list, dtype=np.float32)) expected = np.transpose(np.array(expected_list, dtype=np.float32)) with self.session() as session: with self.test_scope(): input_placeholder = array_ops.placeholder(dtypes.float32, inputs.shape, name="inputs") min_placeholder = array_ops.placeholder(dtypes.float32, (num_channels), name="min") max_placeholder = array_ops.placeholder(dtypes.float32, (num_channels), name="max") outputs = array_ops.fake_quant_with_min_max_vars_per_channel( input_placeholder, min_placeholder, max_placeholder, num_bits=num_bits, narrow_range=narrow_range) result = session.run( outputs, { input_placeholder: inputs, min_placeholder: input_mins, max_placeholder: input_maxs }) self.assertAllCloseAccordingToType(result, expected, rtol=1e-3, atol=1e-5, bfloat16_rtol=0.03)