tf.quantization

2022-09-03 22:05:35 浏览数 (1)

目录

一、tf.quantization

二、tf.quantization.dequantize

三、tf.quantization.fake_quant_with_min_max_args

四、tf.quantization.fake_quant_with_min_max_args_gradient

五、tf.quantization.fake_quant_with_min_max_vars

六、tf.quantization.fake_quant_with_min_max_vars_gradient

七、tf.quantization.fake_quant_with_min_max_vars_per_channel

八、tf.quantization.fake_quant_with_min_max_vars_per_channel_gradient

九、tf.quantization.quantize

十、tf.quantization.quantized_concat

十一、tf.quantization.quantize_and_dequantize


一、tf.quantization

tf.quantization的公共API的名称空间。

函数列表:

  • dequantize(...): 将“输入”张量去量化为浮点张量。
  • fake_quant_with_min_max_args(...): 假量化“输入”张量,类型浮动到相同类型的“输出”张量。
  • fake_quant_with_min_max_args_gradient(...): 为FakeQuantWithMinMaxArgs操作计算梯度。
  • fake_quant_with_min_max_vars(...): 通过全局浮点标量min对浮点类型的“输入”张量进行伪量化。
  • fake_quant_with_min_max_vars_gradient(...): 为FakeQuantWithMinMaxVars操作计算梯度。
  • fake_quant_with_min_max_vars_per_channel(...): 对float类型的“输入”张量进行伪量化,其中一个形状为:[d],
  • fake_quant_with_min_max_vars_per_channel_gradient(...): 为FakeQuantWithMinMaxVarsPerChannel操作计算梯度。
  • quantize(...): 将浮点型的“输入”张量量子化为“T”型的“输出”张量。
  • quantize_and_dequantize(...): 量子化然后去量子化一个张量。
  • quantized_concat(...): 沿一维串联量子化张量。

二、tf.quantization.dequantize

将“输入”张量去量化为浮点张量。

代码语言:javascript复制
tf.quantization.dequantize(
    input,
    min_range,
    max_range,
    mode='MIN_COMBINED',
    name=None
)

[min_range, max_range]是标量浮点数,指定“输入”数据的范围。“mode”属性精确地控制哪些计算用于将浮点值转换为它们的量化等价值。在MIN_COMBINED模式下,张量的每个值都将经历以下过程:

代码语言:javascript复制
if T == qint8: in[i]  = (range(T)   1)/ 2.0
out[i] = min_range   (in[i]* (max_range - min_range) / range(T))

这里range(T) = numeric_limits<T>::max() - numeric_limits<T>::min()

MIN_COMBINED Mode Example

如果输入来自QuantizedRelu6,输出类型为quint8(范围为0-255),但是QuantizedRelu6的可能范围为0-6。因此min_range和max_range值分别为0.0和6.0。对quint8进行去量化将获得每个值,强制转换为float,并乘以6 / 255。注意,如果quantizedtype是qint8,那么该操作将在强制转换之前将每个值增加128。如果模式为“MIN_FIRST”,则使用以下方法:

