深度学习模型部署(番外3)神经网络不同层的量化方法

神经网络层量化

批归一化层Batch Normalization(BN层)

关于归一化的原理可以看之前的这篇blog:BatchNorm原理与应用
批归一化在推理过程中会被融合到上一层或者下一层中,这种处理方式被称为批归一化折叠。这样可以减少量化,也可以减少属于的运算和读写,提高推理速度。
例如对于全连接层 y = W X + b y = WX+b y=WX+b后的批归一化层:
y = B a t c h N o r m ( W X + b ) = B a t c h N o r m ( W X ) = γ ( W x − μ σ 2 + ϵ ) + β = γ W x σ 2 + ϵ + ( β − γ μ σ 2 + ϵ ) = W ~ X + b ~ \begin{align} y& = BatchNorm(WX+b) \\ & = BatchNorm(WX) \\ & = \gamma(\frac{Wx-\mu }{\sqrt[]{\sigma^2+\epsilon } } )+\beta \\ & = \frac{\gamma Wx}{\sqrt[]{\sigma^2+\epsilon } } +(\beta-\frac{\gamma \mu}{\sqrt[]{\sigma^2+\epsilon } }) \\ & = \widetilde{W}X+\widetilde{b} \end{align} y=BatchNorm(WX+b)=BatchNorm(WX)=γ(σ2+ϵ Wxμ)+β=σ2+ϵ γWx+(βσ2+ϵ γμ)=W X+b
从而就将BN层融入到了全连接层的参数中
W ~ k , : = γ k W k , : σ k 2 + ϵ , b ~ k = β k − γ k μ k σ k 2 + ϵ . \begin{aligned} \widetilde{\mathbf{W}}_{k,:}& =\frac{\boldsymbol{\gamma}_k\mathbf{W}_{k,:}}{\sqrt{\mathbf{\sigma}_k^2+\epsilon}}, \\ \widetilde{\mathbf{b}}_{k}& =\boldsymbol{\beta}_k-\frac{\boldsymbol{\gamma}_k\boldsymbol{\mu}_k}{\sqrt{\mathbf{\sigma}_k^2+\epsilon}}. \end{aligned} W k,:b k=σk2+ϵ γkWk,:,=βkσk2+ϵ γkμk.

激活函数层

一般线性层之后都会跟一个激活函数层,从底层的角度考虑,如果在线性层计算完后将数据从寄存器放回内存,再取出来进行非线性层计算,这种方法需要进行读取,非常浪费时间,那么是否能考虑把激活函数层也进行量化,让其可以和量化过的线性层同用定点运算,这样就可以不用放回再取出了,可以直接接着运行。激活函数的种类有很多,像ReLU这种比较简单的激活函数,很容易量化,但是像sigmoid这种激活函数就很难量化,需要复杂的支持。如果不能量化,我们需要在激活函数前后各加一个量化器,这样对精度的影响非常大,很多新的激活函数带来的精度提升在量化后会降低很多。
在这里插入图片描述

池化层

不同的池化层,量化方法也不同。
对于最大池化,输出就来自输入中的最大值,所以对于activation不需要进行量化。
但是对于平均池化,计算出的平均值不一定是一个整数,所以要对activation进行量化,但是输入和输出的范围是差不多的,所以可以公用一个量化器。

实现

pytorch对于量化提供了三种方案:

  • Eager Mode quantization:自己选择量化,自己选择融合
  • FX Graph Mode Quantization:提供了自动量化,自动评估,但是跟nn.Module的兼容性需要用户自己负责,比第一种方案自动化程度高一些
  • PyTorch 2 Export Quantization:pytorch2.1新引入的量化方案,自动化程度更高,也是pytorch官方推荐新手用的方案。
    相关介绍的链接:pytorch官方文档
    一个简单训练后静态量化的demo:
import torch

# define a floating point model where some layers could be statically quantized
class M(torch.nn.Module):
    def __init__(self):
        super().__init__()
        # QuantStub 将float tensor转化为量化表示
        self.quant = torch.ao.quantization.QuantStub()
        self.conv = torch.nn.Conv2d(1, 1, 1)
        self.relu = torch.nn.ReLU()
        # DeQuantStub 将量化表示转化为float tensor
        self.dequant = torch.ao.quantization.DeQuantStub()

    def forward(self, x):
        # 自己手动指定量化模型中的量化点
        x = self.quant(x)
        x = self.conv(x)
        x = self.relu(x)
        # 自己决定何时将量化表示转化为float tensor
        x = self.dequant(x)
        return x


