Additive Powers-of-Two (APoT) Quantization:硬件友好的非均匀量化方法
APoT
本文是电子科大&哈佛大学&新加坡国立联合发表在 ICLR2020 上的一篇非均匀量化(APoT)的工作。本文,在非均匀量化中通过采用Additive Powers-of-Two(APoT)加法二次幂量化,综合考虑了计算上有效性,低比特量化导致的模型精度下降问题。并实现了不错的量化效果!
- 论文题目:Additive Powers-of-Two Quantization: A Non-uniform Discretization for Neural Networks
- 论文链接:https://arxiv.org/pdf/1909.13144v2.pdf
- 论文代码:https://github.com/yhhhli/APoT_Quantization
摘要
本文首先提出了Additive Powers-of-Two(APoT)加法二次幂量化,一种针对钟形和长尾分布的神经网络权重,有效的非均匀性量化方案。通过将所有量化数值限制为几个二次幂相加,这APoT量化有利于提高计算效率,并与权重分布良好匹配。其次,本文通过参数化Clipping函数以生成更好的更新最佳饱和阈值的梯度。最后,提出对权重归一化来调整权重的输入分布,使其在量化后更加稳定和一致。实验结果表明,本文提出的方法优于最先进的方法,甚至可以与全精度模型竞争,因此证明了本文提出的APoT量化的有效性。例如,本文在 ImageNe t上的 3bit 量化 ResNet-34 仅下降了 0.3% 的 Top-1 和 0.2% Top-5 的准确性。
方法
Additive Powers-of-Two量化 (APoT)
三种量化方法示意图
量化表示
代表裁剪阈值。
代表Clip函数,将权重裁剪到
。
中每个元素通过
映射成量化值
代表量化候选数值
代表量化位宽
均匀量化表示
Powers-of-Two (PoT) 量化表示
基于Powers-of-Two (PoT) 的非均匀量化模式有一个好处是在计算过程中可以采用移位的方式代替复杂的乘法运算,因此幂次的非均匀量化可以显著提高计算效率。如下公示所示:
基于Powers-of-Two (PoT) 的非均匀量化十分适配基于钟型的weights形式,可以实现0附近权重集中的位置量化表示多,长尾部分量化表示少。
Additive Powers-of-Two 量化表示
PoT 量化虽然十分适配基于钟型的weights形式,但是,对于增加bit数是没有明显增益。比如,我们将位宽从
设置为
时
范围内的间隔(interval)不会发生变化,只是在
范围进一步缩小间隔。这个问题被定义为 rigid resolution(刚性分辨率)问题。为解决此问题,本文提出了APoT量化表示。
是一个缩放系数,以确保
中的最大级别是
。
称为基位宽,即每个加法项的位宽,
是加法项的数量。
- 当设置了位宽
和基位宽
时,
可由
计算得到。
参数化Clipping函数 (RCF)
传统的STE仅仅对clip函数边界以外的阈值梯度值进行更新,对于边界以内的阈值参数梯度均为零,这不利于寻找最优的clip阈值边界。
针对传统STE梯度约束不完整的问题,本文对权重内外的阈值边界梯度均进行梯度约束,以便于更快更好的训练得到最优阈值。
class _pq(torch.autograd.Function):
@staticmethod
def forward(ctx, input, alpha):
input.div_(alpha) # weights are first divided by alpha
input_c = input.clamp(min=-1, max=1) # then clipped to [-1,1]
sign = input_c.sign()
input_abs = input_c.abs()
if power:
input_q = power_quant(input_abs, grids).mul(sign) # project to Q^a(alpha, B)
else:
input_q = uniform_quant(input_abs, b).mul(sign)
ctx.save_for_backward(input, input_q)
input_q = input_q.mul(alpha) # rescale to the original range
return input_q
@staticmethod
def backward(ctx, grad_output):
grad_input = grad_output.clone() # grad for weights will not be clipped
input, input_q = ctx.saved_tensors
i = (input.abs()>1.).float()
sign = input.sign()
grad_alpha = (grad_output*(sign*i + (input_q-input)*(1-i))).sum()
return grad_input, grad_alpha
权重归一化
权重归一化为裁剪(Clip)和投影(projection)提供了相对一致且稳定的输入分布,这便于在训练过程中更平滑地优化不同层和迭代。此外,将权重的平均值设为零可以使得量化更加对称。权重归一化公式如下,主要是通过权重值减均值除方差完成,使得归一化后的权重分布满足均值为0方差为1。
权重归一化使得训练参数更加一致
APoT量化伪代码
APoT量化伪代码
实验结果
CIFAR-10
CIFAR-10量化结果
ImageNet
ImageNet量化结果-表格
ImageNet量化结果-柱状图
- Python基础知识6:格式化字符、颜色
- 给自定义控件(Web Control)添加事件的几种方法。前两种方法可以不实现IPostBackEventHandler
- 【开源】QuickPager ASP.NET2.0分页控件 v2.0.0.2版本。
- 【开源】我的分页控件正式命名为QuickPager ASP.NET2.0分页控件
- 【开源】QuickPager ASP.NET2.0分页控件V2.0.0.1——分页控件的源码 (二)
- 高级时钟约束
- 【开源】QuickPager ASP.NET2.0分页控件V2.0.0.1——分页控件的源码(一) 主体
- 【开源】QuickPager ASP.NET2.0分页控件V2.0.0.1——支持多种数据库。让分页更加简单。
- IO约束(下)
- 可以通过基类实现的几种功能。vs2008 .net 2.0
- Python基础知识2:字典
- 桶式移位器
- 【开源】QuickPager ASP.NET2.0分页控件V2.0.0.7 增加了一个js函数的分页方式。
- FireEye报告:揭露新型工控系统恶意软件TRITON
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LeetCode85|只出现一次的数字III
- LeetCode84|只出现一次的数字
- LeetCode83|排序矩阵查找
- LeetCode82|翻转字符串里的单词
- LeetCode81|移动零
- LeetCode80|反转字符串中的元音字母
- LeetCode79|平方数之和
- LeetCode91|寻找重复数
- LeetCode90|两个数组的交集
- LeetCode89|在排序数组中查找数字I
- LeetCode88|两数之和IV-输入BST
- LeetCode98|判定字符是否唯一
- LeetCode97|合并两个有序链表
- LeetCode99|数组中出现次数超过一半的数字
- redis源码之hash结构的实现