代码语言:javascript复制
num_discrete_values = 1 << (# of bits in T)
range_adjust = num_discrete_values / (num_discrete_values - 1)
range = (range_max - range_min) * range_adjust
range_scale = range / num_discrete_values
const double offset_input = static_cast<double>(input) - lowest_quantized;
result = range_min   ((input - numeric_limits<T>::min()) * range_scale)

SCALED mode Example

缩放模式匹配QuantizeAndDequantize{V2|V3}中使用的量化方法。如果对模式进行缩放,则不使用输出类型的全范围,而是选择省略对称的最小可能值(例如,输出范围是-127到127,而符号8位量化的输出范围不是-128到127),因此0.0映射到0。我们首先找到张量的值域。我们使用的范围总是以0为中心,所以我们找到m是这样的

代码语言:javascript复制
m = max(abs(input_min), abs(input_max))

我们的输入张量范围是[-m, m]。接下来,我们选择定点量化桶[min_fixed, max_fixed]。如果T有符号,这是

代码语言:javascript复制
  num_bits = sizeof(T) * 8
  [min_fixed, max_fixed] =
      [-(1 << (num_bits - 1) - 1), (1 << (num_bits - 1)) - 1]

否则,如果T是无符号的,则定点范围为

代码语言:javascript复制
[min_fixed, max_fixed] = [0, (1 << num_bits) - 1]

由此计算比例因子s:

代码语言:javascript复制
s = (2 * m) / (max_fixed - min_fixed)

现在我们可以对张量的元素去量化:

代码语言:javascript复制
result = input * s

参数:

  • input:一个张量。必须是下列类型之一:qint8, quint8, qint32, qint16, quint16。
  • min_range:一个类型为float32的张量。可能为输入生成的最小标量值。
  • max_range:类型为float32的张量。可能为输入生成的最大标量值。
  • mode:可选字符串:“MIN_COMBINED”、“MIN_FIRST”、“scale”。默认为“MIN_COMBINED”。
  • name:操作的名称(可选)。

返回值:

  • 类型为浮点32的张量。

三、tf.quantization.fake_quant_with_min_max_args

假量化“输入”张量,类型浮动到相同类型的“输出”张量。

代码语言:javascript复制
tf.quantization.fake_quant_with_min_max_args(
    inputs,
    min=-6,
    max=6,
    num_bits=8,
    narrow_range=False,
    name=None
)

属性(最小值;max]定义输入数据的夹紧范围。输入值量子化为量子化范围([0;2^num_bits - 1]当narrow_range为false且[1;2^num_bits - 1]当为真时),然后反量化,输出为浮点数[min;max)间隔。num_bits是量化的位宽;2到16之间,包括在内。在量化之前,使用以下逻辑调整min和max值。建议取min <= 0 <= max。如果0不在值的范围内,则可能出现意外行为:如果0 < min < max: min_adj = 0和max_adj = max - min.如果min < max < 0: min_adj = min - max和max_adj = 0。如果min <= 0 <= max: scale = (max - min) / (2^num_bits - 1), min_adj = scale * round(min / scale)和max_adj = max min_adj - min。

参数:

  • inputs:类型为float32的张量。
  • min:一个可选的浮点数。默认为6。
  • max:一个可选的浮点数。默认为6。
  • num_bits:一个可选的int.缺省值为8。
  • narrow_range:一个可选的bool。默认值为False。
  • name:操作的名称(可选)。

返回值:

  • 类型为浮点32的张量。

四、tf.quantization.fake_quant_with_min_max_args_gradient

为FakeQuantWithMinMaxArgs操作计算梯度。

代码语言:javascript复制
tf.quantization.fake_quant_with_min_max_args_gradient(
    gradients,
    inputs,
    min=-6,
    max=6,
    num_bits=8,
    narrow_range=False,
    name=None
)

参数:

  • gradients:一个浮点32的张量。FakeQuantWithMinMaxArgs操作之上的反向传播梯度。
  • inputs:类型为float32的张量。作为输入传递给FakeQuantWithMinMaxArgs操作的值。
  • min:一个可选的浮点数。默认为6。
  • max:一个可选的浮点数。默认为6。
  • num_bits:一个可选的int.缺省值为8。
  • narrow_range:一个可选的bool。默认值为False。
  • name:操作的名称(可选)。

返回值:

  • 类型为浮点32的张量。

五、tf.quantization.fake_quant_with_min_max_vars

通过全局浮点标量min对浮点类型的“输入”张量进行伪量化

代码语言:javascript复制
tf.quantization.fake_quant_with_min_max_vars(
    inputs,
    min,
    max,
    num_bits=8,
    narrow_range=False,
    name=None
)

和输出张量的最大值,输出张量的形状与输入张量相同。max]定义输入数据的夹紧范围。输入值量子化为量子化范围([0;2^num_bits - 1]当narrow_range为false且[1;2^num_bits - 1]当为真时),然后反量化,输出为浮点数[min;max)间隔。num_bits是量化的位宽;2到16之间,包括在内。在量化之前,使用以下逻辑调整min和max值。建议取min <= 0 <= max。如果0不在值的范围内,则可能出现意外行为:如果0 < min < max: min_adj = 0和max_adj = max - min.如果min < max < 0: min_adj = min - max和max_adj = 0。如果min <= 0 <= max: scale = (max - min) / (2^num_bits - 1), min_adj = scale * round(min / scale)和max_adj = max min_adj - min。