model_fp32 = M()

# 模型必须设置为eval模式,以便在量化过程中,模型的行为和量化后的行为一致
model_fp32.eval()

# 模型量化配置,里面包括了默认的量化配置,可以通过`torch.ao.quantization.get_default_qconfig('x86')`获取
# 对于PC端的量化,推荐使用`x86`,对于移动端的量化,推荐使用`qnnpack`
# 其他的量化配置,比如选择对称量化还是非对称量化,以及MinMax还是L2Norm校准技术,都可以在这里指定
model_fp32.qconfig = torch.ao.quantization.get_default_qconfig('x86')

# 手动进行融合,将一些常见的操作融合在一起,以便后续的量化
# 常见的融合包括`conv + relu`和`conv + batchnorm + relu`
model_fp32_fused = torch.ao.quantization.fuse_modules(model_fp32, [['conv', 'relu']])


# 准备模型,插入观察者,观察激活张量,观察者用于校准量化参数
model_fp32_prepared = torch.ao.quantization.prepare(model_fp32_fused)

# 进行校准,这里输入需要使用代表性的数据,以便观察者能够观察到激活张量的分布,从而计算出量化参数
input_fp32 = torch.randn(4, 1, 4, 4)
model_fp32_prepared(input_fp32)


# 将模型转化为量化模型,这里会将权重量化,计算并存储每个激活张量的scale和bias值,以及用量化实现替换关键操作
model_int8 = torch.ao.quantization.convert(model_fp32_prepared)

# 运行量化模型,这里的计算都是在int8上进行的
res = model_int8(input_fp32)

得益于pytorch,onnxruntime,tensorrt等工具,模型量化以及部署已经变得非常简单,但是有些知识我们还是要学,就如闫令琪老师说的:工具的发展可以简化我们工作流程,但是不能简化我们学习的知识,API是API,知识是知识。
觉得有帮助,请点赞+收藏,thanks

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/432159.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EPSON RA8000CE (RTC模块)压电侠

RA8000CE是一个集成了32.768 kHz数字温度补偿晶体振荡器(DTCXO)的RTC模块。它包括各种功能,如具有闰年校正的秒到年时钟/日历,时间警报,唤醒计时器,时间更新中断,时钟输出和时间戳功能,可以在外部或内部事件…

python 蓝桥杯填空题

文章目录 字母数判断列名(进制问题)特殊日期 字母数 由于是填空题,那么寻找的话,就直接让每一个位置都是A,通过计算看看是不是结果大于2022即可 判断列名(进制问题) 这道题目,我们可以往数字进制…

基于“xxx” Androidx平台的驱动及系统开发 之 触摸板篇

目录 一、基于全志 A133 Android10平台,适配1366x768 - ilitek2511触摸1、原理图分析2、驱动移植与适配3、补丁和资源文件 二、基于瑞芯微 RK3566 Android11平台,适配GT9XX触摸1、原理图分析2、补丁及资源文件 三、遇到的问题与解决1、基于amlogic Andro…

Pytorch学习07_torchvision中数据集的使用

torchvision torchvision 是 PyTorch 生态系统中的一个用于计算机视觉任务的包,它提供了一系列用于图像和视频处理的工具和数据集。torchvision 可以帮助你加载、预处理、增强和可视化图像数据,并提供了一些经典的计算机视觉模型和预训练权重&#xff0…

计算机网络——24路由器组成

路由器组成 路由器的结构概况 高层面(非常简化的)通用路由器体系架构 路由:运行路由选择算法/协议 (RIP, OSPF, BGP) - 生成 路由表转发:从输入到输出链路交换数据报 - 根据路由表进行分组的转发 输入端口功能 分布式交换: 根…

SkyWalking链路追踪上下文TraceContext的traceId生成的实现原理剖析

结论先行 【结论】 SkyWalking通过字节码增强技术实现,结合依赖注入和控制反转思想,以SkyWalking方式将追踪身份traceId编织到链路追踪上下文TraceContext中。 是不是很有趣,很有意思!!! 【收获】 skywal…

什么是jwt

jwt是JSON Web Token,由3部分构成: 头部Header:头部包含了两部分,token 类型和采用的加密算法(可为none,后端应限制加密算法,不以这里为准)。 载荷Payload:这部分才是重要…

