1.ruyi仿真保存每一层中间结果
1>修改项目配置未见nnie_sim.ini
将[LAYER_LINEAR_PRINT_EN]设置为1,这样就可以保存每一层的中间结果,用以caffe验证。
2>把每层结果hex转换为float
这一步是最为蛋疼的,也不知道ruyi是咋做的,我自己写了一个python脚本来实现,python脚本实现的真tm操蛋,16进制负数咋表示。表示不知道,如果有大神会转换请留言,先谢过!!!
这里首先插下windows计算器。FFFFA69E转换为十进制,看看windows结果。
看见了吗?我也不知道咋回事,四字和双字结果就不一样,NNIE保存的应该是双字的,至于怎么判断,取最高位>8就为负数,最高位小于8就为整数。脚本如下:
import os
import string
import struct
import binascii
import numpy as np
def stringxor(str1):
orxstr=""
for i in range(0,len(str1)):
rst=ord(list(str1)[i])
if rst == 48:
rst = 49
else :
rst = 48
orxstr=orxstr+ chr(rst)
return orxstr
dir = './inst_layer_output_linear/'
#net_tree = './cnn_net_tree.dot'
num = 0
for count, line in enumerate(open('./cnn_net_tree.dot', 'rU')):
result = 'segment' in line
if result:
index1 = line.find('label')
index2 = line.find('net')
sub_line = line[index1 + 7:index2 - 3]
#print (sub_line)
hex_file = dir + 'seg0_layer{}_output0_inst.linear.hex'.format(num)
float_file = dir + 'seg0_layer{}_'.format(num) + sub_line + '_output0_inst.linear.float'
print (hex_file)
print (float_file)
with open(float_file, 'w') as f_f:
for count_h, line_h in enumerate(open(hex_file, 'rU')):
out = 0
first_num = line_h[0]
if int(first_num, 16) < 8:
out = int(line_h.strip(), 16)
else:
a = bin(int(line_h, 16))[2:]
#print (a)
b = stringxor(a)
#c = (int(a))
#print (b)
out = (int(b,2) + 1) * -1
#print (out)
float_out = float(out / 4096)
f_f.write(str(float_out))
f_f.write('\n')
#print (float_out)
num = num + 1
f_f.close()
这里需要提下十六进制转10进制问题,我采取做法是正数直接调python函数,负数,先转换为二进制,然后二进制按位取反后+1,在乘 -1,python按位取反 ~ 真坑爹,只认int;结果是a = -(a+1)这是啥子啊,我要二进制,给我最后结果。。。。。。
2运行caffe,加载每层中间值,比较输出。
使用ruyi的init.prototxt运行caffe demo,加载每层的结果。
net = caffe.Net(net_file,caffe_model,caffe.TEST)
net.blobs['data'].data[...] = img
net.blobs[层1].data[...] = np.loadtxt(层1保存的.float文件).reshape(net.blobs[层1].data.shape)
......
......
一直到NNIE最后的输出层。
out = net.forward()
如果forward之后的输出跟nnie输出一致,恭喜移植成功,不一致,可能初始化以及CPU处理部分有问题。