自动化所的一篇文章, 文章地址, 代码地址
文章主要有两个创新点
- 将量化后的weigths进行split, 然后优化每一位bit, 使得目标函数最小, 得到每一位的bit后再将所有位的bit进行stitching
- 在保证计算效率的前提下, 可以对Activation使用per-channel的量化, 论文中叫Error Compensated Activation Quantization(ECAQ)
下面针对这两条分别说明,
Bit-Split and Stitching
- 常规的二进制, 第一位是符号位, 后面的是绝对值, 每一位只能取0或1. split的作用就是把符号位分配给每个bit, 经过split处理, 总位数会少1, 每一位可取值变为-1, 0, 1. 可表示的范围其实没变都是最小位-111, 最大111.
经过这样处理后, 就可以利用论文中的公式进行优化, 优化这块不太懂. 大致思想还是迭代, 每次迭代时, 固定其他值, 然后求解其中某一位的值.
其实我不太懂, 为什么这里split后求解得出的量化值和scale精度就会更好
- conv/fc的计算过程可以表示位 (假设shape为[M, N] shape为[N, C], 则的shape为[M, C]), 经过per_tensor量化后变为其中和均为标量, 经过这样处理后, 计算量较大的变成了 由原来的float计算变为了int型的计算.
当变为per_channel量化后, 上述过程仍适用. 当变为per_channel量化后, 又标量变为向量, 且其维度为M. 但是若对使用per_channel的量化方法, 则的维度为N, 这样的话, 无法继续将原有的浮点计算转为定点计算, 否则数学上无法等价.
ECAQ的主要思想如图, 即对进行per_channel量化, 但是将量化的scale乘到中.
这里在代码实现层面使用了in_scale
和out_scale
, 所以原本的计算过程变为
这里的会乘到对应的W中, 当把乘到后续的W中以后, X的fake quantize将变成
在代码中这里会设置out_scale=1, 也就是X经过Quantization op后的输出为int, 而非平时的Quantization那样, 输出的是近似与float X的值.
该论文的代码需要注意下面一些地方:
- 先对W进行进行ofwa(optimal fixed-point weight approximation) 解出初步最佳值
- 利用layer的input 和 output再进行ofwa解出W的最佳量化值和scale, 并保存为文件
- load量化后的W到model内, 然后使用数据对量化activation
- Weights bitwidth=8时时间较长
- 当使用ECAQ时, 对feature定点后得到β, 此后beta固定, 且此feature以定点后的数值存在
- 默认情况relu后的quantizer是signed
- First and last layer activation quantize bit-width is always 8
- 不会fold BN
- input image 没有定点
- 只在conv前定点
- 从feature map中随机选取点进行量化, 所以结果每次会有所不同
resnet 系列网络的quantization插入位置
mobilenet系列网络的quantization插入位置
实验:
resnet 18和resnet50
基本复现了论文中的结果, 但是代码没有给出ECAQ的实现, 自己实现后, 结果为
A3W8:
float 69.758/89.078
Bit split & stitch: * Acc@1 64.754 Acc@5 85.926
Bit split & stitch + ECAQ: * Acc@1 66.262 Acc@5 86.750
略有提升, 但是不多.
ECAQ在实现时, 对每一个conv做完ECAQ后需是使用乘以后的W作为conv的weights, 并且,与之对应的activation的Quantization的
mobilenet v2
Bit width | accuracy | accuracy after quantize W but not quantize activation
---- | ----- |
A8W8: | * Acc@1 71.644 Acc@5 90.134 | * Acc@1 71.842 Acc@5 90.296
A8W4: | * Acc@1 67.898 Acc@5 88.028 | * Acc@1 63.652 Acc@5 85.112
A4W4: | * Acc@1 36.672 Acc@5 61.942 | * Acc@1 64.240 Acc@5 85.496
A4W4+ECAQ后:
- Acc@1 46.160 Acc@5 71.004 (只对第一层使用ECAQ)
这里很奇怪, 如果对所有层使用ECAQ, 最终结果不理想,
但如果只对第一层使用ECAQ, 绝对精度虽然还不行, 但是相对于原始的量化, 提升很多
只对第一层量化: * Acc@1 46.160 Acc@5 71.004
思考
- 由于量化条件比较宽松( , per_channel, float scale, unsigned), 所以在8bit时精度几乎没有掉. 这篇论文主要在说自己在低比特时效果更好, 但是实验模型都属于比较好量化的, 在mobilenet v2上的效果似乎不是特别好.
- 而且他们在量化时没有fold bn也挺奇怪.
- 从实验来看, per_channel和per_tensor的量化方式, 对于activation来说貌似影响不大, 即使将per_tensor替换为per_channel精度提升似乎并不高