神经网络量化与反量化

文章讨论了量化和反量化在图像处理和模型压缩中的作用,指出量化可能导致精度损失,而反量化通常无信息损失。通过线性映射公式介绍了浮点数如何转换为定点整数,并提供了计算scale和zeropoint的方法。文中提供了一个C语言实现的示例,展示了从float32到int8的量化和反量化过程,以及由此产生的精度差异和效率提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、背景知识

二、量化与反量化结果做对比

一、背景知识


量化并不是什么新知识,我们在对图像做预处理时就用到了量化。回想一下,我们通常会将一张 uint8 类型、数值范围在 0~255 的图片归一成 float32 类型、数值范围在 0.0~1.0 的张量,这个过程就是反量化。类似地,我们经常将网络输出的范围在 0.0~1.0 之间的张量调整成数值为 0~255、uint8 类型的图片数据,这个过程就是量化。所以量化本质上只是对数值范围的重新调整,可以「粗略」理解为是一种线性映射。(之所以加「粗略」二字,是因为有些论文会用非线性量化,但目前在工业界落地的还都是线性量化,所以本文只讨论线性量化的方案)。

不过,可以明显看出,反量化一般没有信息损失,而量化一般都会有精度损失。这也非常好理解,float32 能保存的数值范围本身就比 uint8 多,因此必定有大量数值无法用 uint8 表示,只能四舍五入成 uint8 型的数值。量化模型和全精度模型的误差也来自四舍五入的 clip 操作。

这篇文章中会用到一些公式,这里我们用 r 表示浮点实数,q 表示量化后的定点整数。浮点和整型之间的换算公式为:

在这里插入图片描述 其中,S是 scale,表示实数和整数之间的比例关系,Z 是 zero point,表示实数中的 0 经过量化后对应的整数,它们的计算方法为:

  rmax 、 rmin 分别是r的最大值和最小值, qmax、 qmin 同理。这个公式的推导比较简单,很多资料也有详细的介绍,这里不过多介绍。需要强调的一点是,定点整数的 zero point 就代表浮点实数的 0,二者之间的换算不存在精度损失,这一点可以从公式 (2) 中看出来,把 r=0代入后就可以得到 q=Z。这么做的目的是为了在 padding 时保证浮点数值的 0 和定点整数的 zero point 完全等价,保证定点和浮点之间的表征能够一致。

二、量化与反量化结果做对比

#include<stdio.h>
#include<string.h>
#include<math.h>
typedef char int8;


float find_float32_max(float *r)
{
    int len = sizeof(r) / sizeof(float); 
    float tmp=0.0f;
    for(int i=0;i<len;i++)
    {
        if(r[i]>tmp)
        {
            tmp = r[i];
        }  
    }
    return tmp;  
}

float find_float32_min(float *r)
{
    int len = sizeof(r) / sizeof(float); 
    float tmp=r[0];
    for(int i=0;i<len;i++)
    {
        if(r[i]<tmp)
        {
            tmp= r[i];
        }  
    }
    return tmp;  
}

//s 是scale 量化系数
float s_value(float *r,int8 *q)
{
    float r_max = find_float32_max(r);
    float r_min = find_float32_min(r);
    int8 q_max = 127;
    int8 q_min = -128;

    float s = (r_max-r_min)/(q_max-q_min);
    return s;
}

//z是zero point 表示实数中的0经过量化后的整数
float z_value(float *r,int8 *q)
{
    float r_max = find_float32_max(r);
    int8 q_max = 127;
    float s = s_value(r,q);
    float z = round(q_max-r_max/s); //越界了
    return z;
}

int float32_to_int8(float *r,int8 *q,float *s,float *z)
{

    *s = s_value(r,q);
    *z = z_value(r,q);

    printf("s=%f\n",*s);
    printf("z=%f\n",*z);

    int len = sizeof(r) / sizeof(float); 
    for(int i=0;i<len;i++)
        q[i] = (int8)round(r[i]/(*s)+(*z));

    return 0;
}

void float32_to_int8_test()
{
    float r[2]={2.1,8.6};
    int8 q[2];
    float s;  
    float z;
    int i;
    int len = sizeof(r) / sizeof(float); 
    float32_to_int8(r,q,&s,&z);

    printf("quantification result:\n");
    for( i=0;i<len;i++)
        printf("q[%d]=%d ",i,q[i]);

    printf("\n");

    printf("inverse quantization result:\n");
    for(i=0;i<len;i++)
    {
        r[i] =  s*(q[i]-z);
        printf("r[%d]=%f ",i,r[i]);
    }
}

int main()
{
    float32_to_int8_test();
    return 0;
}

输入的在这里插入图片描述

量化后的结果为对应为-128,127 ,反量化后的结果与没量化的初始结果发现精度有略微的损失,但是效率 可以提高四倍。

