海思开发:relu、relu6 在量化前后的精度变化及原因思考

一、前言

以前部署 HopeNet 的时候,发现了relu6与relu的差异。具体就是 relu 模型量化后精度下降 14%,relu6 模型量化(指量化前直接替换成relu,再做量化)后精度下降 2.5%。这两个模型除了 backbone、激活函数不一样,其他都一样。所以 relu6 可以减少量化精度损失?因为上面两个模型backbone不一样,所以考虑再进行一个条件更严格的对比实验。

二、实验

特意选了 MobileNet v2,它的激活函数刚好是 relu6,测试数据集类别数是 2,数据集大小为正负类各 500个,精度就是分类的准确率,然后还给每个类别计算了类别精度。我们训练两款模型 MobileNet v2-relu 和 MobileNet v2-relu6 ,它们除了激活函数不同,其余都一样。pytorch 下面训练、测试,因为我的 caffe 不支持 relu6。rgb图片转为bgr格式的图片demo在这里
1. pytoch 推理结果如下:

模型 MobileNet v2-relu
总精度 97.9%
0 类别精度 97.2%
1 类别精度 98.6%
模型 MobileNet v2-relu6
总精度 97.6%
0 类别精度 97.6%
1 类别精度 97.6%

2. 海思 nnie 推理结果

模型 MobileNet v2-relu
总精度 97.7%
0 类别精度 97.0%
1 类别精度 98.4%
模型 MobileNet v2-relu6
总精度 97.8%
0 类别精度 97.6%
1 类别精度 98.0%

注:海思不支持 relu6(勘正一下,后来我在海思上部署relu6成功,相关博客),我是 pytorch 转 caffe 时,直接用 relu 替换的。
由上面数据可见,虽然 MobileNet v2-relu 精度损失不大,但是 relu6 对减少量化精度损失还是有着积极作用。

三、 后言

感觉差距不是很明显,说服力不是很强,考虑以后再做些实验,提高说服力。

四、原因思考

自从发现这个问题而来,就一直在思考背后的原因,虽然该结论还没有得到多个案例的支持,但还是想简单探讨一下,各位老哥看看就好,说的不好可以指出来,我进行修改,谢谢!
一开始思考很久,一直不得门路,后来看量化相关的技术博客时,提到关于权值量化(量化相关博客,这个博客更方便新手学习),想到会不会是:relu 导致权值范围相差过大,而使用 relu6 则缓解了这一现象
所以下面有两个问题需要讨论:
1. 为什么 relu6 能缓解权值相差过大的情况?
2. 为什么权值相差过大会使得量化后精度下降?

先说第一个问题,请出链式法则,
tensor流程图
在这里插入图片描述
上图是 简单的 tensor 流程图,下图是 relu6 的图。
∂ l o s s ∂ w = ∂ l o s s ∂ y ∗ ∂ y ∂ B ∗ ∂ B ∂ w = ∂ l o s s ∂ y ∗ ∂ y ∂ B ∗ A \frac{ {\partial loss}}{ {\partial w}} = \frac{ {\partial loss}}{ {\partial y}} * \frac{ {\partial y}}{ {\partial B}} * \frac{ {\partial B}}{ {\partial w}} = \frac{ {\partial loss}}{ {\partial y}} * \frac{ {\partial y}}{ {\partial B}} * A wloss=ylossBywB=ylossByA
用个简单版本的链式法则公式来解释下,权值相差过大一般是因为权值梯度大小不一引起的,大梯度的 W1 迭代大了点,小梯度的 W2 迭代小了点,这样几个epoch下来,可能使得各个W之间相差过大。
∂ y ∂ B \frac{ {\partial y}}{ {\partial B}} By 是 relu/relu6 的梯度,我们可以看到,A与B之间是线性关系,当B过大时,A也很可能过大,使得梯度 ∂ l o s s ∂ w \frac{ {\partial loss}}{ {\partial w}} wloss过大,最终导致梯度过大出现上面说的情况(以relu为激活函数时)。
而在relu6中,正区间是有隔断的,当B>6时, ∂ y ∂ B \frac{ {\partial y}}{ {\partial B}} By会是0,即当A过大时会使得B大于6,从而使得 ∂ l o s s ∂ w = ∂ y ∂ B = 0 \frac{ {\partial loss}}{ {\partial w}} = \frac{ {\partial y}}{ {\partial B}} = 0 wloss=By=0, 避免了大梯度的产生。

再说说第二个问题——为什么权值相差过大会使得量化后精度下降,这个问题你们看了那个量化相关博客就会更清楚点,我这边举个简单的例子讲下。
卷积权值因为在推理时数值固定,所以一般采用的是非饱和、非对称、逐通道级量化,这三个名词的含义不多做解释了,自己去看→(相关博客1相关博客2)。
在这里插入图片描述

上图就是量化的示意图,假如w绝大部分值在 0 -1 区间(float类型),而现在有部分w值在99-100区间(权值相差100倍),这样量化后的数据基本分布在固定的两个地方(128、255,uint8类型),对卷积权值来说大量的信息被粗暴的压缩,使得模型的表达能力严重下降。而且可以看出有很多区间被浪费掉了,比如 0-127、129-254区间,如果限制权值范围,使得整个区间被好好的利用起来,这样的话权值能够被更加均匀的映射到0-255区间上,使得权值信息更多地被保留,从而减少了量化误差。

猜你喜欢

转载自blog.csdn.net/tangshopping/article/details/112979152
今日推荐