20210902:Hisi量化篇-模型择优

本篇主要介绍如何判定自己训练模型的量化损失以及如何选择最优的模型去量化

如有错误和不当之处,望指教!

根据我自己工作遇到的海思量化精度问题,以及如何改善和提升精度,整理记录而成。

模型转换量化的一般流程:

1:训练模型(fp32)

2:模型选优,依据acc或者loss

2:量化模型(int8/fp16)

3:单图比较输出相似度

4:多图评测ROC,验证精度+选择合适阈值(约等指数)

一般在第3或者第4步才发现量化后,精度损失严重,甚至不能使用。

举个亲身例子:

我在训练活体模型,一般会选择指标最优的模型,然后转换:pytorch->onnx->caffe->wk

自信满满,可一部署,瞬间打脸。明明选择最优模型,为啥量化后效果就崩了呢?

最优模型选择

难道我依据acc或者loss选择的模型并不是最优的???

是的,因为我忽略了部署平台的推理精度fp16这个非常重要的考量因素如果一个模型中的权重分布大部分都处在溢出边缘的话,那么模型转换完精度的模型指标可能会大大下降。

为了更加对比的说明,我选择了两个模型:fp32推理都很棒棒,但量化fp16差异很大。为了方便观察,我们选择onnx模型进行比对。

                    没有量化损失模型 A                                                           量化损失较大模型B

20210902:Hisi量化篇-模型择优_第1张图片    20210902:Hisi量化篇-模型择优_第2张图片

 

 只要不溢出精度上限和下限,就没啥问题。对于FP32来说,1e-10是小case。所以两个模型fp32推理都没有问题。我们知道FP16的普遍精度是~5.96e−8 (6.10e−5) … 65504,可以很明显的看到,右侧模型众多数值,已经溢出了fp16的精度下限。所以大概率量化后精度会下降。

这里有关于精度的介绍:https://moocaholic.medium.com/fp64-fp32-fp16-bfloat16-tf32-and-other-members-of-the-zoo-a1ca7897d407

netron方便查看某一层的权重信息,如果想统计整个模型的权重信息该怎么作呢?上代码

    
        onnx_model = onnx.load(onnx_file)
        onnx_graph = onnx_model.graph
        
        node_weight = []

        node_num = len(onnx_graph.node)
        for idx in range(node_num):
            item_node = onnx_graph.node[idx]
            item_name = item_node.name
            item_type = item_node.op_type
            item_input = item_node.input

            if item_type == "Conv":
                # print(item_name, item_type, item_input)
                node_weight.append(item_input[1])

        num_small = 0
        num_total = 0

        for item in onnx_graph.initializer:
            if item.name in node_weight:
                # print(item.name)
                value_w = np.abs(numpy_helper.to_array(item).flatten())
                value_count = np.where(value_w<=1e-5, 1, 0)
                num_small += np.sum(value_count)
                num_total += value_count.shape[0]
                print("name: ", item.name, "  ratio: ", np.sum(value_count)/value_count.shape[0])
        print(num_small, num_total, num_small/num_total)

需要注意的点:pytorch转onnx时,需要注意BN是否融合到Conv层中。就是确定你对比的是conv还是conv+bn。

我们来看看这两个模型的整体信息统计:

                       没有量化损失模型 A                                                           量化损失较大模型B

20210902:Hisi量化篇-模型择优_第3张图片20210902:Hisi量化篇-模型择优_第4张图片

 很显然,模型A权重数值范围是没有问题的,模型B权重数值在网络深层时很多超过精度范围。特别是在最后,层中有超过1/3的权值精度范围不理想。CNN推理的时候,毕竟是累乘效应,微小的损失可能会积累放大,造成量化精度大幅下降。

说了半天,到底如何选择最优模型呢?

需要综合考量:acc + 权值范围

在训练精度可接受的多个模型中,选择权值范围最符合推理平台的那个模型就可以了。

 

 

 

 

 

 

你可能感兴趣的:(Hisi量化,深度学习,HiSi,量化)