From ecbd52a12231d7233daa3617a465d685de5c1a1a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB=20=D0=A4=D0=B0=D1=82=D1=82?= =?utf8?q?=D0=B0=D1=85=D0=BE=D0=B2/AI=20Tools=20Lab=20/SRR/Assistant=20Eng?= =?utf8?q?ineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 19 Nov 2018 17:19:58 +0300 Subject: [PATCH] [nnc] split model runner script into 4 scripts (#2285) split model runner script into 4 scripts Signed-off-by: Pavel --- contrib/nnc/utils/model_runner/common_place.py | 65 ++++++++ contrib/nnc/utils/model_runner/model_runner.py | 167 --------------------- .../nnc/utils/model_runner/model_runner_caffe.py | 21 +++ .../nnc/utils/model_runner/model_runner_caffe2.py | 22 +++ .../nnc/utils/model_runner/model_runner_onnx.py | 25 +++ .../nnc/utils/model_runner/model_runner_tflite.py | 23 +++ contrib/nnc/utils/model_runner/readme.md | 10 +- 7 files changed, 161 insertions(+), 172 deletions(-) create mode 100644 contrib/nnc/utils/model_runner/common_place.py delete mode 100644 contrib/nnc/utils/model_runner/model_runner.py create mode 100644 contrib/nnc/utils/model_runner/model_runner_caffe.py create mode 100644 contrib/nnc/utils/model_runner/model_runner_caffe2.py create mode 100644 contrib/nnc/utils/model_runner/model_runner_onnx.py create mode 100644 contrib/nnc/utils/model_runner/model_runner_tflite.py diff --git a/contrib/nnc/utils/model_runner/common_place.py b/contrib/nnc/utils/model_runner/common_place.py new file mode 100644 index 0000000..65c3d03 --- /dev/null +++ b/contrib/nnc/utils/model_runner/common_place.py @@ -0,0 +1,65 @@ +import h5py +import argparse +from argparse import RawTextHelpFormatter + + +def regular_step(): + """ + This function is intended to decompose the necessary steps to obtain information from the command line. + + :return: argparse object, which hold paths to nn model and input data + """ + parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter) + + parser.add_argument( + '-m', + '--model', + help=("specify input file with NN model, \n[depends from model, " + " two for caffe and caffe2, one for onnx and tflite]"), + nargs='+') + parser.add_argument('-i', '--input', help=(" specify file with neural" + " network input data, hdf5 for caffe caffe2 tflite " + "and pb for onnx"), required=True) + parser.add_argument('-o', '--output_path', + help='here you specify which place will hold your output, default here', default='') + + + args = parser.parse_args() + # added to check is our input file or not. most simple way + try: + with open(args.input) as f: + pass + except IOError as e: + print('input file your enter doesnt exist!') + + # added to check is our model right or not + try: + for i in args.model: + with open(i) as f: + pass + except IOError as e: + print('model you enter doesnt exist, write correct PATH ') + + + return args + + +def save_result(output_path, output_data): + """ + This function save result of nn working in .hdf5 file + :param output_path: you specify directory to store your result + :param output_data: information that you write to .hdf5 file + :return: + """ + with open(output_path + 'responce.txt', 'w+') as f: + f.write(str(output_data)) + f = h5py.File(output_path + 'responce.hdf5', 'w') + f.create_dataset('out', dtype='float32', data=output_data) + f.close() + + +def read_input(input_path): + h5f = h5py.File(input_path, 'r') + for t in h5f: + tensorName = str(t) + return h5py.File(input_path, 'r')[tensorName][:] diff --git a/contrib/nnc/utils/model_runner/model_runner.py b/contrib/nnc/utils/model_runner/model_runner.py deleted file mode 100644 index a1e4e4e..0000000 --- a/contrib/nnc/utils/model_runner/model_runner.py +++ /dev/null @@ -1,167 +0,0 @@ -import h5py -import onnx -import caffe -import argparse -import tensorflow as tf -import caffe2.python.onnx.backend -from argparse import RawTextHelpFormatter -from caffe2.python import workspace - - -def regular_step(): - """ - This function is intended to decompose the necessary steps to obtain information from the command line. - - :return: argparse object, which hold paths to nn model and input data - """ - parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter) - # add command line flags and options - parser.add_argument( - "--caffe", - help="treat input file as Caffe model", - action="store_true") - parser.add_argument( - "--onnx", - help="treat input file as onnx model", - action="store_true") - parser.add_argument( - "--tflite", - help="treat input file as tflite model", - action="store_true") - parser.add_argument( - "--caffe2", - help="treat input file as caffe2 model", - action="store_true") - - parser.add_argument( - '-m', - '--model', - help=("specify input file with NN model, \n[depends from model, " - " two for caffe and caffe2, one for onnx and tflite]"), - nargs='+') - parser.add_argument('-i', '--input', help=(" specify file with neural" - " network input data, hdf5 for caffe caffe2 tflite " - "and pb for onnx"), required=True) - parser.add_argument('-o', '--output_path', - help='here you specify which place will hold your output, default here', default='') - - - args = parser.parse_args() - # added to check is our input file or not. most simple way - try: - with open(args.input) as f: - pass - except IOError as e: - print('input file your enter doesnt exist!') - - # added to check is our model right or not - try: - for i in args.model: - with open(i) as f: - pass - except IOError as e: - print('model you enter doesnt exist, write correct PATH ') - - # check correct flag input - if (args.caffe + args.caffe2 + args.tflite + args.onnx != 1): - raise Exception('You aren\'t add necessary key caffe caffe2 onnx tflite! or add more then one') - - return args - - -def save_result(output_path, output_data): - """ - This function save result of nn working in .hdf5 file - :param output_path: you specify directory to store your result - :param output_data: information that you write to .hdf5 file - :return: - """ - with open(output_path + 'responce.txt', 'w+') as f: - f.write(str(output_data)) - f = h5py.File(output_path + 'responce.hdf5', 'w') - f.create_dataset('out', dtype='float32', data=output_data) - f.close() - - -def read_input(input_path): - h5f = h5py.File(input_path, 'r') - for t in h5f: - tensorName = str(t) - return h5py.File(input_path, 'r')[tensorName][:] - - -def run_caffe2(init_net, predict_net, input_path, output_path =''): - x = read_input(input_path) - with open(init_net, 'rb') as f: - init_net = f.read() - - with open(predict_net, 'rb') as f: - predict_net = f.read() - p = workspace.Predictor(init_net, predict_net) - # TODO get 'data' parameter more universal, blobs contain other names - results = p.run({'data': x}) - print(results) - save_result(output_path, results) - - -def run_tflite(model, input_path, output_path=''): - input = read_input(input_path) - - interpreter = tf.contrib.lite.Interpreter(model_path=model) - interpreter.allocate_tensors() - - input_details = interpreter.get_input_details() - output_details = interpreter.get_output_details() - input_data = input - interpreter.set_tensor(input_details[0]['index'], input_data) - - interpreter.invoke() - output_data = interpreter.get_tensor(output_details[0]['index']) - print(output_data) - save_result(output_path, output_data) - - -def run_onnx(model, input_path, output_path=''): #args.model[0] , args.input - path = model - - #I'll leave it in case anyone needs to read the .pb file. - #proto_arr = onnx.TensorProto() - #with open(input_path, 'rb') as f: - # proto_arr.ParseFromString(f.read()) - # input_arr = onnx.numpy_helper.to_array(proto_arr) - - modelFile = onnx.load(path, 'rb') - input_arr = read_input(input_path) - output = caffe2.python.onnx.backend.run_model(modelFile, input_arr) - - print(output) - save_result(output_path, output) - - -def run_caffe(model_topology, model_weight, input_path, output_path=''): - path = model_topology - path_w = model_weight - - net = caffe.Net(path_w, path, caffe.TEST) - # TODO get 'data' parameter more universal, blobs contain other names - net.blobs['data'].data[...] = read_input(input_path) - out = net.forward() - all_names = [n for n in net._layer_names] - out = out[all_names[-1]] - save_result(output_path, out) - print(out) - - -if __name__ == '__main__': - args = regular_step() - - # run one of model runner - if args.caffe: - run_caffe(args.model[0], args.model[1], args.input, args.output_path) - elif args.caffe2: - run_caffe2(args.model[0], args.model[1], args.input, args.output_path) - elif args.tflite: - run_tflite(args.model[0], args.input, args.output_path) - elif args.onnx: - run_onnx(args.model[0], args.input, args.output_path) - diff --git a/contrib/nnc/utils/model_runner/model_runner_caffe.py b/contrib/nnc/utils/model_runner/model_runner_caffe.py new file mode 100644 index 0000000..2bb4092 --- /dev/null +++ b/contrib/nnc/utils/model_runner/model_runner_caffe.py @@ -0,0 +1,21 @@ +from common_place import * +import caffe + + +def run_caffe(model_topology, model_weight, input_path, output_path=''): + path = model_topology + path_w = model_weight + + net = caffe.Net(path_w, path, caffe.TEST) + # TODO get 'data' parameter more universal, blobs contain other names + net.blobs['data'].data[...] = read_input(input_path) + out = net.forward() + all_names = [n for n in net._layer_names] + out = out[all_names[-1]] + save_result(output_path, out) + print(out) + +if __name__ == '__main__': + args = regular_step() + + run_caffe(args.model[0], args.model[1], args.input, args.output_path) \ No newline at end of file diff --git a/contrib/nnc/utils/model_runner/model_runner_caffe2.py b/contrib/nnc/utils/model_runner/model_runner_caffe2.py new file mode 100644 index 0000000..877af28 --- /dev/null +++ b/contrib/nnc/utils/model_runner/model_runner_caffe2.py @@ -0,0 +1,22 @@ +from common_place import * + +from caffe2.python import workspace + + +def run_caffe2(init_net, predict_net, input_path, output_path =''): + x = read_input(input_path) + with open(init_net, 'rb') as f: + init_net = f.read() + + with open(predict_net, 'rb') as f: + predict_net = f.read() + p = workspace.Predictor(init_net, predict_net) + # TODO get 'data' parameter more universal, blobs contain other names + results = p.run({'data': x}) + print(results) + save_result(output_path, results) + +if __name__ == '__main__': + args = regular_step() + + run_caffe2(args.model[0], args.model[1], args.input, args.output_path) \ No newline at end of file diff --git a/contrib/nnc/utils/model_runner/model_runner_onnx.py b/contrib/nnc/utils/model_runner/model_runner_onnx.py new file mode 100644 index 0000000..9506b8e --- /dev/null +++ b/contrib/nnc/utils/model_runner/model_runner_onnx.py @@ -0,0 +1,25 @@ +from common_place import * + +import onnx +import caffe2.python.onnx.backend + +def run_onnx(model, input_path, output_path=''): #args.model[0] , args.input + path = model + + #I'll leave it in case anyone needs to read the .pb file. + #proto_arr = onnx.TensorProto() + #with open(input_path, 'rb') as f: + # proto_arr.ParseFromString(f.read()) + # input_arr = onnx.numpy_helper.to_array(proto_arr) + + modelFile = onnx.load(path, 'rb') + input_arr = read_input(input_path) + output = caffe2.python.onnx.backend.run_model(modelFile, input_arr) + + print(output) + save_result(output_path, output) + +if __name__ == '__main__': + args = regular_step() + + run_onnx(args.model[0], args.input, args.output_path) diff --git a/contrib/nnc/utils/model_runner/model_runner_tflite.py b/contrib/nnc/utils/model_runner/model_runner_tflite.py new file mode 100644 index 0000000..2b32aaf --- /dev/null +++ b/contrib/nnc/utils/model_runner/model_runner_tflite.py @@ -0,0 +1,23 @@ +from common_place import * +import tensorflow as tf + +def run_tflite(model, input_path, output_path=''): + input = read_input(input_path) + + interpreter = tf.contrib.lite.Interpreter(model_path=model) + interpreter.allocate_tensors() + + input_details = interpreter.get_input_details() + output_details = interpreter.get_output_details() + input_data = input + interpreter.set_tensor(input_details[0]['index'], input_data) + + interpreter.invoke() + output_data = interpreter.get_tensor(output_details[0]['index']) + print(output_data) + save_result(output_path, output_data) + +if __name__ == '__main__': + args = regular_step() + + run_tflite(args.model[0], args.input, args.output_path) diff --git a/contrib/nnc/utils/model_runner/readme.md b/contrib/nnc/utils/model_runner/readme.md index 6606a41..51ff65b 100644 --- a/contrib/nnc/utils/model_runner/readme.md +++ b/contrib/nnc/utils/model_runner/readme.md @@ -15,19 +15,19 @@ The purpose of the examples below is to demonstrate which arguments and in which caffe: ``` -$ python3 model_runner.py --caffe -m caffe1_runer/inception-v3_ref.caffemodel caffe1_runer/inception-v3_ref.prototxt -i caffe1_runer/ILSVRC2012_val_00000002.JPEG.tfl.hdf5 +$ python3 model_runner.py -m caffe1_runer/inception-v3_ref.caffemodel caffe1_runer/inception-v3_ref.prototxt -i caffe1_runer/ILSVRC2012_val_00000002.JPEG.tfl.hdf5 ``` caffe2: ``` -$ python model_runner.py --caffe2 -m caffe2_runer_and_photo/caffe2_models/init_net.pb caffe2_runer_and_photo/caffe2_models/predict_net.pb -i randomInput.hdf5 +$ python model_runner.py -m caffe2_runer_and_photo/caffe2_models/init_net.pb caffe2_runer_and_photo/caffe2_models/predict_net.pb -i randomInput.hdf5 ``` tflite: ``` -$ python model_runner.py --tflite -m tflite_runer_and_photo/TST-1-2\ AVARAGE_POOP_2D.tflite -i tflite_runer_and_photo/in.hdf5 +$ python model_runner.py -m tflite_runer_and_photo/TST-1-2\ AVARAGE_POOP_2D.tflite -i tflite_runer_and_photo/in.hdf5 ``` onnx: ``` -$ python model_runner.py --onnx -m onnx_runer/model.onnx -i onnx_runer/input_0.pb +$ python model_runner.py -m onnx_runer/model.onnx -i RANDOM.hdf5 ``` ------ @@ -36,4 +36,4 @@ $ python model_runner.py --onnx -m onnx_runer/model.onnx -i onnx_runer/input_0.p -m mean pre learned model which you run -i mean model's input - --caffe --caffe2 --onnx --tflite - keys which talk script how to work with input files + -- 2.7.4