参数:

  • inputs:类型为float32的张量。
  • min:一个浮点32的张量。
  • max:一个浮点32的张量。
  • num_bits:一个可选的int.缺省值为8。
  • narrow_range:一个可选的bool。默认值为False。
  • name:操作的名称(可选)。

返回值:

  • 类型为浮点32的张量。

六、tf.quantization.fake_quant_with_min_max_vars_gradient

为FakeQuantWithMinMaxVars操作计算梯度。

代码语言:javascript复制
tf.quantization.fake_quant_with_min_max_vars_gradient(
    gradients,
    inputs,
    min,
    max,
    num_bits=8,
    narrow_range=False,
    name=None
)

参数:

  • gradients:一个浮点32的张量。FakeQuantWithMinMaxVars操作之上的反向传播梯度。
  • inputs:类型为float32的张量。作为输入传递给FakeQuantWithMinMaxVars操作的值。最小,最大:量子化区间,标量浮点数。
  • 最小:一个浮点32的张量。
  • max:一个浮点32的张量。
  • num_bits:一个可选的int.缺省值为8。量化的位宽;2到8之间,包括。
  • narrow_range:一个可选的bool。默认值为False。是否量化为2^num_bits - 1个不同的值。
  • name:操作的名称(可选)。

返回值:

张量对象的元组(backprops_wrt_input、backprop_wrt_min、backprop_wrt_max)。

  • backprops_wrt_input:类型为float32的张量。
  • backprop_wrt_min:类型为float32的张量。
  • backprop_wrt_max:一个类型为float32的张量。

七、tf.quantization.fake_quant_with_min_max_vars_per_channel

对float类型的“输入”张量进行伪量化,其中一个形状为:[d],

代码语言:javascript复制
tf.quantization.fake_quant_with_min_max_vars_per_channel(
    inputs,
    min,
    max,
    num_bits=8,
    narrow_range=False,
    name=None
)

[b, d] [b, h, w, d]通过每个通道将形状的min和max浮动到与输入形状相同的‘输出’张量。max]定义输入数据的夹紧范围。输入值量子化为量子化范围([0;2^num_bits - 1]当narrow_range为false且[1;2^num_bits - 1]当为真时),然后反量化,输出为浮点数[min;max)间隔。num_bits是量化的位宽;2到16之间,包括在内。在量化之前,使用以下逻辑调整min和max值。建议取min <= 0 <= max。如果0不在值的范围内,则可能出现意外行为:如果0 < min < max: min_adj = 0和max_adj = max - min.如果min < max < 0: min_adj = min - max和max_adj = 0。如果min <= 0 <= max: scale = (max - min) / (2^num_bits - 1), min_adj = scale * round(min / scale)和max_adj = max min_adj - min。

参数:

  • inputs:类型为float32的张量。
  • min:一个浮点32的张量。
  • max:一个浮点32的张量。
  • num_bits:一个可选的int.缺省值为8。
  • narrow_range:一个可选的bool。默认值为False。
  • name:操作的名称(可选)。

返回值:

  • 类型为浮点32的张量。

八、tf.quantization.fake_quant_with_min_max_vars_per_channel_gradient

为FakeQuantWithMinMaxVarsPerChannel操作计算梯度。

