int8量化

 

感觉深度学习在移动端的全面开花就在这两年了,其实感觉已经开始开花了。

先说说量化是怎么一回事,目前我们在caffe, tensorflow等框架上训练模型(前向和反向)都是使用float 32的,与int 8相比,所需储存空间更大,但是精度更好。

量化目前来讲,有两种方式,一种是通过训练量化finetune原来的模型,另一种是直接对模型和计算进行量化。这篇文章先来讲不使用finetune,直接对训练完毕的模型进行进行量化。

在深度学习中,对float 32进行int 8量化,使其模型尺寸更小、推断更快、耗电更低。唯一的缺点,模型精度会下降。

先比较一下,float 32 和 int 8有什么区别

Dynamic Range(两种数据类型的数值范围)

FP32 -3.4 x 10^38 ~ +3.4 x 10^38

INT8 -128 ~ +127

其实量化过程很简单,更高精度的向低精度的范围进行映射。

int8量化

int8量化

int8量化

当bias=0时,就是正负对称做的一个对称的量化

int8量化

图片来自于《8-bit inference with tensor RT》,版权归nvidia所有

在量化过程中,又可以分两个部分,一是模型参数weights,模型一般可以直接使用No saturation的方式直接进行量化, int8量化 .

另一部分就是计算过程中的值的量化activations,这部分我们就选择Saturate的方法,这种方法就有一个阈值选择的过程。

在《8-bit inference with tensor RT》 文章中,对threshold的选择使用的是相对熵(kl divergence),在离散情况下的相对熵 int8量化

在一个验证数据集上,以一个batch为例,对该batch的每一层计算频率直方图(FP32 histogram H with 2048 bins: bin[ 0 ], ..., bin[ 2047 ])

int8量化

图片来自于《8-bit inference with tensor RT》版权归nvidia所有

当然在这片文章中的量化方法还是比较简单的,对于Resnet、googlenet之类的比较复杂的网络,效果还是不错的,精度损失的比较小,但是对于mobilenet、shufflenet之类的本身比较精简的网络精度损失还是比较明显的,特别是应用在检测网络架构中的时候。

另外一篇google的文章《Quantizing deep convolutional networks for efficient inference: A whitepaper》。这篇论文是在上述的量化方法上进行优化的,对上面的方法有两个方面的补充。

首先提出了一个对称量化和非对称量化的概念,即在公式(1)中的bias,在nvidia的文章中,bias=0(在他的文章中提到并不需要偏置)就是对称量化的概念,0量化后还是0; int8量化 的情况就是非对称量化,但是这其中需要注意的是bias的需要是整型,因为在深度学习的模型中,有太多的0-padding存在了,若是bias非整型,那么在量化过程中会有大量的数值0的精度收到损失。

第二个提出了逐层量化和逐通道量化的概念,从字面非常容易理解两个量化的区别,我们也看到在nvidia的方法中使用了逐层量化的方法,每一层采用同一个阈值来进行量化。逐通道量化就是对每一层每个通道都有各自的阈值,对精度有一个很好的提升。

对量化是阈值的选取计算,这篇文章采用了更简单的方法。对于权重,使用实际的最大和最小值来决定量化参数。对于激活输出,使用跨批(batches)的最大和最小值的滑动平均值来决定量化参数。

最后来看一下效果,文章中只有分类网络,对于检测网络的精度下降的结果,还在实验中。

int8量化

图片来自于《Quantizing deep convolutional networks for efficient inference: A whitepaper》版权归google所有

还有训练中的量化,之后的文章再讲。

上一篇:MXNet 图优化与算子融合


下一篇:reverse的一些常用资料