模型压缩方法分类
如今,庞大的参数量和推理过程中巨大的运算量阻碍着模型落地部署,成为深度学习的技术瓶颈之一。为解决这些问题,深度学习和硬件设计的专家学者针对深度神经网络压缩与加速方法展开了大量的研究。目前,较为有效地降低深度神经网络模型的空间和时间复杂度,达到模型压缩和推理速度的方法包括模型剪枝、知识蒸馏、神经网络结构搜索、张良分解和模型量化(Quantization)等。
**模型剪枝:**通过去除模型中对性能影响较小的部分,从而解决模型过参数问题。根据剪枝粒度可以分为结构化剪枝和非结构化剪枝。非结构化剪枝会带来稀疏计算问题;结构化剪枝格式仍为32位,无法部署到低位宽的硬件设备上。
**知识蒸馏:**使用一个训练好的大网络指导训练一个小模型,小模型效果可比肩大模型。但是知识蒸馏应用于具有softmax损失函数的任务且需要额外设计学生网络结构。
神经网络结构搜索:基于神经网络结构搜索的方法通过算法自动设计神经网络结构。该方法会消耗大量时间和计算资源。
**张量分解:**依据底秩近似,将张量分解为多个尺寸更小的张量,以达到减小神经网络模型存储空间的目的,但是需要特殊格式的DNN硬件加速器。
**模型量化:**基于量化的方法可以通过减少网络模型运算数值的位宽来达到压缩和加速神经网络的目的,从而使深度学习网络具有部署在资源受限、低位宽的边缘设备上。量化方法是一种在模型训练和推理方面都取得巨大成功的方法,在工业界届取得较为成熟的应用。
线性量化
深度神经网络模型存在严重的参数冗余问题,并且所有参数都使用32为浮点数,而实际模型所能用到的精度远远不及32位浮点数所能表达的范围;并且边缘计算设备的数据位宽较低,存储容量有限,针对低位宽的数值计算深度优化可以得到客观的加速效果。神经网络量化通过降低网络模型参数数值表示所需的为宽,可以在不影响模型人物性能情况下在一定程度上达到降低内存容量的效果。
神经网络量化通过某种量化映射将所有权重和激活值从浮点数转化为低位宽的数值表示。量化操作是用一组离散符号或者整数值来近似连续信号的过程,最简单直接的方法就是将连续值通过仿射变换线性地映射到距离最近的整型值上。
主流的神经网络量化形式为线性量化,即利用线性变化函数将浮点数映射到整型集合中。使用线性量化函数好处在于简单直接地将全精度浮点数映射到低位宽的整型数值范围并且两种类型的数据计算过程完全等价,无需修改计算过程。
其中,x为原始浮点数,x_hat为量化后的,位宽为b的整型,S为量化缩放系数。getInt函数表示取整操作,可以为四舍五入函数round或者向上取整函数ceil或者向下取整floor函数。截断函数目的是保证对取整后的数在所要映射的整型范围内,范围大小由位宽b决定。有符号整型范围为 [ − 2 b − 1 + 1 , 2 b − 1 − 1 ] [-2^{b-1}+1, 2^{b-1}-1] [−2b−1+1,2b−1−1],无符号整型范围 [ 0 , 2 b − 1 ] [0 , 2^{b}-1] [0,2b−1]
对称量化与非对称量化
在确定量化函数后,其取之范围也被唯一确定,根据浮点数经过量化和反量化后的取值集合分为对称量化和非对称量化。
1) 对称量化
对称量化是最简单的线性量化形式,一般要求量化的截断阈值(阶段阈值为真实值范围的上下界,不一定是最大最小值)是对称的,同时被量化的数值分布也是对称分布的。
2) 非对称量化
非对称量化的量化后范围和截断阈值是非对称的。这种不对称会导致量化后一些取值无法利用,因此,非对称量化引入了量化零点偏移Z来调整缩放后的范围。
非对称量化适合范围不均衡的数值分布,如输出不平衡的激活函数等。由于引入量化零点偏移,其计算和存储开销会增大。
均匀量化与非均匀量化(非线性量化)
量化方法按照量化步长是否均匀分为均匀量化和非均匀量化。量化步长指的是不同量化等级之间的间距,量化等级为被量化后的值。
线性量化函数建立了一个等距的映射关系,属于均匀量化。如下图,均匀量化中,量化步长d均匀;非均匀量化中,d大小不均匀。
非均匀量化会对真实值x采用长度不同的步长进行划分,通过量化函数得到非均匀的量化结果d。对于如何将真实值划分为非均匀的,以及量化后的范围也是非均匀的是非均匀量化中的重要问题,早期的方法包括聚类,权值共享等量化方法。
对权值和对激活值量化的区别在于:(1)权值有正有负,一般多采用对称量化。目前大多数网络使用 ReLU 作为激活函数,因此得到的激活值都是非负的,对激活值可采用非对称量化。(2)量化一般需要统计数据的分布范围。对于网络权值而言,最大最小值很容易就可以获得。但是对于激活值而言,其范围和输入图片相关,相对应获取范围的方法分别有在线和离线两种处理方式。离线方式需要在部署之前统计激活值的范围,计算得出比例因子,并在之后的部署过程中将该值固定。统计激活值范围的方法有多种,例如通过跑一个小规模的校准数据集统计激活值范围。这种离线收集方式的问题在于,用于统计的数据集和实际推理数据集的分布可能不相同,导致统计的激活值范围不准确,最终影响网络准确率。在线方式则是在网络推理过程中实时计算动态范围。虽然这样得到的结果会更准确,但是需要额外的硬件支持,增加了计算开销,实际应用场景不多。
优化方法
量化过程不可避免的会丢失之前训练好的模型所学到的信息,导致模型在对应任务上性能下降,故在确定了量化方法后,需要对量化函数中的量化参数和原始模型中的参数进行优化,以在一定程度上恢复性能。根据是否要对量化模型重新训练,将优化方法分为量化感知训练(QAT)和后训练量化(PTQ)。
量化感知训练(QAT)
对神经网络的权重和激活值的量化会引入一定误差,这种误差可以视作对原始值的干扰,随着网络层的增加,网络模型的任务损失随之增大。解决该问题的常用方法是剃度下降,通过对量化模型重新训练,令量化模型在优化过程中收敛到新的局部最优点,该方法叫做量化感知训练。
一般量化感知训练步骤如下,在整个训练过程会保留一套全精度权值拷贝,在前向传播过程中,该全精度权值会被量化至目标精度,使用该量化权值计算网络输出以及损失函数。在权值更新时,则会将梯度的微小变化累积到全精度权值上,这样在经过多次更新后,权值才有可能会被量化至相邻的量化等级。在实际训练过程中,一般会使用模拟量化,即所有的操作仍然可以使用全精度数进行计算,会将权值和激活值量化为离散值后再反量化回原本的范围。
量化感知训练会在一些特定位置插入针对权值和激活值的,浮点精度的伪量化节点,用于模拟网络的量化过程。受限于量化函数的离散性,反向传播的梯度无法经由伪量化节点的 Int 算子向后传播。早期方案是使用直通估计器(Straight-Through Estimator,STE)来估计Int算子反向传播时的梯度,将四舍五入等不方便求导的操作的梯度近似为1。但会导致梯度不匹配的情况出现。在量化感知训练中,有两个默认前提条件,首先训练需要访问完整的训练数据集,其次要确定量化操作对输出的影响。
后训练量化(PTQ)
后训练量化不需要对神经网络模型进行重新训练直接将预训练的 FP32 网络转换为定点数网络,并且对训练数据集依赖更小。不需要训练数据或只需要访问少部分无标签图片用于激活值分布统计和校正补偿。PTQ 流程中的一个基本步骤就是为量化器确定量化范围或比例因子。由于 PTQ 的目的就是为了快速量化,因此大部分方法都集中优化单层网络的本地误差,而非考虑整体网络任务的损失。