代码语言:javascript复制
tf.quantization.fake_quant_with_min_max_vars_per_channel_gradient(
    gradients,
    inputs,
    min,
    max,
    num_bits=8,
    narrow_range=False,
    name=None
)

参数:

  • gradients:一个浮点32的张量。FakeQuantWithMinMaxVars操作上方的反向传播梯度,形状为:[d]、[b, d]、[b, h, w, d]。
  • inputs:类型为float32的张量。作为输入传递给FakeQuantWithMinMaxVars操作的值,其形状与梯度相同。min, max:量化区间,形状浮点数[d]。
  • min:一个浮点32的张量。
  • max:一个浮点32的张量。
  • num_bits:一个可选的int.缺省值为8。量化的位宽;2到16之间,包括在内。
  • narrow_range:一个可选的bool。默认值为False。是否量化为2^num_bits - 1个不同的值。
  • name:操作的名称(可选)。

返回值:

张量对象的元组(backprops_wrt_input、backprop_wrt_min、backprop_wrt_max)。

  • backprops_wrt_input:类型为float32的张量。
  • backprop_wrt_min:类型为float32的张量。
  • backprop_wrt_max:一个类型为float32的张量。

九、tf.quantization.quantize

将浮点型的“输入”张量量子化为“T”型的“输出”张量。

代码语言:javascript复制
tf.quantization.quantize(
    input,
    min_range,
    max_range,
    T,
    mode='MIN_COMBINED',
    round_mode='HALF_AWAY_FROM_ZERO',
    name=None
)

[min_range, max_range]是标量浮点数,指定“输入”数据的范围。“mode”属性精确地控制哪些计算用于将浮点值转换为它们的量化等价值。“round_mode”属性控制当将浮点值舍入到量子化的等价值时,使用哪种舍入打结算法。在MIN_COMBINED模式下,张量的每个值都将经历以下过程:

代码语言:javascript复制
out[i] = (in[i] - min_range) * range(T) / (max_range - min_range)
if T == qint8: out[i] -= (range(T)   1) / 2.0

这里ic_limits<T>::max() - numeric_limits<T>::min()

MIN_COMBINED Mode Example

假设输入类型为float,可能的范围为[0.0,6.0],输出类型为quint8([0,255])。min_range和max_range值应该指定为0.0和6.0。从float到quint8的量化将把输入的每个值乘以255/6并转换为quint8。如果输出类型是qint8([- 128,127]),则操作将在强制转换之前将每个值再减去128,以便值的范围与qint8的范围一致。如果模式为“MIN_FIRST”,则使用以下方法:

