363 lines
16 KiB
Python
Executable File
363 lines
16 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from utils import *
|
|
from argparse import ArgumentParser
|
|
import numpy as np
|
|
import os
|
|
import sys
|
|
|
|
import importlib
|
|
try:
|
|
importlib.import_module("acuitylib")
|
|
except:
|
|
ACUITY_PATH = os.environ['ACUITY_PATH']
|
|
sys.path.append(ACUITY_PATH)
|
|
|
|
from acuitylib.vsi_nn import VSInn
|
|
|
|
def read_inputs_outputs_file(inputs_outputs_file):
|
|
args_dict = {
|
|
"inputs": None,
|
|
"outputs": None,
|
|
"input_size_list": None,
|
|
"size_with_batch": None,
|
|
"input_dtype_list": None,
|
|
"target_onnx_file": None,
|
|
"predef_file": None,
|
|
"mean_values": None,
|
|
"std_values": None
|
|
}
|
|
|
|
with open(inputs_outputs_file, 'r') as inter_file:
|
|
args = inter_file.readlines()
|
|
if len(args) == 1:
|
|
args = args[0].split("--")
|
|
for arg in args:
|
|
if "inputs" in arg:
|
|
args_dict["inputs"] = ' '.join(arg.split()[1:]).strip('\"').strip('\'')
|
|
elif "outputs" in arg:
|
|
args_dict["outputs"] = ' '.join(arg.split()[1:]).strip('\"').strip('\'')
|
|
elif "input-size-list" in arg:
|
|
args_dict["input_size_list"] = arg.split()[1].strip('\"').strip('\'')
|
|
elif "size-with-batch" in arg:
|
|
args_dict["size_with_batch"] = arg.split()[1].strip('\"').strip('\'')
|
|
elif "input-dtype-list" in arg:
|
|
args_dict["input_dtype_list"] = arg.split()[1].strip('\"').strip('\'')
|
|
elif "predef-file" in arg:
|
|
args_dict["predef_file"] = arg.split()[1]
|
|
elif "mean-values" in arg:
|
|
args_dict["mean_values"] = arg.split()[1].strip('\"').strip('\'')
|
|
elif "std-values" in arg:
|
|
args_dict["std_values"] = arg.split()[1].strip('\"').strip('\'')
|
|
return args_dict
|
|
|
|
def importer(modelfile_name, save=True):
|
|
nn = VSInn()
|
|
|
|
if os.path.exists(modelfile_name+'.prototxt') is True:
|
|
prototxt = modelfile_name+'.prototxt'
|
|
weights = modelfile_name+'.caffemodel'
|
|
if os.path.exists(weights) is True:
|
|
print_params(nn.load_caffe, model=prototxt, weights=weights)
|
|
net = nn.load_caffe(model=prototxt, weights=weights)
|
|
else:
|
|
print_params(nn.load_caffe, model=prototxt)
|
|
net = nn.load_caffe(model=prototxt)
|
|
elif os.path.exists(modelfile_name+'.pb') is True:
|
|
tf_model = modelfile_name+'.pb'
|
|
inputs_outputs_file = 'inputs_outputs.txt'
|
|
if os.path.exists(inputs_outputs_file) is True:
|
|
args_dict = read_inputs_outputs_file(inputs_outputs_file)
|
|
print_params(nn.load_tensorflow, model=tf_model, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"],
|
|
predef_file=args_dict["predef_file"],
|
|
mean_values = args_dict["mean_values"],
|
|
std_values = args_dict["std_values"])
|
|
net = nn.load_tensorflow(model=tf_model, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"],
|
|
predef_file=args_dict["predef_file"],
|
|
mean_values=args_dict["mean_values"],
|
|
std_values=args_dict["std_values"]
|
|
)
|
|
else:
|
|
print("{} does not exist".format(inputs_outputs_file))
|
|
sys.exit(1)
|
|
elif os.path.exists(modelfile_name+'.tflite') is True:
|
|
lite_model = modelfile_name+'.tflite'
|
|
inputs_outputs_file = 'inputs_outputs.txt'
|
|
if os.path.exists(inputs_outputs_file) is True:
|
|
args_dict = read_inputs_outputs_file(inputs_outputs_file)
|
|
print_params(nn.load_tflite, model=lite_model, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"])
|
|
net = nn.load_tflite(model=lite_model, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"])
|
|
else:
|
|
net = nn.load_tflite(lite_model)
|
|
elif os.path.exists(modelfile_name+'.cfg') is True:
|
|
darknet_file = modelfile_name+'.cfg'
|
|
weights = modelfile_name+'.weights'
|
|
if os.path.exists(weights) is True:
|
|
print_params(nn.load_darknet, model=darknet_file, weights=weights)
|
|
net = nn.load_darknet(model=darknet_file, weights=weights)
|
|
else:
|
|
print("{} does not exist".format(weights))
|
|
sys.exit(1)
|
|
elif os.path.exists(modelfile_name+'.onnx') is True:
|
|
onnx_file = modelfile_name + '.onnx'
|
|
inputs_outputs_file = 'inputs_outputs.txt'
|
|
if os.path.exists(inputs_outputs_file) is True:
|
|
args_dict = read_inputs_outputs_file(inputs_outputs_file)
|
|
print_params(nn.load_onnx, model=onnx_file, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"],
|
|
input_dtype_list=args_dict["input_dtype_list"])
|
|
net = nn.load_onnx(model=onnx_file, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"],
|
|
input_dtype_list=args_dict["input_dtype_list"])
|
|
else:
|
|
net = nn.load_onnx(model=onnx_file)
|
|
elif os.path.exists(modelfile_name+'.pt') is True:
|
|
pt_file = modelfile_name + '.pt'
|
|
inputs_outputs_file = 'inputs_outputs.txt'
|
|
if os.path.exists(inputs_outputs_file) is True:
|
|
args_dict = read_inputs_outputs_file(inputs_outputs_file)
|
|
print_params(nn.load_pytorch_by_onnx_backend, model=pt_file, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"])
|
|
net = nn.load_pytorch_by_onnx_backend(model=pt_file, inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
size_with_batch=args_dict["size_with_batch"])
|
|
else:
|
|
net = nn.load_pytorch_by_onnx_backend(model=pt_file)
|
|
elif os.path.exists(modelfile_name+".h5") is True:
|
|
keras_file = modelfile_name+'.h5'
|
|
inputs_outputs_file = 'inputs_outputs.txt'
|
|
if os.path.exists(inputs_outputs_file) is True:
|
|
args_dict = read_inputs_outputs_file(inputs_outputs_file)
|
|
print_params(nn.load_keras, model=keras_file,
|
|
inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
convert_engine="Keras")
|
|
net = nn.load_keras(model=keras_file,
|
|
inputs=args_dict["inputs"],
|
|
input_size_list=args_dict["input_size_list"],
|
|
outputs=args_dict["outputs"],
|
|
convert_engine="Keras")
|
|
else:
|
|
net = nn.load_keras(model=keras_file)
|
|
else:
|
|
print("Cannot find model :{}".format(modelfile_name))
|
|
sys.exit(1)
|
|
|
|
if nn.is_quantize_model is True:
|
|
for tensor in net.tensors:
|
|
if tensor.quant_param is not None and tensor.quant_param.qtype == 'float16':
|
|
nn.is_quantize_model = False
|
|
break
|
|
|
|
if save:
|
|
output_model = modelfile_name + '.json'
|
|
output_data = modelfile_name + '.data'
|
|
|
|
nn.save_model(net, output_model)
|
|
nn.save_model_data(net, output_data)
|
|
if nn.is_quantize_model is True:
|
|
quantize_output = modelfile_name + '_asymu8' + '.quantize'
|
|
print("!!! It's a quant model. !!!")
|
|
print("!!! To suit the naming rule , rename to {}!!!".format(quantize_output))
|
|
nn.save_model_quantize(net, quantize_output)
|
|
return net, nn.is_quantize_model
|
|
|
|
def read_channel_mean_value_file(channel_mean_value_file, channel):
|
|
mean_scale = []
|
|
with open(channel_mean_value_file, 'r') as inter_file:
|
|
line = inter_file.readline().strip()
|
|
nums = line.split()
|
|
if len(nums) == 1 and nums[0] == '':
|
|
print("No data in the {}, Please enter the correct data.".format(channel_mean_value_file))
|
|
sys.exit(1)
|
|
else:
|
|
for num in nums:
|
|
mean_scale.append(float(num))
|
|
|
|
if len(mean_scale) == (channel + 1):
|
|
mean = mean_scale[0:channel]
|
|
scale_r = mean_scale[channel]
|
|
# The scale in inputmeta.yml is equal to 1/(the scale in channel_mean_value_file)
|
|
# the scale in channel_mean_value_file is the scale of origin platform
|
|
scale = [1.0 / scale_r] * channel
|
|
elif len(mean_scale) == (channel * 2):
|
|
mean = mean_scale[0:channel]
|
|
scale_r = mean_scale[channel:]
|
|
scale = [1.0 / s for s in scale_r]
|
|
else:
|
|
print("Please enter the correct data in channel_mean_value.txt file for model preprocess.")
|
|
sys.exit(1)
|
|
return mean, scale
|
|
|
|
def preprocess(net, modelfile_name, save=True):
|
|
nn = VSInn()
|
|
inputs_shape = []
|
|
inputs_lid = []
|
|
inputs_name = []
|
|
inputs_type = []
|
|
preprocess_dict = {}
|
|
inputs = net.get_input_layers(ign_variable=True)
|
|
for l in inputs:
|
|
if l.is_op('input'):
|
|
inputs_lid.append(l.lid)
|
|
preprocess_params = {}
|
|
shape = l.params.shape
|
|
inputs_shape.append(shape)
|
|
inputs_name.append(l.name)
|
|
inputs_type.append(l.params.type)
|
|
if shape[0] == 0:
|
|
shape[0] = 1
|
|
preprocess_params['shape'] = shape
|
|
fmt = net.get_org_platform_mode()
|
|
if fmt == 'nchw':
|
|
print("The default layout of your model is nchw, please note if it needs to changed!")
|
|
preprocess_params['reverse_channel'] = fmt == 'nchw'
|
|
|
|
if len(shape) == 4:
|
|
if fmt == 'nchw':
|
|
channel = shape[1]
|
|
else:
|
|
channel = shape[-1]
|
|
if channel == 3 or channel == 1 or channel == 4:
|
|
channel_mean_value_file = 'channel_mean_value.txt'
|
|
if os.path.exists(channel_mean_value_file) is True:
|
|
mean, scale = read_channel_mean_value_file(channel_mean_value_file, channel)
|
|
else:
|
|
mean = [0] * channel
|
|
scale = [1.0] * channel
|
|
preprocess_params['mean'] = mean
|
|
preprocess_params['scale'] = scale
|
|
else:
|
|
preprocess_params['scale'] = 1.0
|
|
preprocess_dict[l.name] = preprocess_params
|
|
|
|
num = len(inputs_shape)
|
|
if num == 1:
|
|
if os.path.exists('dataset.txt') is True:
|
|
nn.set_database(net, dataset_files='dataset.txt', dataset_type="TEXT")
|
|
else:
|
|
if os.path.exists("inputs") is False:
|
|
os.system("mkdir inputs")
|
|
input = np.random.random(inputs_shape[0]).astype(inputs_type[0])
|
|
shape = '_'.join(str(inputs_shape[0][i]) for i in range(len(inputs_shape[0])))
|
|
dataset_name = '{}_{}_{}.npy'.format(inputs_lid[0], shape, 0)
|
|
dataset_name = dataset_name.replace('@', '').replace(':', '_').replace('/', '_')
|
|
dataset_name = "./inputs/" + dataset_name
|
|
if os.path.exists(dataset_name) is False:
|
|
np.save(dataset_name, input)
|
|
nn.set_database(net, dataset_files=dataset_name, dataset_type='NPY')
|
|
preprocess_dict[inputs_name[0]]['reverse_channel'] = False
|
|
else:
|
|
dataset_files = []
|
|
for i in range(num):
|
|
if os.path.exists('dataset{}.txt'.format(i)) is True:
|
|
dataset_files.append('dataset{}.txt'.format(i))
|
|
dataset_type = "TEXT"
|
|
else:
|
|
if os.path.exists("inputs") is False:
|
|
os.system("mkdir inputs")
|
|
input = np.random.random(inputs_shape[i]).astype(inputs_type[i])
|
|
shape = '_'.join(str(inputs_shape[i][j]) for j in range(len(inputs_shape[i])))
|
|
dataset_name = '{}_shape_{}.npy'.format(inputs_lid[i], shape, i)
|
|
dataset_name = dataset_name.replace('@', '').replace(':', '_').replace('/', '_')
|
|
dataset_name = "./inputs/" + dataset_name
|
|
if os.path.exists(dataset_name) is False:
|
|
np.save(dataset_name, input)
|
|
dataset_files.append(dataset_name)
|
|
dataset_type = "NPY"
|
|
preprocess_dict[inputs_name[i]]['reverse_channel'] = False
|
|
nn.set_database(net, dataset_files=dataset_files, dataset_type=dataset_type)
|
|
|
|
# preprocess
|
|
nn.set_preprocess(net, preprocess_dict)
|
|
inputmeta_serialize = nn.get_inputmeta(net)
|
|
inputmeta_serialize['databases'][0]['ports'][0]['redirect_to_output'] = False
|
|
nn.set_inputmeta(net, inputmeta_serialize)
|
|
|
|
if save:
|
|
inputmeta_yml = modelfile_name + '_inputmeta.yml'
|
|
nn.save_model_inputmeta(net, inputmeta_yml)
|
|
return net
|
|
|
|
def postprocess(net, modelfile_name, save=True):
|
|
nn = VSInn()
|
|
acuity_postprocess_list = [
|
|
{'dump_results': {'file_type': 'TENSOR'}},
|
|
{'print_topn': {'topn': 5}},
|
|
]
|
|
nn.set_acuity_postprocess(net, acuity_postprocess_list)
|
|
|
|
app_postprocess_list = []
|
|
outputs = net.get_output_layers()
|
|
net.compute_shape()
|
|
for l in outputs:
|
|
if l.is_op('output'):
|
|
app_sublist = []
|
|
app_params = {}
|
|
add_postproc_node = False
|
|
dim_num = len(l.get_output().shape.dims)
|
|
perm = []
|
|
for i in range(dim_num):
|
|
perm.append(i)
|
|
app_params['add_postproc_node'] = add_postproc_node
|
|
app_params['perm'] = perm
|
|
app_params['force_float32'] = True
|
|
|
|
app_sublist.append(l.lid)
|
|
app_sublist.append([app_params])
|
|
app_postprocess_list.append(app_sublist)
|
|
|
|
nn.set_app_postprocess(net, app_postprocess_list, set_by_lid=True)
|
|
|
|
if save:
|
|
postprocess_file_yml = modelfile_name + '_postprocess_file.yml'
|
|
nn.save_model_outputmeta(net, postprocess_file_yml)
|
|
|
|
return net
|
|
|
|
def main():
|
|
options = ArgumentParser()
|
|
options.add_argument("model", type=str, help="Model directory")
|
|
|
|
args = options.parse_args()
|
|
print(args)
|
|
if os.path.exists(args.model) and os.path.isdir(os.path.abspath(args.model)):
|
|
model_filename = get_modelfile_name(args.model)
|
|
if model_filename is None:
|
|
print("Please enter the path that includes the model.")
|
|
os.chdir(args.model)
|
|
else:
|
|
model_filename = args.model
|
|
|
|
#import
|
|
net, _ = importer(model_filename)
|
|
#prepocess
|
|
preprocess(net, model_filename)
|
|
#postprocess
|
|
postprocess(net, model_filename)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|