Skip to content

Instantly share code, notes, and snippets.

@hewumars
Last active June 22, 2019 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hewumars/d2039adb280504097a3ffd96eaa84265 to your computer and use it in GitHub Desktop.
Save hewumars/d2039adb280504097a3ffd96eaa84265 to your computer and use it in GitHub Desktop.
1.cnet.py --path 模型保存路径 --name 模型名称 --shape 1 3 16 56 --outputs prob1 rect1 fc1x 执行caffe推理生成输入bin,输出bin 2.bin2float.py caffe_out.bin npu_out.bin 0.001 对比输出bin和其他硬件推理引擎获得的输出bin 3.utils.py工具生成随机数据或者读取jpg
#!/usr/bin/env python2
# coding=utf-8
import struct
import sys, os
import math
def bin2float(s):
size = len(s)
print('file size: {}'.format(size))
if size % 4 != 0:
raise Exception('the input bin size should be divisible by 4')
float_size = int(size/4)
s = struct.unpack('%df'%float_size, s)
return s
def get_data(file):
if not os.path.exists(file):
raise Exception('%s doesnot exist' % file)
with open(file, 'rb') as f:
data = f.read()
if len(data) == 0:
raise Exception('read %s failed'% file)
return bin2float(data)
def compare(f0, f1, epsilon, off0=0, off1=0, size=0):
d0 = get_data(f0)
d1 = get_data(f1)
s0 = len(d0)
s1 = len(d1)
size = s0
if s0 != s1:
print "WARNING:"
print " The sizes of the two binaries are not same (", s0, "vs", s1, ")"
print " Ignore some more data"
if s0 > s1:
size = s1
d0 = d0[:size]
if s1 > s0:
size = s0
d1 = d1[:size]
msg = ""
failed = 0
for i in range(0, size):
if abs(d0[i] - d1[i]) > epsilon or math.isnan(d0[i]) or math.isnan(d1[i]):
if failed == 0:
msg = "*** Data Error: [%d %d] %f vs %f" % (i, i, d0[i], d1[i])
failed += 1
if failed == 0:
print "*** Similarity: 1.0 (%d/%d)" % (size, size)
else:
similarity = float(size - failed) / size
msg += ", Similarity: %f (%d/%d) " % (similarity, size - failed, size)
raise Exception(msg)
def dump(f0, dec_places=5):
s0 = get_data(f0)
size = len(s0)
full = int(size / 10)
remain = int(size % 10)
_c = 0
for i in range(0, full):
_s = s0[_c : _c + 10]
_s = list(map(lambda x: "%f" % x, _s))
_c += 10
print ' '.join(_s)
if remain != 0:
_s = list(map(lambda x: "%f" % x, s0[_c:]))
print ' '.join(_s)
if __name__ == '__main__':
if len(sys.argv) < 3:
print "Usage: ./bin2float.py compare file0.bin file1.bin [epsilon]"
print " ./bin2float.py dump file0.bin"
exit(1)
epsilon = 0.00001
try:
if sys.argv[1] == 'compare':
f0 = sys.argv[2]
f1 = sys.argv[3]
if len(sys.argv) == 5:
epsilon = float(sys.argv[4])
print f0, ' vs ', f1
compare(f0, f1, epsilon)
elif sys.argv[1] == 'dump':
f0 = sys.argv[2]
dump(f0)
except Exception as e:
print e.message
exit(1)
exit(0)
#!/usr/bin/python2
##
## Copyright (C) Bitmain Technologies Inc.
## All Rights Reserved.
##
import os, sys
import argparse
import numpy as np
import caffe
import struct
from utils import *
PATH = 'F:/code/Atlas300'
class CNet:
def __init__(self, model_dir, model_name, shape):
models_path = PATH
name = '{}/{}/{}'.format(models_path, model_dir, model_name)
n, c, h, w = shape
self.image = PATH + '/test_p.jpg'
self.input = '{}_input_{}_{}_{}_{}.bin'.format(name, n, c, h, w)
self.input_shape = (int(n), int(c), int(h), int(w))
self.output_bin = '{}_output_{}_{}_{}_{}_ref.bin'.format(name, n, c, h, w)
caffe_model = '{}.caffemodel'.format(name)
deploy_protos = [
'{}/{}/{}_caffe_deploy.prototxt'.format(models_path, model_dir, model_name),
'{}/{}/{}_deploy.proto'.format(models_path, model_dir, model_name),
'{}/{}/{}_deploy.prototxt'.format(models_path, model_dir, model_name),
'{}/{}/{}.prototxt'.format(models_path, model_dir, model_name),
'{}/{}/caffe_deploy.proto'.format(models_path, model_dir),
'{}/{}/caffe_deploy.prototxt'.format(models_path, model_dir)
]
deploy_proto = None
for file in deploy_protos:
if os.path.exists(file):
deploy_proto = file
break
'''
# make input data
if not os.path.exists(self.input):
make_input_data(shape, self.input)
'''
# make input data myself
if not os.path.exists(self.input):
make_cv_data(shape, self.image, self.input)
self.net = caffe.Net(deploy_proto, caffe_model, caffe.TEST)
def forward(self, target_name=None):
data = np.fromfile(self.input, dtype=np.float32)
data = data.reshape(self.input_shape)
self.net.blobs['data'].reshape(*data.shape)
self.net.blobs['data'].data[...] = data
if target_name:
output = self.net.forward(end=target_name)
else:
output = self.net.forward()
return output
def forward_and_store(self, outputs=None):
output = self.forward()
if len(output) == 1:
top_data = output.values()[0]
else:
tops = []
if outputs:
outputs = outputs#.split(',')
print(outputs)
else:
outputs = output.keys()
for k in outputs:
d = output[k]
d = d.reshape(d.size)
tops.append(d)
top_data = np.concatenate(tuple(tops))
print("outputs:", output.keys())
top_data.tofile(self.output_bin)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--path', required=True, help='relative path of model after BMNET_MODELS_PATH')
parser.add_argument('--name', required=True, help='name of model')
parser.add_argument('--shape', nargs=4, metavar='4', required=True, help='input shape')
parser.add_argument('--outputs', nargs='*', help='outputs of network')
arg = parser.parse_args()
shape = [int(x) for x in arg.shape]
# path: model_dir, name: model_name, shape: [N, C, H, W]
net = CNet(arg.path, arg.name, shape)
net.forward_and_store(arg.outputs)
//读取二进制文件,用于numpy.tofile生成的随机数据,或者是图像rgb数据。模型验证时使用。
char* ReadBinFile(const char *file_name, uint32_t *fileSize)
{
std::filebuf *pbuf;
std::ifstream filestr;
size_t size;
filestr.open(file_name, std::ios::binary);
if (!filestr)
{
return nullptr;
}
pbuf = filestr.rdbuf();
size = pbuf->pubseekoff(0, std::ios::end, std::ios::in);
pbuf->pubseekpos(0, std::ios::in);
if (size <= 0)
{
return nullptr;
}
char * buffer = (char*)malloc(size);
if (nullptr == buffer)
{
return nullptr;
}
pbuf->sgetn(buffer, size);
*fileSize = size;
filestr.close();
return buffer;
}
#!/usr/bin/python2
##
## Copyright (C) Bitmain Technologies Inc.
## All Rights Reserved.
##
import os, sys
import numpy as np
import cv2
'''
def make_input_data(shape, dst):
count = reduce(lambda x, y: x * y, list(shape))
# if file exists and its matches, then return it directly.
if os.path.exists(dst) and count * 4 == os.path.getsize(dst):
return dst
_input = np.random.normal(0, 1, count)
_input = _input.astype('float32')
_input.tofile(dst)
return dst
'''
def make_cv_data(shape, src, dst):
img = cv2.imread(src)
# BGR to GRAY
if shape[1] == 1:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# resize
img.resize(tuple(shape))
img = np.ascontiguousarray(img, dtype=np.float32)
img.tofile(dst)
return dst
def compare(f0, f1, epsilon):
print(f0, 'vs', f1, 'epsilon:', epsilon)
d0 = np.fromfile(f0, dtype = np.float32)
d1 = np.fromfile(f1, dtype = np.float32)
if len(d0) != len(d1):
msg = "two binary should be same size, %d bytes <=> %d bytes" % (len(d0), len(d1))
raise Exception(msg)
diff = np.abs(d0 - d1)
num_diff = np.sum(diff > epsilon)
if num_diff > 0:
msg = "Result %d/%d mismatch." %(num_diff, len(d0))
raise Exception(msg)
else:
print("Result matches.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment