量化流程分为两部分,权重量化,激活层量化。激活层的量化是关键,而激活层量化的核心,是因数据分布不均需选取一个合适的截断值。
main()
network_prepare() #网络预处理
1.网络预处理,创建一个可运行的网络对象,输入测试图片,为了生成量化blob的校准数据。
weight_quantize() #
quantize_layer.quantize_weight() ##量化权重
2. 量化权重数据,直接采用最大值线性映射。
activation_quantize()#
layer.initial_blob_max() ##初始化最大blob_data.
3. 运行网络,获得每层卷积feature map blob 数据的绝对值的最大值,就是最大blob_data.
layer.initial_blob_distubution_interval()##计算直方图间隔
4. 计算直方图间隔,直接用blob_data除以2048
layer.initial_histograms(blob)##初始化直方图
5. 初始化每层blob data 直方图,直方的个数就是2048
layer.quantize_blob()##计算KL散度
threshold_distribution()###计算threshold_bin
6.计算合适的截断的阈值和激活基准值,首先将blob data直方图截断生成参考直方图p, 长度为[128,2048],生成长度128的量化的直方图quantize_bin,然后将量化的扩展到长度和p一样的长度的q, 计算p,q的KL-divergence,相对熵,使得相对熵最小的阈值就是合适的截断阈值,就可以直接线性映射获得激活基准值。
save_calibration_file()##保存权重缩放系数和激活基准值。
7.保存结果。