在这里插入图片描述

<think>好的,我现在需要回答用户关于端到端自动驾驶中的模型量化、前处理量化和后处理反量化的具体实现方法的问题。首先,我得回顾一下用户提供的引用内容,特别是引用3和4,因为它们提到了模型量化和端到端感知模型的相关内容。 用户的问题集中在三个部分:模型量化、前处理量化和后处理反量化的实现方法。我需要先分别解释这三个概念,然后给出具体的实现步骤或方法。同时,要结合引用中的信息,比如引用3提到的将权重和激活值转换为低精度整数,以及模型量化的好处。引用4提到端到端感知模型的架构,可能涉及到数据处理的流程。 首先,模型量化是指将模型的参数从高精度(如FP32)转换为低精度(如INT8),以减少计算量和存储需求。前处理量化可能指的是在输入数据进入模型之前,将其量化为低精度格式。后处理反量化则是将模型的输出从低精度转换回高精度,以便后续处理或执行控制指令。 接下来,我需要考虑具体的实现步骤。例如,前处理量化可能需要归一化数据,然后应用量化参数(如缩放因子和零点)。TensorRT或PyTorch的量化工具可能在这里被用到。模型量化可能涉及训练后量化量化感知训练,需要选择合适的方法。后处理反量化则涉及将量化后的输出乘以缩放因子并加上零点,恢复为浮点数。 还要注意用户提到的端到端自动驾驶系统的整体流程,确保量化反量化步骤无缝衔接,不影响实时性。可能涉及到的工具和框架,如TensorRT、ONNX Runtime,以及量化方法如动态量化、静态量化等需要提及。 需要检查是否有遗漏的细节,比如校准过程的重要性,或者如何处理不同层的量化参数。同时,要确保语言清晰,步骤明确,符合用户要求的结构化回答。最后生成相关问题,可能涉及量化方法的选择、挑战、工具比较等。</think>### 端到端自动驾驶中的模型量化实现方法 #### 一、模型量化的核心作用 模型量化通过将浮点计算转换为低精度整数计算(如INT8),降低模型计算量和存储需求,提升车载计算设备的运行效率[^3]。其实现需结合前处理量化和后处理反量化形成完整闭环。 #### 二、前处理量化实现 1. **输入归一化** 对传感器数据(摄像头/激光雷达)进行标准化处理: $$x_{norm} = \frac{x_{raw} - \mu}{\sigma}$$ 其中$\mu$为均值,$\sigma$为标准差 2. **量化参数计算** 使用校准数据集动态确定缩放因子(scale)和零点(zero_point): ```python scale = (max_value - min_value) / (2^bit_width - 1) zero_point = round(-min_value / scale) ``` 3. **整数映射** 将归一化数据映射到整数范围: $$x_{quant} = clamp(round(x_{norm}/scale) + zero_point, 0, 255)$$ 4. **硬件加速实现** 使用TensorRT的`IInt8EntropyCalibrator2`接口或PyTorch的`torch.quantization.QuantStub()`实现自动化处理[^3] #### 三、模型量化技术 1. **训练后量化(PTQ)** ```python model = torch.quantization.convert(model_fp32) ``` 2. **量化感知训练(QAT)** 在训练中模拟量化误差: ```python qconfig = torch.quantization.get_default_qat_qconfig('fbgemm') model.qconfig = qconfig torch.quantization.prepare_qat(model, inplace=True) ``` 3. **混合精度量化** 对关键层(如注意力机制)保留FP16精度,其他层使用INT8 #### 四、后处理反量化 1. **输出重建** $$y_{dequant} = (y_{quant} - zero_point_{out}) \times scale_{out}$$ 2. **控制指令恢复** 对转向角/油门等控制量进行反归一化: $$control_{actual} = y_{dequant} \times range + min_{value}$$ 3. **时域一致性处理** 加入卡尔曼滤波平滑量化噪声: $$\hat{x}_k = F_k\hat{x}_{k-1} + B_ku_k$$ #### 五、实现示例(PyTorch) ```python class QuantizedAutopilot(nn.Module): def __init__(self): super().__init__() self.quant = torch.quantization.QuantStub() self.conv1 = nn.Conv2d(3, 64, 3) self.dequant = torch.quantization.DeQuantStub() def forward(self, x): x = self.quant(x) x = self.conv1(x) return self.dequant(x) # 量化配置 model.qconfig = torch.quantization.get_default_qconfig('qnnpack') torch.quantization.prepare(model, inplace=True) # 校准过程... torch.quantization.convert(model, inplace=True) ``` #### 六、关键技术挑战 1. 感知-决策联合量化误差控制 2. 时序信号量化中的累积误差消除 3. 多传感器数据量化参数同步 4. 低精度计算下的安全边界保障[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值