新宝6娱乐app下载-新宝6手机app下载-新宝6官网 > SEO算法 > 专栏 深度学习算法优化系列三 Google CVPR2018 int8量化算法新

专栏 深度学习算法优化系列三 Google CVPR2018 int8量化算法新

admin SEO算法 2020年02月12日

  模型量化仍然属于模型压缩的范畴,而模型压缩的目的是降低模型的内存大小,加快模型推理速度。在这之前,主要有两方面的研究用于减少模型的大小和前向推理的时间。一是在网络结构上的改进,诸如MobileNet,SqueezeNet,ShuffleNet和DenseNet等等。二是量化权重和激活函数,将32位的浮点数用更低位的数来表示,如half-float,int,bit等等。然而这些方法并没有在一个合理的BaseLine基础上进行评估。这些网络的BaseLine几乎都是选在AlexNet,VGG16,GoogleNet这种大型网络,而这些大型网络在设计时为了达到高准确率存在很多容易,所以在压缩这些网络时都有不小的效果提现。其二在于很量化方法没有在真正的硬件上进行有效性证明。有的方法只在权重上进行量化,仅仅关心设备的存储,而不关心计算效率。有的方法如2-bit/3-bit权重网络和bit-shifit网络,它们把权重限制为0或者 ,即把乘法操作用二进制移位来实现。但在某些硬件上,二进制移位实现并不比乘法,加法好。并且,只有当Bit大的时候,乘法操作才显得比较昂贵。从上面的介绍引出这篇论文的目的,即是要将乘法的输入:权重和激活值都量化成比较小的位宽,即int8量化。

  同时,量化一般可以分为两种模式,即训练后量化(post-training-quantizated)以及训练时量化(quantization-aware-training)。训练后量化比较容易理解,即将训练后的模型中的权重从float32量化到int8,并以int8的形式保存,但在实际推理时,还需要反量化为浮点数类型进行计算。这种量化方式在大模型上的效果很好,因为大模型的抗噪能力很强,但在小模型上表现就比较差了。而训练中量化意思是在训练的过程中引入伪量化操作,即在前向传播的时候,采用量化后的权重和激活值,但在反向传播的时候仍然对float类型的权重进行梯度下降,前向推理时全部使用int8的方式进行计算。

  这篇论文提出了一种将float32量化为int8的方法,并给出了一个训练和推理框架,推理框架使得模型可以在能执行整型运算的计算设备上高效运行,训练框架和推理框架相辅相成,可以显著降低量化过程中的精度损失。

  首先,定义 代表量化后的值, 代表原始的 float32 值,新宝6娱乐app下载-新宝6手机app下载-新宝6官网这篇论文抛弃了之前使用查表的方式将浮点数映射为整数的方法,而是直接引入了一个映射关系来表示,如公式(1)所示:

  其中 代表缩放系数, 代表 ,即真实浮点数 映射到整数时所对应的值,和 的数据类型一致。对于 int8 量化,新宝6娱乐app下载-新宝6手机app下载-新宝6官网 就是 8-bit 整数,对于 B-bit 量化, q 就是 B-bit 的实数,对于有 bias 的情况,就固定量化为· 32-bit 的实数。新宝6娱乐app下载-新宝6手机app下载-新宝6官网其中 的计算方式为:

  可以将卷积层的量化过程总结如下,这部分借鉴了一篇CSDN博主的流程,链接放在附录的参考博客1了。卷积层的量化过程表示为:

  值得注意的一点事,如果有连续的层需要进行量化操作时,就没有必要反量化了,如上面的 10-11 步骤,但这很有可能带来乘加累积导致的溢出,所以每层量化似乎似乎是比较稳妥的做法。

  从公式(1)可以看到,每个 中的实数 都表示带有一对参数 和 的实数 。则对实数矩阵 , 做乘法,其结果矩阵的每个实数可以用下面的公式表示:

  可以看到 是式子(3)中唯一不是整数的值,并且经验发现 的值总是在 中,所以可以将 表示为下面的式子:

  其中 是非负整数, 是一个整数。这样实数运算就变成了整数运算,同时 可以用移位运算。这个 就是上面介绍的卷积层量化过程中的右移参数。

  注意,这里还有一个关键点就是在预测阶段,权重矩阵的量化系数 可以通过已有的参数统计出来。而激活层的量化参数是大量训练数据指数移动均值计算出来的,所以这里才会有 没出来,但先使用了 。

  在上面的公式(4)中因为两个矩阵都需要减去各自的零点 Z 值,减法运算后得到的值可能会突破 int8 范围,到时候就需要 int16 来存储,但整个运算为了控制在int8的类型下计算,论文做了下面的变换。

  这样可以有效的避免计算过程中的值溢出 int8 范围。但可以发现,这个等效变换仍然没有改变整个计算的复杂度,都为 。

  前面描述了权重的矩阵计算,但在神经网络中还有偏置 bias 和激活函数的映射,因为 int8 类型的运算完之后的值应该是在 int32 之内的,所以 bias 选择 int32 的类型,这样的选择一是因为 bias 在整个神经网络中只占据极少的一部分,此外 bias 的作用其实非常重要,高精度的 bias 可以降低模型的偏差。因此加上 bias 之后就变成了 int32 ,我们需要再次转换成 int8 类型(反量化),之后再进入到激活中。具体如下图所示:

  得到了 int32 之后的结果后需要再次转换成 int8 类型(反量化),之后再执行激活函数的操作。

  在介绍中提到,后处理量化过程适合大模型,而小模型会导致精度损失比较大。论文认为后处理量化主要存在两点问题:

  因此,论文提出了一种在前向传播阶段模拟量化的方法,反向传播和平常一样,所有的权重和biases都用浮点数保存以微调小变化。具体的量化方法如下:1、 weights再输入进行卷积之前就开始量化,如果有bn层,将bn层融入到weights中。2、 激活在激活函数执行完之后再量化。

  对于上面的量化范围 (a, b) , weight 和 activation 是不一样的,对于 weight 来说很简单,就是该权重中最大最小值,但是对于 activation 是不太一样的, 对于 activation 采用了 EMA (滑动平均)来对输入中的最大最小值计算得到的,但是在训练初期,因为输入的值变化较大,会影响到滑动平均的值,因此在初期不对 activation 做量化,而是在网络稳定之后再引入。

  对于bn层,在训练时是一个单独的层存在,但是在前向推理时为了提升效率是融合到卷积或全连接层的权重和偏置中的,如下图:

  AI 研习社专栏旨在满足有持续创作能力的的知名学者、技术专家、优秀博主、讲师和人工智能人才文字创作和打造专属个人IP的需求。AI 研习社希望能够帮助大咖见证求知,分享洞见~

标签: 算法优化方法