AIIC学习日记-十进制浮点数预处理为二进制定点数

背景

前几天研究生学长给我了一个图像输入的txt,和LeNet的参数文件,让我写个卷积核。

LeNet.h5打开方式:
netron
netron网页版

目前是做的AI推断加速,并非AI训练。

对cnn不了解的可以看看这个:LeNet-5详解

任务

我第一件事情是将这两个数据从定点数转化为二进制数,然后将这两个数据作为 coe文件导入BRAM ip核中。

浮点数是什么

但是我发现我好像不会浮点数了,哭。十进制浮点数转成二进制(IEEE 754 在线计算器)

对于float单精度来说,32bit=1bit符号位+8bit(有符号指数位 -128-127)+23bit(数据)

我们需要将十进制的数转变为二进制的数,然后都表示成 1.xxx*2^n 的形式,只需要记录xxx即可,因此23bit可以表示24bit。

浮点数精度: 我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到十进制小数点后6位。

这里用的是定点数,咳咳

后来才知道定点数就可以了,定点数一共16bit(自己设定即可),1bit符号+15bit数据,小数点位置人为定义。

netron导出的卷积核数据处理为一列数据

从LeNet导出的数据里有[],\n等,需要修改为一列数据。

strip()函数只能对字符的首尾删减!

replace倒是蛮好用的。replace后要赋值给自己(s)才行!

s=s.replace('/n','').replace('[','').replace(']','').replace(' ','')
预处理浮点数的代码

因为卷积核参数是3x3x1x64(64个3x3的卷积核,但是直接去掉括号的话,得到的前64个数据为每个卷积核的第一个数据,所以需要转换才行。lenet_new_proc.txt是经过转换的文件,连续的9个数为一个卷积核的数据)


####### lenet数组转coe文件格式(一列),不包括定点数转二进制#################################################
import numpy as np
store_data = np.zeros( (64,9)) #9列,64行


f = open('lenet.txt','r')
data = f.readlines()
# print(data)
new_data =[]
j = 0
for i in range(len(data)):
    row = int(j%64)#行
    column = int(j/64)#列
    j = j + 1
    # row = int(i % 64)  # 行
    # column = int(i / 64)  # 列

    new = str(data[i])
    new = new.replace('[','').replace(']','').replace(' ','').replace(',','').lstrip('\n')#先去除逗号
    if new == '':#某些行是空格,并没有处理掉
        j = j - 1
        # data.pop(i) #根据索引删除列表中的空格
        # i = i - 1
        print('空行')
        continue
    new = new.replace('\n', ',\n') #恢复逗号,数组表示的时候,逗号位置和一列表示不对
    proc_new = new.strip(',\n')
    new_data.append(new)
    proc_new = float(proc_new)

    print(i,'行,列:',row,column,'data:',new,'proc_data',proc_new)
    store_data[row][column]= proc_new
# print(store_data)
# print(data)
# print(new_data)
np.savetxt("./store_data.v", store_data, fmt='%f', delimiter=',')

p = open ('lenet_new.txt','w') #直接转换为一列,并不正确
for i in (new_data):
    p.write(i)

fp = open('lenet_new_proc.txt', 'w')  # 正确的转换
for row in range(64):
    for column in range(9):
        data = store_data[row][column]
        data = str(data)+',\n'
        fp.write(data)
########################################################

########卷积核确定最大最小值,从而决定定点数 ################################################
p = open ('lenet_new.txt','r')
list=[]
for data in p.readlines():
    data=data.replace(',\n','')
    data=float(data) #str to float
    list.append(data)
# print(list)

print('max',max(list))
print('min',min(list))

最后一段代码比较大小来确定位宽。一个数据的位宽取决于最大的数和要表示的最小的精度

十进制浮点数预处理为二进制定点数

补码+原码=2^n

一个n位数的补码加原码等于2的n次方 这个n包括符号位。 因此一个负数可以先加上2^n,表示补码。

十进制浮点数预处理为二进制定点数代码

bin()整型转二进制
rjust() 左边填充0到固定位数

ff = open('file_float.v','r')#待处理的数据
fc = open('file_binary.v','w')#处理完成的数据

######定点数转二进制代码1  ##########################
def conInt(n):#整数部分
    s = bin( int(n) ).lstrip('0b')
    # print('整数', s)
    s = s.rjust(8, '0')  # 左补0
    s = str(s)[1:8]
    print('整数', s)
    return s

def conFra(n):#小数部分
    n = '0.'+str(n)
    n = (float(n)*2**8)#若取8bit小数
    print('小数', n)
    n = int(n) # 得到小数位,
    back =bin(n).lstrip('0b')
    back = back.rjust(8, '0')  # 左补0  这里必须左补0,因为整个小数左移了8bit,而整数部分多数没有8bit,所以需要补齐0
    # dec, less = str(n).split('.')  # 得到小数位,less表示剩下的,不用
    # back = bin(int(dec)).lstrip('0b')


    print('小数', back)
    # for _ in range(len(back), 8):
    #     back +='0'
    return back


def dec_bin(data):
    # n=eval(input())
    # data=6.06397055089473724
    # data = 6
    print('输入数据----------------------------------------',data)
    if data<0:
        sign_flag = '1'
        data = data + 2**8 #取补码等于+2^8次幂。8bit小数位  一个n位数的补码加原码等于2的n次方 这个n包括符号位
    else:
        sign_flag = '0'

    if type(data) == float:#小数
        a,b = str(data).split('.')
        # print('float!')
    else: #整数
        a = data
        b = '0'
    print('a',a,'b',b)
    out = sign_flag + str(conInt(a))+'.'+str(conFra(b))
    print('输出数据----------------------------------------',out)
    fc.write(sign_flag + str(conInt(a)) + str(conFra(b))+'\n')

cnt=0
for data in ff.readlines():

    data_in = float(data.strip(',\n'))
    print(data_in)
    dec_bin(data_in)
    cnt += 1
    print('cnt',cnt)

关于CSDN直接复制粘贴会多回车

处理代码如下:

f = open('old.txt','r')
data = f.readlines()
print(data)
for i in (data):
    data.remove('\n')#remove删除list中与之匹配的第一个字符

# print(data)

p = open ('new.txt','w')
for i in (data):
    p.write(i)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值