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]))
示例#2
0
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)
示例#3
0
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)
示例#4
0
    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)