神经网络量化--从早期的量化算法谈起

(本文首发于公众号,没事来逛逛)

之前写过一系列网络量化相关的文章,它们都出自 Google 在 2018 年发表的一篇论文,目前也是 tflite 和 pytorch 等框架中通用的量化标准。不过,最近有读者在后台问我,说他看到的一些论文和我文章中的方法差别很大,被搞懵了。因此,今天想整理一下网络量化的发展脉络,帮助刚入门的同学更好地理清这里面的来龙去脉。

为什么要模型量化

关于模型量化,最直接的想法当然是把所有浮点运算都转变为定点运算,换言之需要把所有数值从 float 等浮点型上转变为 int16、int8 等整型变量,甚至变成 2bit、3bit 等极低比特表达。要知道一个 float32 的数值需要占据 4 个字节,而 int8 最多一个,不仅内存读取上快了几倍,而且定点运算也会比浮点运算更容易实现硬件加速 (2bit 等极端情况甚至用移位来实现,快到飞起)。

而神经网络里面的数值主要分三种:网络权重、中间的输出特征 (feature map),梯度。如果把权重和特征可以定点化,那推理的时候就可以在 FPGA 等硬件上跑完整个网络,节能又高效,如果梯度也能定点化,那训练的时候也可以提速,总之,量化高效节能环保,好处大大的有。

稳扎稳打派

最开始的时候人们并不知道量化会对网络产生什么影响,因此需要一点点尝试。比如过,先对权重 weight 做量化,看看网络还能不能 work。

典型代表如 MIT 的韩松教授。刚入门模型量化的同学应该都读过他的 Deep Compression 论文,这是集剪枝量化等技术于一身的作品。其中,量化这一步的基本操作如图中所示:

这是一种非常朴素的思想。假设权重的数值是在区间 [-1.08, 2.12] 之间,那一种最简单的量化方法就是找出 -1, 0, 1, 2 这几个整数作为中心,然后把各个权重四舍五入到这几个数即可。这种四舍五入的操作会导致误差 (这也是量化误差的来源),假设有一个输入是 0.5,对应的浮点权重本来是 2.09,结果被我们量化到 2,在前向传播的时候,就会从 0.5 × 2.09 0.5 \times 2.09 0.5×2.09 变成 0.5 × 2 0.5 \times 2 0.5×2。综合起来,每一层前向传播都会累积大量的误差,这些误差会在 loss 上体现出来,又以梯度的形式传回来,最终,更新到原来的浮点权重上。

这种量化的思路相信大部分人都能理解。作为量化上开荒时代的作品,它对落地并不友好 (这种聚类找量化中心的形式不方便硬件加速,同时由于没有对中间的 feature 量化,前向传播其实还是要浮点进行),并且在量化训练上也存在一些难点 (万一权重都在 0~1 之间,那量化后的权重就变成 0 或者 1,信息都丢掉了)。

之后也有一些论文针对它做了一些改进,比如周教授在英特尔做的 Incremental Network Quantization,他们采用的是移位量化,因此会量化到 2 − 1 2^{-1} 21 2 − 2 2^{-2} 22 等一些数值上 (在硬件上可以通过 bitshift 来实现,非常快,不过本质上和量化到 1、2…等意义是一样的)。他们估计是发现之前的方法在量化训练上存在一些问题 (比如直接四舍五入后,在前向传播中信息丢失太多,导致网络的训练优化很困难),因此改进了量化训练方式,采用逐步量化,而不是一口吃成一个胖子,让一部分权重保持全精度来更好地学习量化误差。

当然,这些改进工作并没有做到真正的全量化,对网络中间的 feature 还是采用浮点的形式保存 (为什么都没有对 feature 做量化,可以猜测是网络优化的难度太大),因此落地价值都不算大。

极致压缩派

江湖上其实还有另一伙狂人,追求极致压缩,要用 3 个比特甚至 2 个比特来实现量化。

第一个吃螃蟹的人中,典型的如 Bengio 大佬。他的研究组提出了 Binarized Neural Networks,仅使用 +1 和 -1 来表达所有数值,并且是做到 weight 和 feature 都量化,因此很适合硬件部署 (如果模型效果不

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值