2.2 动态范围的常用计算方法

news2024/12/28 18:50:08

1. 动态范围的常用计算方法

动态范围(Dynamic
Range)指的是输入数据中数值的范围,计算动态范围是为了确定量化时使用的比特位数(还是抽象😂)。个人理解:考虑到输入数据可能存在数据分布不均,即有些数据偏离过大。而过大的偏离值,会影响求得的scale,进而影响量化的精度。因此,合理选取数据中的范围,去除偏离值,获得更好的Scale,毕竟Scale会影响到整个量化的精度。

常用的动态范围计算方法方法:

  • Max方法:在对称量化中直接取输入数据中的绝对值的最大值作为量化的最大值。这种方法简单易用,但容易受到噪声等异常数据的影响,导致动态范围不准确。
  • Histogram方法:统计输入数据的直方图,根据先验知识获取某个范围内的数据,从而获得对称量化的最大值。这种方法可以减少噪声对动态范围的影响,但需要对直方图进行统计,计算复杂度较高。
  • Entropy方法:将输入数据的概率密度函数近似为一个高斯分布,以最小化熵作为选择动态范围的准则。这种方法也可以在一定程度上减少噪声对动态范围的影响,但需要对概率密度函数进行拟合和计算熵,计算复杂度较高。

对称量化和非对称量化的选择与动态范围的计算方法有一定的关系:

  • 对称量化要求量化的最大值和最小值的绝对值相等,可以采用Max方法或Histogram方法进行计算。
  • 非对称量化则可以采用Entropy方法进行计算,以最小化量化后的误差。

下面将对Histogram方法和Entropy方法进行详细介绍

2. Histogram

2.1 直方图的定义

直方图(histogram) 是统计学中常用的一种图形,它将数据按照数值分组并统计每组数据的出现频率,然后将频率用柱状图的方式表示出来。直方图通常用于描述一组数据的分布情况,可以帮助人们了解数据的特征,例如数据的中心位置、离散程度、对称性、峰态等。直方图如下图所示:

在这里插入图片描述
生成直方图的代码:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.randn(1000)

plt.hist(data, bins=50)

plt.title("histgram")
plt.xlabel("value")
plt.ylabel("freq")
# plt.savefig("histgram.png", bbox_inches="tight")
plt.show()

2.2 基于Histogram的动态范围实现

为什么要使用Histogram来计算动态范围?
主要在于直方图统计了数据出现的频率,它可以将数据按照一定的区间进行离散化处理,并计算每个区间中数据点的数量。这种方法相对于Max方法来说,能够更好地反映数据的分布情况,从而更准确地评估数据的动态范围。

算法流程
我们假设数据服从正态分布,即离散点在两边,我们可以通过从两边向中间靠拢的方法,去除离散点,类似于双指针的方法,算法具体流程如下:

  • 首先,统计输入数据的直方图和范围
  • 然后定义左指针和右指针分别指向直方图的左边界和右边界
  • 计算当前双指针之间的直方图覆盖率,如果小于等于设定的覆盖率阈值,则返回此刻的左指针指向的直方图值,如果不满足,则需要调整双指针的值,向中间靠拢
  • 如果当前左指针所指向的直方图值大于右指针所指向的直方图值,则右指针左移,否则左指针右移
  • 循环,直到双指针覆盖的区域满足要求

基于上述算法流程的示例代码:

def scale_cal(x):
    max_val = np.max(np.abs(x))
    return max_val / 127
# histogram_range函数是基于数据直方图计算缩放因子的。
# 该函数先将数据进行直方图统计。然后,使用双指针算法去除数据直方图中的离散点。最后,通过剩余数据的动态范围计算出缩放因子。
def histogram_range(x):
    hist, range = np.histogram(x, 100)
    total = len(x)
    left  = 0
    right = len(hist) - 1
    limit = 0.99
    while True:
        cover_percent = hist[left:right].sum() / total
        if cover_percent <= limit:
            break

        if hist[left] > hist[right]:
            right -= 1
        else:
            left += 1
    
    left_val = range[left]
    right_val = range[right]
    dynamic_range = max(abs(left_val), abs(right_val))
    return dynamic_range / 127

