1.浮点和定点
数据类型有int,float,double。一般认为int是定点,float和double是浮点,但这样是不准确的。
1.1定点数
定点数:小数点的位置是固定的。所以即便是小数,只要小数点位置固定,也可以是定点数,这就是定点小数:
定点小数的小数固定在最高有效位之前,而定点整数的小数固定在最低有效位之后:
定点小数表示小数点后的部分:
(二十六)通俗易懂理解——浮点与定点的计算机表示及互转 - 知乎
机器数的定点表示与浮点表示_定点表示法和浮点表示法-CSDN博客
1.2浮点数
对于又有整数部分,又有小数部分的数,也可以记录小数点位置,然后分别使用定点数表示。但我们有更好的表示方法,那就是浮点数。
相比于定点数是按照小数点前后分开之后分别用二进制表示,浮点数也是把bit分成两段,但不是直接表示数值,而是科学计数法的指数和前面的系数:
一般以2为底,M是尾数,E是阶码。定点数中两段bit的长度是固定的,浮点数的长度根据其数据类型也是固定的。下面是IEEE 754标准:
阶码位宽 | 尾数位宽 | 总bit数 | |
float | 8 | 24 | 32 |
double | 11 | 53 | 64 |
对于float,虽然阶码和尾数的长度都固定,但是对应的数据值的小数点其实是不固定的:
这就解释了为什么说浮点数的小数点是不固定的。浮点数没有受小数点位置不可控的影响,抓住了变中的不变,成功的使用固定长度的bit表示了常见的小数。
2.定点化
如果浮点数的取值范围比较稳定,可以考虑转换为定点数。因为定点数的计算效率更高,有的硬件平台也只支持定点数的计算指令。转换为定点数后,还可以更直观方便地进行精度的取舍,比如舍弃更低的小数位,降低了内存。
对浮点数a,如果取值范围在[0,16),在定点数中可以分配4bit表示整数部分。对于16bit的内存,预留一位表示符号位,所以留给小数部分的还有11bit,所以可以保留11位小数精度。此时的定点小数使用Q格式表示就是Q11.
最后往往把小数点移动到最后,所以
0100100110111100(2)
3.量化
在确定了模型结构后,每次训练模型的参数都会更新。而模型参数(包括卷积核和偏置)都是浮点数。深度学习中,一般使用FLOPs(Floating Point Operations)来衡量一次前向传播所需的浮点运算次数。
模型量化(Model Quantization)就是通过某种方法将浮点模型转为定点模型。既然本质上是定点化,那么模型量化的好处和定点类似,都是损失精度的代价下,有更快的速度,更小的内存,更小的功耗。
以常见32bit浮点型到8bit为例,模型大小直接变成了原来的1/4,更重要的是因为使用了整型,可以使用SIMD指令集,而SIMD在移动端的优化已经非常充分了,速度可以加快2~4倍。
3.1 对什么量化
量化的对象是模型,模型以参数的形式来表示。那么模型量化就是压缩参数吗?是,又不完全是。
使用更低bit进行量化肯定会减少它所能表达的范围,所以可以搭配一些参数量压缩的算法。事实上,模型量化一开始就是为了压缩模型参数,韩松ICLR2016使用K-Means聚类,以类中心代替属于该类的所有样本,低bit只需要对类中心表示,从而可以使得保留更多的空间来表示更多的其他数据。