概述
在资源和内存受限的移动或者 IoT 平台上,对深度学习模型进行推理时进行模型量化很重要。
Google 提出的 MobileNet V1 模型极大降低了模型模型参数量和内存占用,但是一个缺陷就是 MobileNet V1 中使用的深度分离卷积,在进行量化时造成了极大的量化精度损失。下表所示,在直接对 MobileNet V1 进行训练后 8 bit 量化后,在 ImageNet 数据集上的分类精度从 70.50% 下降到 1.80%,量化基本不可用。
基于此,作者首先发现 MobileNet V1 中的量化误差是由其中的 BN 层和 ReLU6 层带来的,随后提出了一种适合于量化的深度分离卷积结构,极大降低了量化误差。
经典量化流程
首先在这里提到的量化都指训练后量化,即直接对浮点模型进行量化而不进行额外的训练操作。
下图所示,在一个经典的量化流程里面,首先模型的浮点型权重都被转化为 8 位整形。然后推理时,在输入到一个定点运算操作符之前,浮点型输入先被转化为 8 位无符号整形,经过这些操作符会输出一个 32 位结果,然后通过激活重采样重新转化为 8 位整形输出到下一个运算操作符。
在 TensorFlow 中,量化是基于一个均分分布进行的。给定一个浮点表示 xfloat,它对应的 8 bit 量化表示 xquant8 可以表示为:
其中:
上式中 Δx 表示量化步长,b 是 bit 位宽度,对于 8 bit 量化 b=8。δx 是一个偏置值,使得浮点 0 可以被正确地表示。xmax 和 xmin 是特征层浮点最大和最小值。
基于上面的定义,一个量化卷积操作的计算步骤就如下:
进一步的,给定上一步骤输出的最大和最小值,对这个 32 位输出进行重量化:
在这个量化过程中,图 1 中的五个过程,每个过程都可能存在量化误差损失。
MobileNet V1 量化损失原因分析
MobileNet V1 中存在大量的 DepthWise 分离卷积,这些 DepthWise 卷积在每个通道上分别进行,然而用于量化的最大最小值却是在所有通道里面获取的。某个通道中的离群值就可能极大增加模型的量化误差。
下图所示,6个离群值 α(BN 操作中的缩放系数) 极大增加了量化值范围,这些离群值使得量化位都浪费在保存这些大值上,而小值的表示就被压缩了。
改进方法
基于这样的发现,进行针对性的改进就相对容易了:
- 移除分离卷积中的 BN 和 ReLU6 层;
- 使用 ReLU 替换剩余的 ReLU6;
- 对分离卷积权重加入 L2 正则化损失。
最终的模型结构如下表所示:
结果及结论
基于上述修改后的模型结构,MobileNet V1 的量化损失基本上消失,使得量化模型可用。最重要的是发现了深度分离卷积中不同通道数据可能具有不同分布,对整个层使用一个全局的量化因子将会极大降低该层的表征能力,这也是使用分离卷积后进行量化精度极大降低的直接原因。