if __name__ == "__main__":
    np.random.seed(1)
    data_float32 = np.random.randn(1000).astype('float32')
    # print(f"input = {data_float32}")

    scale = scale_cal(data_float32)
    scale2 = histogram_range(data_float32)
    print(f"scale = {scale}  scale2 = {scale2}")

Histogram方法虽然能够解决Max方法中的离散点噪声问题,但是使用数据直方图进行动态范围的计算,要求数据能够比较均匀地覆盖到整个动态范围内。

  • 如果数据服从类似正态分布,则直方图的结果具有参考价值,因为此时的数据覆盖动态范围的概率较高。
  • 但如果数据分布极不均匀或出现大量离散群,则直方图计算的结果可能并不准确。此时可考虑其它的动态范围计算方法。

3. Entropy

3.1 Entropy的定义

Entropy方法是一种基于概率分布的动态范围计算方法,通过计算概率分布之间的KL散度来选择合适的动态范围。

在模型量化中,通常所用的熵(Entropy)是指量化后的输出值的熵,即量化后的概率分布。因此,使用熵方法计算动态范围就是在计算量化后的概率分布。那么我们该如何度量量化前后的误差呢?可以使用KL散度。

在概率论或信息论中,KL散度(Kullback-Leibler divergence)又称为相对熵(relative entropy),是描述两个概率分布P和Q差异的一种方法。公式如下:
在这里插入图片描述

KL散度值越小,代表两种分布越相似,量化误差越小;反之,KL散度值越大,代表二种分布差异越大,量化误差越大。

3.2 基于Entropy的动态范围实现

算法流程

Entropy方法中使用了直方图和概率分布的方法,进而计算动态范围。其流程如下:

  • 统计直方图分布。首先,对于待量化的数据,统计其数值分布情况,得到数据的直方图
  • 生成p分布和q分布
  • 对p和q进行归一化。将p和q的概率分布进行归一化,使其满足概率分布的性质
  • 计算p和q的KL散度。使用KL散度方法,计算p和q两个概率分布之间的距离,作为衡量量化误差的指标。KL散度越小表示两个分布越相似,因此在动态范围的选择中,KL散度越小的分布更加合适

在量化操作中,动态范围通常是由P和Q两个概率分布的取值范围决定的。P分布表示原始数据在浮点数表示下的取值范围,Q分布则表示对应的量化数据的取值范围。因此,Entropy方法计算P和Q的KL散度,是为了得到最优的Q分布,而最优的Q分布代表量化数据的最优取值范围,量化数据的最优取值范围和原始数据的取值范围都知道了,那么最优的Scale就确定下来了。

示例代码一

下面是通过生成的两组随机数据使用Entropy方法估计数据的动态范围的示例代码:

import numpy as np
import matplotlib.pyplot as plt
# 首先定义了一个计算KL散度的函数cal_kl,用于计算两个概率分布P和Q之间的KL散度
def cal_kl(p, q):
    KL = 0
    for i in range(len(p)):
        KL += p[i] * np.log(p[i]/q[i])
    return KL
# 定义了一个kl_test函数,用于使用Entropy方法来估计数据的动态范围。
# 在kl_test中,先随机生成概率分布y,将其归一化后计算与输入的概率分布x之间的KL散度,如果小于阈值,则认为当前的概率分布y最优,结束迭代。否则继续生成一个新的随机概率分布y,重复KL散度计算,直到找到满足条件的最优概率分布
def kl_test(x, kl_threshod = 0.01):
    y_out = []
    while True:
        y = [np.random.uniform(1, size+1) for i in range(size)]
        y /= np.sum(y)
        kl_result = cal_kl(x, y)
        if kl_result < kl_threshod:
            print(kl_result)
            y_out = y
            plt.plot(x)
            plt.plot(y)
            break
    return y_out

