模型量化神经网络模型量化简介
Posted AIPlayer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模型量化神经网络模型量化简介相关的知识,希望对你有一定的参考价值。
模型的权重数据一般是float32的浮点数据,所谓量化则是将float32转换为int8的过程。时下很多框架比如nvidia的TensorRT,xilinx的DNNDK,TensorFlow,PyTorch,MxNet 等都提供了量化的功能。
相比于float32的数据,int8在运算时占用更少的内存,而且运算更快,可以更好的将量化的模型部署在低功耗嵌入式设备上,从而将算法落地到手机端以及自动驾驶等应用场景。然而,量化是一个有损的转换过程,量化后的模型会造成准确率的下降。
量化的本质是将float32的数据一一映射到int8,通常使用的是线性映射,有非对称和对称两种模式:
非对称量化
非对称模式下,可以通过比例缩放scale和零点偏移offset两个操作将float32值域内的min/max映射到int8范围[0, 255]。
对称量化
对于对称量化,通过使用min/max的最大绝对值作为量化的数据范围,并以0为对称中心来对in8的范围[-128, 127]进行量化。
两种模式的主要区别在于量化的范围,因为非对称量化时将浮点范围的min/max值映射到了量化范围的min/max值,所以它更好地利用了量化范围。而对称量化则不然,如果浮点的值大部分分布在正数的,那么对称量化会导致一部分量化范围内的值没有被利用,一个典型的例子就是在ReLU的输出全为正数,使用对称量化意味着有一个最高位没有被使用。但是对称量化的优点是计算简单,它并不需要理会offset的额外计算。
问题一,uint8只能表达[0,255]的整数,如何使用256个数来表达数值很宽的float32呢?
有趣的是神经网络的weights往往是集中在一个非常狭窄的范围。所以在实际量化场景中并不需要对float32的所有值都做映射。但是对于float32而言即便是一个很小的范围能够表达的浮点数也是非常多的,所以必然会有多个浮点数被映射成同一个int8整数,从而造成精度的丢失。
问题二,为什么量化之后的模型精度不会下降太多?
一个直觉解释是,神经网络被过度参数化,进而包含足够的冗余信息,裁剪这些冗余信息不会导致明显的准确度下降。相关证据是,对于给定的量化方法,FP32 网络和 INT8 网络之间的准确度差距对于大型网络来说较小,因为大型网络过度参数化的程度更高。
对于一个神经网络模型,可以量化的数据包括输入数据,权重以及激活输出。
目前在工程应用上有两种主流的方式,训练后量化(post-training quantization)和训练时量化或者叫量化感知训练(quantization aware training,即QAT)。
训练后量化
(1)仅量化权重(weights)
仅量化权重是只将权值数据量化到8bits上,根据训练后的权重数据,取出最大最小值,根据量化公式进行量化计算,确定权重的量化参数。
(2)同时量化权重和激活值(activation)
对于激活值的量化,需要预先准备好校准数据集,将校准数据集作为模型的输入进行推理,记录下激活输出,然后取出最大最小值,根据量化公式进行量化计算,从而确定量化参数。
量化感知训练
量化感知训练就是把量化的影响加入到网络的训练当中,从而使训练得到的网络参数能更好地适应量化所带来的精度损失。
整个训练过程中保存浮点权重的副本“weights”,目的是在不损失精度的情况下积累来自梯度的小变化,一旦模型被训练,仅使用量化权值进行推理。在训练期间,conv+relu的操作仍然可以以浮点精确运行,而边界中的“量化”操作wt_quant与act_quant则可以确保离散值的权重和激活。
以上是关于模型量化神经网络模型量化简介的主要内容,如果未能解决你的问题,请参考以下文章