了解tf.contrib.lite.TFLiteConverter量化参数

了解tf.contrib.lite.TFLiteConverter量化参数,第1张

了解tf.contrib.lite.TFLiteConverter量化参数

仅设置post_training_quantize = True时会发生什么情况?即为什么第一种情况可以正常工作,而第二种情况却没有。

在TF 1.14中,这似乎只是量化存储在磁盘上.tflite文件中的权重。本身并不能将推理模式设置为量化推理。

即,您可以拥有一个tflite模型

float32
该模型具有推断类型,但是
post_training_quantize=True
为了减小磁盘大小和在运行时更快地加载模型,对模型权重进行了量化(使用)。

如何估计第二种情况的均值,标准差和范围参数?

该文档使许多人困惑。让我解释一下研究后得出的结论:

  1. 不幸的是,在TF库和文档中,量化参数/统计具有3种 等效 形式/表示:
    • 一种)
      (mean, std_dev)
    • B)
      (zero_point, scale)
    • C)
      (min,max)
  2. 从B)和A)转换:
    • std_dev = 1.0 / scale
    • mean = zero_point
  3. 从C)转换为A):
    • mean = 255.0*min / (min - max)
    • std_dev = 255.0 / (max - min)
    • 说明:量化统计信息是用于将范围(0,255)映射到任意范围的参数,您可以从2个等式开始:
      min / std_dev + mean = 0
      max / std_dev + mean = 255
      ,然后按照数学公式来获得上述转换公式
  4. 从A)转换为C):
    • min = - mean * std_dev
    • max = (255 - mean) * std_dev
  5. 命名“ mean”和“ std_dev”令人困惑,并且在很大程度上被认为是错误的名词。

要回答您的问题:,如果您的输入图像具有:

  • 范围(0,255)然后
    mean = 0, std_dev = 1
  • 范围(-1,1)然后
    mean = 127.5, std_dev = 127.5
  • 范围(0,1)然后
    mean = 0, std_dev = 255

看起来在第二种情况下模型推断更快,这取决于模型输入是uint8的事实吗?

是的,可能。但是,除非您使用特定硬件的矢量化指令,否则量化模型通常会比较慢。TFLite经过优化,可以为ARM处理器运行那些专用指令。从TF
1.14或1.15开始,如果您是在本地计算机x86
Intel或AMD上运行它,那么如果量化模型运行得更快,我会感到惊讶。[更新:在TFLite的路线图上添加对x86矢量指令的一流支持,以使量化推理比浮点运算更快]

在第一种情况下意味着’量化’:(0.0,0)在第二种情况下意味着’量化’:(0.003921568859368563,0),’量化’:(0.7843137383460999,128)?

这里的格式是

quantization: (scale, zero_point)

在第一种情况下,您仅激活了

post_training_quantize=True
,这不会使模型运行量化推理,因此无需将输入或输出从float转换为uint8。因此,这里的量化统计本质
null
上是,表示为
(0,0)

在第二种情况下,您通过提供激活了量化推理

inference_type =tf.contrib.lite.constants.QUANTIZED_UINT8
。因此,您同时具有输入和输出的量化参数,在将模型输入时将浮点输入转换为uint8以及在输出时将uint8输出转换为浮点输出都需要这些参数。

  • 在输入时,进行转换:
    uint8_array = (float_array / std_dev) + mean
  • 在输出时,执行以下转换:
    float_array = (uint8_array.astype(np.float32) - mean) * std_dev
  • 注意.astype(float32)在python中这是获得正确计算所必需的
  • 请注意,可能会使用其他文本
    scale
    代替,
    std_dev
    因此除法将变为乘法,反之亦然。

另一个令人困惑的事情是,即使您在转换过程中指定

quantization_stats = (mean,std_dev)
get_output_details
will也会返回
quantization: (scale,zero_point)
,不仅形式不同(scale vs std_dev),而且顺序也不同!

现在,要了解输入和输出获得的这些量化参数值,让我们使用上面的公式来推导

(min,max)
输入和输出的实数值()的范围。使用以上公式,我们得到:

  • 输入范围:(
    min = 0, max=1
    是您通过提供来指定的
    quantized_input_stats = {input_node_names[0]: (0.0, 255.0)} # (mean, stddev)
  • 输出范围:
    min = -100.39, max=99.6


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5617027.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存