Last active
June 22, 2019 01:35
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//读取二进制文件,用于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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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