if __name__ == "__main__":
    np.random.seed(1)
    size = 10
    x = [np.random.uniform(1, size+1) for i in range(size)]
    x /= np.sum(x)
    y_out = kl_test(x, kl_threshod = 0.01)
    plt.show()
    print(x, y_out)

下面是KL散度阈值为0.01时原始数据x(蓝色)和最优概率分布y(橙色)的可视化图,可以看到此时的x和y的分布比较接近:
在这里插入图片描述

示例代码二

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ansys Zemax | NSC 非序列矢高图用户分析

本文介绍如何使用 NSC 矢高图用户分析功能在非序列模式下测量和显示对象的矢高。了解此功能的基础知识&#xff0c;包括如何设置复杂 CAD 零件的文件以获取特定面的矢高值。&#xff08;联系我们获取文章附件&#xff09; 介绍 OptocStudio 的序列模式具有表面矢高分析功能&…

硬件系统工程师宝典(28)-----关于LDO,应该知道的事

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。上篇我们说到BJT配合MOSFET控制电源开关的四种电路以及MOSFET的均流电路。今天我们来讲讲LDO的应用分析。 LDO的结构 LDO&#xff08;Low Dropout R…

Linux内核源码的配置和编译

目录 配置交叉编译工具链 读README 配置内核源码支持当前的硬件平台 驱动配置 内核编译 编译&#xff1a; 问题&#xff1a; 解决问题的方法&#xff1a; 测试内核 配置交叉编译工具链 打开内核源码顶层目录的Makefile&#xff0c; hqUbuntu:~/fs6818_uboot/kernel-3.4.39$ vi …

IP地址、子网划分

目录 一、IP地址1.IP地址表示2.分类IP地址3.无分类编址 CIDR4.特殊IP地址 二、子网划分1.子网、子网掩码、子网划分VLSM2.网络地址、广播地址3.示例1&#xff1a;等分为两个子网3.1 划分前&#xff1a;3.2 划分后&#xff1a; 4.示例2&#xff1a;等分为四个子网3.1 划分前&…

五种经典IO模型详解

目录 同步和异步同步阻塞IO模型基本概念应用场景优缺点 同步非阻塞IO模型基本概念应用场景优缺点 IO多路复用模型信号驱动IO模型回顾复习1.信号2.产生信号的条件3.可重入函数4.为什么中断处理函数不能直接调用不可重入函数5.如何写出可重入的函数 基本概念应用场景优缺点 异步I…

【操作系统】 1、计算机系统概述

1.1 操作系统的基本概念 从操作系统的角度上来划分计算机体系结构&#xff1a; 这里注意一点&#xff1a; 编译器属于应用程序。 操作系统&#xff1a;是指控制和管理计算机系统的 硬件 和软件 资源&#xff0c;合理的组织、调度计算机的工作与资源分配&#xff0c;进而为用…

对象数组练习案例

定义一个长度为3的数组&#xff0c;数组存储1~3名学生对象作为初始数据&#xff0c;学生对象的学号&#xff0c;姓名各不相同。 * 学生的属性&#xff1a;学号、姓名、年龄 * 要求1&#xff1a;再次添加一个学生对象&#xff0c;并在添加的时候进行学号的唯一性判断 * 要求2&am…

Nautilus Chain:我们将支持EIP6969

在今年 5 月初&#xff0c;以太坊核心开发者、Slingshot 的 CTO zkCole 提出了一个通用的协议标准 EIP-6969 &#xff0c;其旨在实现合约保护收入&#xff08;在以太坊 L2 上引入 / 标准化 CSR &#xff09;&#xff0c;该提案可以看作是之前 EIP-1559的改进版&#xff0c;并在…

Record类浅喽一眼~