代码语言:javascript复制
num_discrete_values = 1 << (# of bits in T)
range_adjust = num_discrete_values / (num_discrete_values - 1)
range = (range_max - range_min) * range_adjust
range_scale = num_discrete_values / range
quantized = round(input * range_scale) - round(range_min * range_scale)  
  numeric_limits<T>::min()
quantized = max(quantized, numeric_limits<T>::min())
quantized = min(quantized, numeric_limits<T>::max())

这个函数和MIN_COMBINED之间最大的区别是,最小范围先四舍五入,然后再从四舍五入值中减去。在MIN_COMBINED中,引入了一个小偏差,重复的量化和去量化迭代将引入越来越大的误差。

SCALED mode Example

缩放模式匹配QuantizeAndDequantize{V2|V3}中使用的量化方法。如果对模式进行缩放,则不使用输出类型的全范围,而是选择省略对称的最小可能值(例如,输出范围是-127到127,而符号8位量化的输出范围不是-128到127),因此0.0映射到0。我们首先找到张量的值域。我们使用的范围总是以0为中心,所以我们找到m是这样的

代码语言:javascript复制
m = max(abs(input_min), abs(input_max))

我们的输入张量范围是[-m, m]。接下来,我们选择定点量化桶[min_fixed, max_fixed]。如果T有符号,这是

代码语言:javascript复制
  num_bits = sizeof(T) * 8
  [min_fixed, max_fixed] =
      [-(1 << (num_bits - 1) - 1), (1 << (num_bits - 1)) - 1]

否则,如果T是无符号的,则定点范围为

代码语言:javascript复制
[min_fixed, max_fixed] = [0, (1 << num_bits) - 1]

由此计算比例因子s:

代码语言:javascript复制
s = (max_fixed - min_fixed) / (2 * m)

现在我们可以量化张量的元素:

代码语言:javascript复制
result = round(input * s)

需要注意的一件事是,在量化过程中,操作符可能会选择稍微调整请求的最小值和最大值,所以应该始终使用输出端口作为进一步计算的范围。例如,如果请求的最小值和最大值接近相等,它们将被一个小的epsilon值分隔,以防止创建格式不良的量子化缓冲区。否则,您可能会得到所有量子化值都映射到相同浮点值的缓冲区,这将导致必须对其执行进一步计算的操作出现问题。

参数:

  • input:类型为float32的张量。
  • min_range:一个类型为float32的张量。可能为输入生成的最小标量值。
  • max_range:类型为float32的张量。可能为输入生成的最大标量值。
  • T: tf.DTyp:tf.qint8,quint8,qint32,qint16,tf.quint16之一。
  • mode:可选字符串:“MIN_COMBINED”、“MIN_FIRST”、“scale”。默认为“MIN_COMBINED”。
  • round_mode:可选字符串from: "HALF_AWAY_FROM_ZERO", "HALF_TO_EVEN"。默认为“HALF_AWAY_FROM_ZERO”。
  • name:操作的名称(可选)。

返回值:

张量对象的元组(输出,output_min, output_max)。

  • output:T型张量。
  • output_min:一个类型为float32的张量。
  • output_max:一个类型为float32的张量。

十、tf.quantization.quantized_concat

沿一维串联量子化张量。

代码语言:javascript复制
tf.quantization.quantized_concat(
    concat_dim,
    values,
    input_mins,
    input_maxes,
    name=None
)

参数:

  • concat_dim: int32类型的张量。0-D。要连接的维度。必须在[0,rank(值)]范围内。
  • values:包含至少两个具有相同类型的张量对象的列表。要连接的N个张量。它们的级别和类型必须匹配,它们的大小必须在除concat_dim之外的所有维度上匹配。
  • input_mins:一个与类型为float32的张量对象的值长度相同的列表。每个输入张量的最小标量值。
  • input_maxes:一个长度与类型为float32的张量对象的值相同的列表。每个输入张量的最大标量值。
  • name:操作的名称(可选)。

返回值:

张量对象的元组(输出,output_min, output_max)。

  • output:一个张量。具有与值相同的类型。
  • output_min:一个类型为float32的张量。
  • output_max:一个类型为float32的张量。

十一、tf.quantization.quantize_and_dequantize

量子化然后去量子化一个张量。

代码语言:javascript复制
tf.quantization.quantize_and_dequantize(
    input,
    input_min,
    input_max,
    signed_input=True,
    num_bits=8,
    range_given=False,
    round_mode='HALF_TO_EVEN',
    name=None,
    narrow_range=False
)

参数:

  • input:一个量子化和去量子化的张量。
  • input_min:如果range_given=True,则需要在量化表示中表示的最小输入值。
  • input_max:如果range_given=True,则需要在量化表示中表示的最大输入值。
  • signed_input:如果量化是带符号的或无符号的,则为真。
  • num_bits:量子化的位宽。
  • range_given:如果真使用input_min和input_max作为输入范围,则从输入张量中确定min和max。
  • round_mode:将浮点值舍入为量子化值时的舍入模式。
  • name:操作的可选名称。
  • narrow_range:如果为真,则量子化最小值的绝对值与量子化最大值相同,而不是大于1。也就是说,对于8位量化,最小值是-127而不是-128。

返回值:

  • 一个张量。每个元素都是对相应的输入元素进行量化和去量化的结果。

0 人点赞