本文主要聊一聊深度学习模型量化中对激活函数的处理方式。
之前已经写过几篇关于模型量化的文章:《【模型推理】谈谈几种量化策略:MinMax、KLD、ADMM、EQ》、《【模型推理】谈谈模型量化组织方式》,里面对一些常用的量化算法及量化的组织方式进行了一些介绍,有兴趣的同学可以查阅。这里主要说一下模型中的激活函数特别是非线性激活函数的量化方式。
RELU 函数比较特殊,在 Conv 后跟着 RELU 后,一般会进行融合量化,其中 RELU 这种分段线性函数可以用 clip 函数截断处理进行量化,但是有许多激活函数是非线性的,无法进行截断处理,那么非线性激活函数该如何量化呢?其实非线性激活函数在很多框架中是不会进行量化的,若非要量化,可以采用查表法、泰勒展开法。
1、查表法
查表法的思路在运算性能低或者没有专门的非线性函数指令的单板机上常常被使用。对于神经网络中非线性激活函数的量化中查表法该如何使用呢?
任何一个非线性激活函数在进行量化时,都可以用如下数学表达式进行等效:
上述式子中,很多情况下 f() 这个函数是无法彻底用整型运算代替的,而查表法的思想是基于输入 qx 在被量化后为 int8 类型,其值域为有限集合[-2^7, 2^7-1],因此,用查表代替运算时,我们可以预先算好任何 qx 所对应的量化值:
实际推理过程中,我们预先计算好的表其长度为 256,假设表的第 128 位数的指针为 Y128,那么取出经过非线性函数的量化值是个很简单的取址操作,如下所示:
以下分别是 sigmoid 和 mish 激活函数经过模拟出来的浮点数,其输入分布为在 [-4, 4] 的平均分布时使用 KL 散度量化算法进行量化后的曲线图:
2、泰勒展开
对可导函数在某点 x0 进行泰勒展开,该函数在该点必须是无限可导的。那么其展开式如下:
将量化公式代入上述式子,可得到如下的量化等效式:
这样就实现了使用泰勒展开方法对非线性激活函数进行量化,但是可想而知,这种通过这样方法来进行量化的方法缺陷很多,其中最为严重就是量化精度误差与运算耗时,所以这种量化方式不一定适合实际的部署。
以上聊了一下深度学习模型中的非线性激活函数的量化方法,有问题欢迎讨论。