当前位置: 首页 > news >正文

神经网络量化3-全连接层实现量化

本节,我们模拟下全连接层实现量化,原理上为了方便计算,全连接矩阵采用动态量化的方法,而输入由于不断在变化,我们采用静态量化的方法,直接给出代码:

import torch
import numpy as np
import math
#静态量化
def fix_quantize_tensor(array, highB, lowB, num_bits=8):
    rangeB = highB - lowB
    shiftDist = -(highB + lowB) / 2
    qmax = 2.**num_bits - 1.
    zero_point = shiftDist / rangeB * qmax;
    qmaxp = 2.**(num_bits - 1) - 1.
    qminp = -2.**(num_bits - 1)
    zero_point = math.floor(zero_point)
    scale = rangeB / qmax
    q_x = array/scale + zero_point
    q_x = q_x.round().int()
    q_x[q_x > qmaxp] = qmaxp
    q_x[q_x < qminp] = qminp
    return q_x, zero_point, scale
#动态量化
def quantize_tensor(array, num_bits=8):
    highB = array.max()
    lowB = array.min()
    rangeB = highB - lowB
    shiftDist = -(highB + lowB) / 2
    qmax = 2.**num_bits - 1.
    zero_point = shiftDist / rangeB * qmax;
    qmaxp = 2.**(num_bits - 1) - 1.
    qminp = -2.**(num_bits - 1)
    zero_point = zero_point.floor().int()
    scale = rangeB / qmax
    q_x = array/scale + zero_point
    q_x = q_x.round().int()
    q_x[q_x > qmaxp] = qmaxp
    q_x[q_x < qminp] = qminp
    return q_x, zero_point, scale
#输入信号    
x1 = torch.randn(1, 10, dtype=torch.float32) * 0.1
#权重矩阵
W = torch.randn(10, 10, dtype=torch.float32) * 0.1
#偏置
mbias = torch.randn(1, 10, dtype=torch.float32) * 0.1

print('************quantize value**************')
q2, z2, s2 = quantize_tensor(W)

m_range = 0.5
print(x1)
#静态量化输入信号,且输入信号量化范围对称
q1, z1, s1 = fix_quantize_tensor(x1, m_range, -m_range)
print(q1, z1, s1)

print(mbias)
#偏置的量化和输入信号要一致,这样可以减少运算复杂度
qb, zb, sb = fix_quantize_tensor(mbias, m_range, -m_range)
print(qb, zb, sb)

print('************quantize matrix multiply*************')
########### s1(q1-z1)q2+qb #############
#通过*2^16+移位的方式来实现浮点乘运算
M0 = int(s2 * (2**16))
qresult = (torch.matmul(q1 - z1, q2) * M0) >> 16
qresult = qresult.round().int() + qb
print(qresult)
print('************quant result***********************')
print(qresult * s1)
print('************real result*************************')
print(torch.matmul(x1, W) + mbias)

结果:

************quantize value**************
tensor([[ 0.1819,  0.0145, -0.2078, -0.0485, -0.0212, -0.0677, -0.0572,  0.0349,
          0.1925, -0.0266]])
tensor([[ 46,   4, -53, -12,  -5, -17, -15,   9,  49,  -7]], dtype=torch.int32) 0 0.00392156862745098
tensor([[ 0.0032,  0.0095, -0.1825, -0.1033, -0.0582, -0.1757, -0.0893,  0.0119,
          0.0336, -0.0487]])
tensor([[  1,   2, -47, -26, -15, -45, -23,   3,   9, -12]], dtype=torch.int32) 0 0.00392156862745098
************quantize matrix multiply*************
tensor([[ -1,  -1, -44, -38, -15, -53, -31,   9,   4, -15]], dtype=torch.int32)
************quant result***********************
tensor([[-0.0039, -0.0039, -0.1725, -0.1490, -0.0588, -0.2078, -0.1216,  0.0353,
          0.0157, -0.0588]])
************real result*************************
tensor([[-0.0041, -0.0049, -0.1688, -0.1506, -0.0592, -0.2056, -0.1213,  0.0356,
          0.0133, -0.0617]])

注意结果是随机的,需要注意,我们对于输入信号和偏置的量化采用的是相同的量化参数,且zero_point为0,这是常用的一种方法,可以简化操作流程,得到的结果就是按照这个量化参数量化的结果(s1和z1),对于神经网络下一级可以继续按照这样的量化信号继续下一级运算,

相关文章:

  • 12 File文件对象:创建、获取基本信息、遍历文件夹、查找文件;字符集的编解码 (黑马Java视频笔记)
  • Qt动态设置样式,实现样式实时切换
  • IntelliJ 配置文件plugin.xml
  • Vector 的模拟实现:从基础到高级
  • 10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)
  • ABSD基于架构的软件设计
  • 在WINDOWS中如何运行VBS脚本,多种运行方式
  • 游戏引擎学习第167天
  • LLM(5):了解 GPT 架构
  • SY6280AAC usb电流限流电子开关
  • 美国站群服务器租用应该怎么选?
  • C++输入输出流第一弹:标准输入输出流 详解(带测试代码)
  • 预处理指令中#if 和 #endif的用法
  • 拉取镜像太慢?一文解决!
  • 3分钟学会FTP下载FY4A和Himawari-8数据
  • 每日OJ_牛客_MT1最大差值_模拟+贪心_C++_Java
  • 基于大模型的喉癌全程预测与治疗方案优化研究报告
  • 春秋云境刷题1
  • 从0到1入门AOP
  • Spring中的循环依赖问题是什么?
  • 习近平同瑞典国王卡尔十六世·古斯塔夫就中瑞建交75周年互致贺电
  • 秦洪看盘|重估叙事主题卷土重来,给A股注入新活力
  • 同观·德国|默茨当总理后,能否带领德国在欧盟“说了算”?
  • 世界银行最新营商环境体检单:59个测评点,上海22项达全球最优水平
  • 新闻分析:电影关税能“让好莱坞再次伟大”?
  • 虚构医药服务项目、协助冒名就医等,北京4家医疗机构被处罚