Linux网络隧道协议IPIP认知(基于Linux network namespace 的 IPIP 隧道通信)

写在前面 博文内容为 Linux 隧道通信 IPIP认知内容涉及:ipip 介绍,一个 ipip 通信 Demo 以及数据帧流转分析理解不足小伙伴帮忙指正 某些人和事,哪怕没有缘分,是路边的风景,可是只要看一眼,依然会让人觉得…

空间直角坐标系、大地坐标系、平面坐标系介绍

空间直角坐标系、大地坐标系、平面坐标系 2017-04-11 13:53 ( 一)空间直角坐标系 空间直角坐标系的坐标原点位于参考椭球的中心,Z轴指向参考椭球的北极,X轴指向起始子午面与赤道的交点,Y轴位于赤道面上切按右手系于X轴呈90度夹角,某点中的坐标可用该点在此坐标系的各…

九型人格测试,3号成就型人格的职业分析

成就型人格(也叫3号人格),在九型人格中,是一种喜欢争强好胜的人格(这跟和平型人格具有强烈的对比性)。这种人格的人,对于一切给自己带来成就感的事情会表现得非常上心,不会有丝毫地疏…

【鸿蒙 HarmonyOS 4.0】多设备响应式布局

一、背景 在渲染页面时,需要根据不同屏幕大小渲染出不同的效果,动态的判断设备屏幕大小,便需要采用多设备响应式布局。这种设计方法能够动态适配各种屏幕大小,确保网站在不同设备上都能呈现出最佳的效果。 二、媒体查询&#xf…

EMO在哪体验?阿里对口型视频生成工具EMO下载地址?阿里巴巴新模型EMO的技术原理

这几天,阿里的对口型视频生成工具EMO火了。根据官方宣传,EMO只需要上传一张图片和一段音频就可以一键生成对口型视频,而且视频中的嘴型还可以与声音匹配。这项技术支持多语言、对话、唱歌以及快速语速的适配,但也可能成为制造虚假…

[两个栈实现队列]

[两个栈实现队列] 一、题目二、思路三、代码 一、题目 二、思路 //思路:两个栈实现队列,栈是先入后出,队列是队尾入,对头出,(先入先出),那么可以这样干,假设一个栈Pushst&#xff0c…

C++ Python网易云音乐播放器

程序示例精选 网易云音乐播放器 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《网易云音乐播放器》编写代码,代码整洁,规则,易读。 学习与应用推荐首选。…

Javaweb之SpringBootWeb案例之自动配置案例的自定义starter实现的详细解析

3.2.4.2 自定义starter实现 自定义starter的步骤我们刚才已经分析了,接下来我们就按照分析的步骤来完成自定义starter的开发。 首先我们先来创建两个Maven模块: 1). aliyun-oss-spring-boot-starter模块 创建完starter模块后,删除多余的文件…

CSS的文本样式属性值,web前端开发规范

正文 介绍下半连接队列 服务器第一次接收到客户端的SYN后,会处于SYN-REVD阶段,此时双方还没有建立完全的连接, 服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称为半连接队列 已经完成三次握手并建立连接&#xff…

html 文字滚动

<marquee> 标签 创建文字滚动的标签 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>wzgd</title></head><body><marquee direction"left" height"30" width"600&q…

图解 TCP 拥塞控制

文章目录 什么是拥塞控制拥塞控制算法慢启动拥塞避免快速恢复 TCP拥塞控制状态机 什么是拥塞控制 拥塞控制是一种 确保网络中的数据包以可持续的速率传输 的机制&#xff0c;避免因为数据包太多而超过网络当前的承载能力&#xff0c;导致网络性能下降&#xff0c;甚至产生大量…

golang 注释插件

Goanno插件 自动生成golang注释,该插件为 Intellij/Goland 中的 golang 提供自动生成注释 如何使用&#xff1f; control command / (for windows: control alt /)&#xff08;生成注释&#xff09;Right click -> Generate -> Goanno&#xff08;生成注释&#x…

【框架学习 | 第一篇】一篇文章读懂MyBatis

文章目录 1.Mybatis介绍1.1Mybatis历史1.2Mybatis特点1.3与其他持久化框架对比1.4对象关系映射——ORM 2.搭建Mybatis2.1引入依赖2.2创建核心配置文件2.3创建表、实体类、mapper接口2.4创建映射文件2.4.1映射文件命名位置规则2.4.2编写映射文件2.4.3修改核心配置文件中映射文件…