Record类的一点小概念嗷。 一. 基本使用 java19 的新特性: 我们先构造一个student的Record类. 默认构造几个属性. public record Student(Integer id,String name, String email,Integer age) {} 然后简单搞一点例子 public static void main(String[] args) { St…

2023年上半年系统分析师上午真题及答案解析

1.信息系统的构成包括( )。 A.计算机硬件、计算机软件、网络和通信设备、系统分析人员、系统设计人员、系统开发人员 B.计算机硬件、计算机软件、系统分析人员、系统设计人员、系统开发人员 C.计算机硬件、计算机软件、系统设计人员、系统开发人员、信息用户 D.计算机硬件…

【C++】类和对象——友元函数和友元类的概念、初始化列表、explicit关键字、static成员

文章目录 1.友元函数和友元类的概念1.1友元函数1.2友元类 2.构造函数知识补充2.1初始化列表2.2explicit关键字 3.static成员3.1static成员概念3.2static成员特性 1.友元函数和友元类的概念 在C中&#xff0c;友元函数和友元类是指允许非成员函数或非成员类访问某个类中的私有成…

LeetCode面向运气之Javascript—第13题-罗马数字转整数-99.21%

LeetCode第13题-罗马数字转整数 题目要求 给定一个罗马数字&#xff0c;将其转换成整数。 罗马数字 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M 分别代表1&#xff0c;5&#xff0c;10&#xff0c;50&#xf…

一些常用的分布式组件实现技巧

广播 可用redis的pubsub机制来支持集群内的广播。 基于redis的分布式锁 加锁 使用setnx命令&#xff1a; SET lock_key random_value NX PX 5000 其中&#xff1a; random_value 是客户端生成的唯一的字符串&#xff0c;用于在删除时唯一标识client身份。 NX 代表只在键不…

【开发实用】还在用BeanUtils?不如用MapStruct

文章目录 1. 什么是MapStruct2. 为什么使用MapStruct3. 如何使用MapStruct 1. 什么是MapStruct MapStruct是一个Java注解处理器&#xff0c;它可以简化Java bean之间的转换。它使用基于生成器的方法创建类型安全的映射代码&#xff0c;这些代码在编译时生成&#xff0c;并且比…

2023夏季黑客松大赛,Moonbeam邀请你来BUIDL

由Parity和OneBlock联合举办的「2023 夏季波卡黑客松大赛」正在火热开启中。自报名开启之日&#xff0c;便获得了来自海内外对波卡生态的高度专注和对Web3开发的热情。 本次黑客松聚焦智能合约、开发工具、社交网络等大赛命题&#xff0c;邀请了行业领军人、技术大咖、投资人等…

推进开源法律知识普及|2023开放原子全球开源峰会开源法律与合规分论坛即将启幕

随着开源在推动创新、促进协作方面的作用日益凸显&#xff0c;开源领域的法律与合规问题日益受到关注。 6月11日&#xff0c;开放原子全球开源峰会开源法律与合规分论坛将在北京经济开发区国家信创园召开&#xff0c;论坛以“开源知识产权的深度现实与广阔未来”为主题&#x…

基于SSM的校园旧书交易交换平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Mybatis_plus——标准分页功能制作

mybatispuls中提供分页查询中需要两个参数&#xff0c;一个是IPage接口的实现类&#xff0c;还有一个后面说。 IPage有且只有一个实现类Page类型在里面已经提供有了&#xff0c;传两个参数即可使用&#xff0c;一个是页码值&#xff0c;一个是每页显示数据的条数。查询完之后可…

chatgpt赋能python:Python代做:让您的网站更友好的SEO利器

Python代做&#xff1a;让您的网站更友好的SEO利器 如果您是一位网站管理员或者SEO工程师&#xff0c;您一定知道SEO对于网站的重要性。那么在SEO中&#xff0c;Python代做可以为您提供什么&#xff1f;在本文中&#xff0c;我们将通过介绍Python代做的技术和方法&#xff0c;…

unity发布webGL后无法预览解决

众所周知&#xff0c;unity发布成webgl后是无法直接预览的。因为一般来说浏览器默认都是禁止webgl运行的。 直接说我最后的解决方法&#xff1a;去vscode里下载一个live server ,安装好。 下载vscode地址Visual Studio Code - Code Editing. Redefined 期间试过几种方法都不管…