keras训练的DenseNet模型的张量流精简转换上的量化性能差异很大

时间:2018-10-29 17:34:44

标签: tensorflow machine-learning keras tensorflow-lite toco

我使用Keras训练了两个模型。两种模型使用相同的体系结构(来自keras_applications.densenet包的DenseNet169实现),但是它们各自具有不同数量的目标类(一种情况下为80个,另一种情况下为200个)。

  • 将两个模型都转换为.pb格式都可以正常工作(推断性能相同)。我使用https://github.com/amir-abdi/keras_to_tensorflow

  • 上的keras_to_tensorflow实用程序
  • 使用TOCO将两个模型转换为.tflite格式都很好(再次,推断性能相同)。

  • 使用TOCO中的量化将80级模型转换为.tflite效果很好(前三位准确性下降了<1%)。

  • 使用TOCO中的量化功能将200级模型转换为.tflite会出现问题(前三位准确性下降了30%)。

对于两个模型,我都使用与TOCO相同的命令行:

toco --graph_def_file frozen_graph.pb \ --output_file quantized_graph.tflite \ --inference_type FLOAT \ --inference_input_type FLOAT \ --output_format TFLITE \ --input_arrays input_1 \ --output_arrays output_node0 \ --quantize True

我的tensorflow版本是1.11.0(虽然我也曾在用于训练的Ubuntu机器上尝试过相同的命令/环境,但通过pip安装在macOS Mojave上,但结果相同)。

对于一个模型而不是另一个模型,如此大的影响推理准确性的原因我完全不知所措。对于相同的两个体系结构/目标类组合的许多不同的培训,这都是正确的。我觉得我一定很想念什么,但我很困惑。

1 个答案:

答案 0 :(得分:1)

这只是一个小小的偷偷摸摸的评论,因为我不确定这是否可以帮上忙,但由于时间太长,我决定将其作为答案...


我的猜测是准确性下降可能是由您网络输出的差异引起的。量化后(顺便说一下,张量流使用fixed-point quantization),您只用256点(8位)玩,而不是float32的全密集范围。

在网络上的大多数博客中,都说量化的主要假设是权重和激活趋于位于较小的值范围内。但是,有一个隐式假设在博客和文献中很少被提及:单个样本上的网络激活应适当地分布在量化范围内

请考虑以下情形,其中假设成立(特定层上单个样本的激活直方图,垂直线是量化点): enter image description here

现在考虑以下情形:第二个假设不成立,但是第一个假设可以仍然保持不变(蓝色是总体价值分布,灰色是给定样本,垂直条是量化点):

enter image description here

在第一种情况下,很好地覆盖了给定样本的分布(具有很多定量点)。在第二个中,只有2个定量点。 类似的事情也可能发生在您的网络上:也许对于80个类别,它仍然有足够的量化点来区分,但是对于200个类别,我们可能还不够...

  

嘿,但这不会影响具有1000个类的MobileNet,甚至不会影响MobileNetV2,这是残留的吗?

这就是为什么我称其为“疯狂的猜测”。也许MobileNet和MobileNetV2的输出差异不如DenseNet。前者在每一层只有一个输入(已经由BN进行了标准化),而DenseNet在各地都有连接,因此它可以具有更大的方差以及对小变化的敏感性,而BN可能没有太大帮助。 >


现在,请尝试以下清单:

  • TensorFlow 上手动收集80和200个模型的激活统计信息,不仅包括输出,还包括内部层。价值是集中在一个领域还是广泛传播?
  • 看看 TensorFlow 模型的单输入激活分布是否很好,或者我们集中在一个地方可能会有一些问题?
  • 最重要的:看看 Quantum TF-Lite 模型的输出是什么?如果如上所述存在方差问题,那么此处将显示最多的内容。

PS:也请分享您的结果,我想很多人都会对解决量化问题感兴趣:)