原文:
https://openaccess.thecvf.com/content_ICCV_2019/papers/Nagel_Data-Free_Quantization_Through_Weight_Equalization_and_Bias_Correction_ICCV_2019_paper.pdf
代码(目测是非官方发布,运行起来bug巨多,慎重,但是写的确实还不错):
https://github.com/jakc4103/DFQ
这篇论文全称是《Data-Free Quantization Through Weight Equalization and Bias Correction》,来自于高通人工智能研究院,不久前被ICCV2019接收,后面简称DFQ。该论文提出了一种不需要额外数据来finetune恢复精度的离线8bit量化方法,它利用了relu函数的尺寸等价缩放的特性来调整不同channel的权重范围,并且还能纠正量化过程中引入的偏差,使用方法也很简单,只需要调用一个API就可以,该量化方法在图像分类、语义分割和目标检测中都很有效。其实本质上这篇论文就是讲如何利用激活函数ReLU的数学性质,均衡相邻两层权重各通道的数据范围,让per-layer的量化方法能融合per-channel的优势,又不需要在硬件上承担额外开销,最大化离线量化的效果。但是论文的想法还是基于简单情况做的考虑,真正应用上的局限性还是存在的,不过总的看完感觉想法还是蛮新颖的,在一些方面具有启发性,所以还是想陈述一下自己看完后的理解。
通常我们用各种现有成熟的深度学习框架,如TensorFlow、Pytorch或mxnet等搭建网络模型时,参数和中间运行数据都是默认为float32类型的,然而在移动嵌入式设备上,由于内存大小、功耗等限制,直接部署原始的浮点网络是不切实际的,所以就需要对原始浮点模型进行压缩,减少参数所需的内存消耗,通常的方法有剪枝、知识蒸馏、量化、矩阵分解,其中量化方法是使用最为普遍的,因为将32bit的参数量化为8bit,需要消耗的内存直接就缩减到了原始的1/4,而其他方法针对不同任务,不同模型,在满足性能要求的情况下实际能节省多少资源都是无法保证的。
一个32bit的浮点tensor量化为INT8(范围[0,255],也可以量化到[-128,127])只需要4步:缩放、取整、偏移和溢出保护,如下所示:
8bit量化器(来自Google量化白皮书)
最后de-quantization的操作有两个作用:计算量化误差、用于恢复精度的finetune训练比如一个tensor的浮点范围是[-1,1],那么缩放系数就是255/2=127.5(equ. 1用的步长,和缩放系数互为倒数),缩放之后的tensor是[-127.5,127.5],取整是[-127,128],偏移是让浮点的0能够对应一个int8的整数,防止0填充出现误差,选取的时候也会尽量使得浮点最小值对应int8的0,所以这里z=127,偏移之后可以使得tensor是[0,255],溢出保护之后仍然是[0,255]。de-quantization回去的话可以看到量化的tensor恢复回来变成了[-127/127.5, 128/127.5],与原始的[-1,1]存在一些偏差,说明量化的过程是不可逆的,必定会存在量化误差,这个误差是四舍五入操作导致的。
回到这篇DFQ论文,我们分析一下他要解决的问题和作出的贡献
MobileNet v2
DFQ流程
示意图
具体实验结果可以看论文的Experiment,一句话描述就是量化后的效果能超过per-channel的方法,且逼近FP32的模型,更厉害的是还能推广到语义分割和目标检测等常见视觉任务上面,reviewers看完应该就没话说了。
实验结果
总的来说这个论文的工作很完整,从提出问题,总结前人方法和归类目前已有的方法,通过数学推导来提出自己的解决方法(而非调参),到对比实验,ablation study,最后推广到其他任务,最后的附录也是很好的,从论文的完整度写作上是非常值得借鉴的。但我感觉这篇论文还存在以下局限性:
在这里插入图片描述
最后说说带来的启发吧,轻量级网络如MobileNet,ShuffleNet系列的直接离线量化效果其实不是很好,因为本身网络的冗余度就很低了,不像AlexNet, GoogleNet,ResNet这样巨无霸网络,说实话有些量化论文拿这些冗余网络来做对比实验真的是一言难尽。
趣图
目前针对轻量级网络直接量化效果差的解决办法是quantization-aware training,就是在FP32模型训练收敛之后,再加入量化的操作,继续进行finetune,这个过程还是比较耗时,且在一些情况下还需要一些调参技巧,如BN操作中的moving_mean和moving_variance要重新校正还是直接冻结等,且在一些深度学习框架上提供模型压缩与量化工具也是更倾向于一键直接离线量化,要加入量化训练的话还是稍微麻烦一些。所以如果有更好的离线量化方法的话,只需要给定一个FP32模型文件,就能得到一个性能不错的量化网络是最好的选择。这个论文带来的启发是直接在数学上考虑量化误差,并且利用已有的信息将误差来源大的项进行公式上的融合,比如上下层的权重逐通道范围均衡,使得每一层的权重各个通道之间的范围接近。朝着这个方法应该还可以做一些改进什么的吧。以上就是我对本篇论文的解读和拙见,非官方复现的代码因为代码bug太多,实在debug不下去了,没能跑出相应的效果,不过最近又在偷偷更新,而且加入了很多看不懂的操作(明明Data-Free,咋还开始疯狂load数据了???)。