class_docstr: Performs dequantization on an input tensor with affine/linear quantization.
  
  The quantized data comes from the first "input".
  The other parameters -- ``scale``, ``zero_point``, and ``axis`` -- describe how
  unquantized values can be extracted from it,
  using the following equation for affine/linear quantization::
  
      unquantized_data = scale * (input - zero_point)
  
  Parameters
  ----------
  input: tensor<SrcT, [1..]> (Required)
  
  zero_point: const tensor<SrcT, [0..1]> (Optional)
      * The ``zero_point`` can be either a scalar or a vector. If not provided,
        it is assumed to be ``0``.
      * The ``zero_point`` follows similar broadcasting rules and size constraints as ``scale``.
  
  scale: const tensor<DstT, [0..1]> (Required)
      * The ``scale`` can be either a scalar or a vector.
      * If ``scale`` is a vector, for implementation, it is broadcasted to the following shape:
          - The rank of ``scale`` becomes the same as the rank of the input.
          - Constraint: ``size(scale-vector) == input.shape[axis]``.
          - For ``i == axis``, ``scale.shape[i] == input.shape[i]``.
          - For ``i != axis``, ``scale.shape == 1``.
          - For example:
              - Assume ``input.shape = (2, 3, 4, 5)`` and ``axis = 1``.
              - If ``scale`` is a vector, then ``scale.size`` needs to be equal to
                ``input.shape[axis]``; that is, equal to ``3``.
              - This is broadcasted to ``(1, 3, 1, 1)``.
  
  axis: const tensor<int32, []> (Optional)
  
  Returns
  -------
  tensor<DstT, [1..]>
  
  Attributes
  ----------
  SrcT: uint8, int8
  DstT: fp16, fp32
code: def value_inference(self):
      quantized_data = self.input.val
      if self.zero_point is not None:
          zero_point = self.zero_point.val
      else:
          zero_point = (
              np.int8(0)
              if self.input.dtype == types.int8
              else np.uint8(0)
          )
      scale = self.scale.val
      axis = None
      if self.axis is not None:
          axis = self.axis.val
  
      sc = _rank_promoted_to_same_as_data(quantized_data, axis, scale)
      zp = _rank_promoted_to_same_as_data(
          quantized_data, axis, zero_point
      )
      val = sc * (
          quantized_data.astype(np.float32) - zp.astype(np.float32)
      )
      return val.astype(scale.dtype)
  
file_path: coremltools/coremltools/converters/mil/mil/ops/defs/iOS17/quantization_ops.py
imports: import numpy
  from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.input_type import InputSpec, TensorInputType
  from coremltools.converters.mil.mil.operation import VALUE, Operation, precondition
  from coremltools.converters.mil.mil.ops.defs._op_reqs import register_op
  from coremltools.converters.mil.mil.ops.defs.iOS17 import _IOS17_TARGET
label_desc: Use image node_id 2 for calling the dequantize obj's underlying member method code with example usage: obj.value_inference() and returns: val