def test_initializer(self): X = np.array([[1, 2], [3, 4]]).astype(np.float32) Y = np.array([[1, 2], [3, 4]]).astype(np.float32) weight = np.array([[1, 0], [0, 1]]) graph_def = make_graph( [ make_node("Add", ["X", "Y"], ["Z0"]), make_node("Cast", ["Z0"], ["Z"], to="float"), make_node("Mul", ["Z", "weight"], ["W0"]), make_node("Tanh", ["W0"], ["W1"]), make_node("Sigmoid", ["W1"], ["W2"]), make_node("Scale", ["W2"], ["W3"], scale=-1.0) ], name="test_initializer", inputs=[ make_tensor_value_info("X", onnx.TensorProto.FLOAT, (2, 2)), make_tensor_value_info("Y", onnx.TensorProto.FLOAT, (2, 2)), make_tensor_value_info("weight", onnx.TensorProto.FLOAT, (2, 2)), ], outputs=[ make_tensor_value_info("W3", onnx.TensorProto.FLOAT, (2, 2)) ], initializer=[ make_tensor("weight", onnx.TensorProto.FLOAT, [2, 2], weight.flatten().astype(float)) ]) def sigmoid(x): return 1 / (1 + np.exp(-x)) W_ref = -sigmoid(np.tanh((X + Y) * weight)) c2_rep = c2.prepare(make_model(graph_def)) output = c2_rep.run({"X": X, "Y": Y}) np.testing.assert_almost_equal(output["W3"], W_ref)
def _test_net(self, net_name, input_blob_dims=[1, 3, 224, 224], decimal=7): model_dir = self.model_dir(net_name) # predict net is stored as a protobuf text c2_predict_pb = os.path.join(model_dir, 'predict_net.pbtxt') c2_predict_net = caffe2_pb2.NetDef() with open(c2_predict_pb, 'r') as f: google.protobuf.text_format.Merge(f.read(), c2_predict_net) c2_predict_net.name = net_name # init net(weights) is stored as a protobuf binary c2_init_pb = os.path.join(model_dir, 'init_net.pb') c2_init_net = caffe2_pb2.NetDef() with open(c2_init_pb, 'rb') as f: c2_init_net.ParseFromString(f.read()) c2_init_net.name = net_name + '_init' n, c, h, w = input_blob_dims data = np.random.randn(n, c, h, w).astype(np.float32) inputs = [data] c2_ref = c2_onnx.caffe2_net_reference(c2_init_net, c2_predict_net, inputs) init_graph = c2_onnx.caffe2_net_to_onnx_graph(c2_init_net) predict_graph = c2_onnx.caffe2_net_to_onnx_graph(c2_predict_net) c2_ir = c2.prepare(predict_graph, init_graph=init_graph) onnx_output = c2_ir.run(inputs) for blob_name in c2_ref.keys(): np.testing.assert_almost_equal(onnx_output[blob_name], c2_ref[blob_name], decimal=decimal)
def _test_net(self, net_name, input_blob_dims=(1, 3, 224, 224), decimal=7): np.random.seed(seed=0) model_dir = self._model_dir(net_name) if not os.path.exists(model_dir): self._download(net_name) c2_predict_pb = os.path.join(model_dir, 'predict_net.pb') c2_predict_net = caffe2_pb2.NetDef() with open(c2_predict_pb, 'rb') as f: c2_predict_net.ParseFromString(f.read()) c2_predict_net.name = net_name c2_init_pb = os.path.join(model_dir, 'init_net.pb') c2_init_net = caffe2_pb2.NetDef() with open(c2_init_pb, 'rb') as f: c2_init_net.ParseFromString(f.read()) c2_init_net.name = net_name + '_init' n, c, h, w = input_blob_dims data = np.random.randn(n, c, h, w).astype(np.float32) inputs = [data] _, c2_outputs = c2_native_run_net(c2_init_net, c2_predict_net, inputs) del _ model = c2_onnx.caffe2_net_to_onnx_model( predict_net=c2_predict_net, init_net=c2_init_net, value_info=json.load( open(os.path.join(model_dir, 'value_info.json')))) c2_ir = c2.prepare(model) onnx_outputs = c2_ir.run(inputs) self.assertSameOutputs(c2_outputs, onnx_outputs, decimal=decimal) self.report_mem_usage(net_name)
def test_embed_params(proto, model, input, state_dict=None, use_gpu=True): """ This is only a helper debug function so we can test embed_params=False case as well on pytorch front This should likely be removed from the release version of the code """ device = 'CPU' if use_gpu: device = 'CUDA' model_def = onnx.ModelProto.FromString(proto) onnx.checker.check_model(model_def) prepared = c2.prepare(model_def, device=device) if state_dict: parameters = [] # Passed in state_dict may have a different order. Make # sure our order is consistent with the model's order. # TODO: Even better: keyword arguments! for k in model.state_dict(): parameters.append(state_dict[k]) else: parameters = list(model.state_dict().values()) W = {} for k, v in zip(model_def.graph.input, flatten((input, parameters))): if isinstance(v, Variable): W[k.name] = v.data.cpu().numpy() else: W[k.name] = v.cpu().numpy() caffe2_out = prepared.run(inputs=W) return caffe2_out
def test_relu_graph(self): inputs = ['X'] outputs = ['Y'] graph_def = helper.make_graph( [helper.make_node("Relu", inputs, outputs)], name="test", inputs=inputs, outputs=outputs) X = np.random.randn(3, 2).astype(np.float32) Y_ref = np.clip(X, 0, np.inf) # Testing with a list c2_rep = c2.prepare(graph_def) output = c2_rep.run({"X": X}) np.testing.assert_almost_equal(output["Y"], Y_ref)
def run_generated_test(model_file, data_dir, device='CPU'): model = onnx.load(model_file) input_num = len(glob.glob(os.path.join(data_dir, "input_*.pb"))) inputs = [] for i in range(input_num): inputs.append(numpy_helper.to_array(load_tensor_as_numpy_array( os.path.join(data_dir, "input_{}.pb".format(i))))) output_num = len(glob.glob(os.path.join(data_dir, "output_*.pb"))) outputs = [] for i in range(output_num): outputs.append(numpy_helper.to_array(load_tensor_as_numpy_array( os.path.join(data_dir, "output_{}.pb".format(i))))) prepared = c2.prepare(model, device=device) c2_outputs = prepared.run(inputs) assert_similar(outputs, c2_outputs)
def _onnx_as_caffe2(fpath): import onnx_caffe2.backend as backend import numpy as np import onnx import onnx.helper import onnx.checker model = onnx.load(fpath) onnx.checker.check_model(model) rep = backend.prepare(model, device='CUDA:0') # or "CPU" # For the Caffe2 backend: # rep.predict_net is the Caffe2 protobuf for the network # rep.workspace is the Caffe2 workspace for the network # (see the class onnx_caffe2.backend.Workspace) outputs = rep.run(np.random.randn(10, 3, 224, 224).astype(np.float32)) # To run networks with more than one input, pass a tuple # rather than a single numpy ndarray. print(outputs[0])
def test_relu_graph(self): X = np.random.randn(3, 2).astype(np.float32) Y_ref = np.clip(X, 0, np.inf) node_def = make_node( "Relu", ["X"], ["Y"]) output = c2.run_node( node_def, {"X": X}) np.testing.assert_almost_equal(output.Y, Y_ref) graph_def = make_graph( [node_def], name="test", inputs=[make_tensor_value_info("X", onnx.TensorProto.FLOAT, [3, 2])], outputs=[make_tensor_value_info("Y", onnx.TensorProto.FLOAT, [3, 2])]) c2_rep = c2.prepare(make_model(graph_def)) output = c2_rep.run(X) np.testing.assert_almost_equal(output.Y, Y_ref)
def test_relu_node_inplace(self): node_def = helper.make_node( "Relu", ["X"], ["Y"], consumed_inputs=[1]) X = np.random.randn(3, 2).astype(np.float32) output = c2.run_node( node_def, {"X": X}) graph_def = helper.make_graph( [node_def], name="test", inputs=["X"], outputs=["X", "Y"]) Y_ref = np.clip(X, 0, np.inf) c2_rep = c2.prepare(graph_def) output = c2_rep.run({"X": X}) # With the inplace change from Zach, there shouldn't be Y # np.testing.assert_almost_equal(output["Y"], Y_ref) # ensure we wrote over X np.testing.assert_almost_equal(output["X"], Y_ref)
def pytorch_to_onnx(torch_model, dummy_input, model_name): #dummy_input = Variable(torch.rand(1, 1, 96, 96)) torch_model.cpu() torch_model.train(False) torch_model.convert_to_onnx = True torch.onnx.export(torch_model, dummy_input, f"trained_models/{model_name}.proto", verbose=False, export_params=True) # test if it works onnx_model = onnx.load(f"trained_models/{model_name}.proto") onnx.checker.check_model(onnx_model) print(onnx.helper.printable_graph(onnx_model.graph)) rep = backend.prepare(onnx_model, device="CPU") print(rep.run(dummy_input.data.cpu().numpy())[0]) return rep
def _test_net(self, net_name, input_blob_dims=(1, 3, 224, 224), decimal=7): np.random.seed(seed=0) model_dir = self._model_dir(net_name) if not os.path.exists(model_dir): self._download(net_name) c2_predict_pb = os.path.join(model_dir, 'predict_net.pb') c2_predict_net = caffe2_pb2.NetDef() with open(c2_predict_pb, 'rb') as f: c2_predict_net.ParseFromString(f.read()) c2_predict_net.name = net_name c2_init_pb = os.path.join(model_dir, 'init_net.pb') c2_init_net = caffe2_pb2.NetDef() with open(c2_init_pb, 'rb') as f: c2_init_net.ParseFromString(f.read()) c2_init_net.name = net_name + '_init' n, c, h, w = input_blob_dims data = np.random.randn(n, c, h, w).astype(np.float32) inputs = [data] c2_outputs = c2_native_run_net(c2_init_net, c2_predict_net, inputs) for input_name in c2_predict_net.external_input: if input_name == 'data' or input_name == 'gpu_0/data': break else: raise RuntimeError( 'Could not find input name of model {}'.format(net_name)) predict_model = c2_onnx.caffe2_net_to_onnx_model( predict_net=c2_predict_net, init_net=c2_init_net, value_info={ input_name: (onnx_pb2.TensorProto.FLOAT, (1, 3, 224, 224)) }) c2_ir = c2.prepare(predict_model) onnx_outputs = c2_ir.run(inputs) self.assertSameOutputs(c2_outputs, onnx_outputs, decimal=decimal) self.report_mem_usage(net_name)
def test(self): _model = onnx.load(self.MODEL_PATH + "shufflenet/model.pb") node_count = len(_model.graph.node) more_outputs = [] output_to_check = [] for node in _model.graph.node: more_outputs.append( helper.make_tensor_value_info(node.output[0], TensorProto.FLOAT, (100, 100))) output_to_check.append(node.output[0]) _model.graph.output.extend(more_outputs) tf_rep = tf.prepare(_model) cf_rep = c2.prepare(_model) sample = np.load(self.MODEL_PATH + "shufflenet/test_data_{}.npz".format(str(1)), encoding='bytes') inputs = list(sample['inputs']) outputs = list(sample['outputs']) my_out = tf_rep.run(inputs) cf_out = cf_rep.run(inputs) for op in output_to_check: try: np.savetxt(op.replace("/", "__") + ".cf", cf_out[op].flatten(), delimiter='\t') np.savetxt(op.replace("/", "__") + ".tf", my_out[op].flatten(), delimiter='\t') np.testing.assert_allclose(my_out[op], cf_out[op], rtol=1e-2) print(op, "results of this layer are correct within tolerence.") except Exception as e: np.set_printoptions(threshold=np.inf) mismatch_percent = (find_between(str(e), "(mismatch", "%)")) print(op, "mismatch with percentage {} %".format(mismatch_percent))
# load model model = torch.load("model.p") model.cpu() # Evaluation Mode model.train(False) # Create dummy input dummy_input = Variable(torch.randn(1, 3, 224, 224)) output_torch = model(dummy_input) # Export ONNX model torch.onnx.export(model, dummy_input, "model.proto", verbose=True) # Load ONNX model graph = onnx.load("model.proto") # Check Formation onnx.checker.check_graph(graph) # Print Graph to get blob names onnx.helper.printable_graph(graph) # Check model output rep = backend.prepare(graph, device="CPU") output_onnx = rep.run(dummy_input.cpu().data.numpy().astype(np.float32)) # Verify the numerical correctness upto 3 decimal places np.testing.assert_almost_equal(output_torch.data.cpu().numpy(), output_onnx[0], decimal=3)
import onnx import onnx_caffe2.backend as backend # Prepare the inputs, here we use numpy to generate some random inputs for demo purpose import numpy as np img = np.random.randn(1, 3, 224, 224).astype(np.float32) # Load the ONNX model model = onnx.load('TFeat_tf.onnx') # Run the ONNX model with Caffe2 outputs = backend.prepare(model, [img])
output_torch = model(inp) # # # Export ONNX model torch.onnx.export(model, inp, "/media/SRResNet/model.proto", verbose=True) # # # Load ONNX model onnx_model = onnx.load("/media/SRResNet/model.proto") # onnx_model.ir_version = 1 # # Check Formation onnx.checker.check_graph(onnx_model.graph) # # Print Graph to get blob names onnx.helper.printable_graph(onnx_model.graph) # # Check model output rep = backend.prepare(onnx_model, device="CPU") inp_onnx = x print(inp_onnx) output_onnx = rep.run(inp_onnx) print(adjust(output_torch.data.numpy()[0])) print(adjust(output_onnx[0][0])) img_torch = adjust(output_torch.data.numpy()[0]) img_onnx = adjust(output_onnx[0][0]) print(np.max(np.abs(img_torch - img_onnx))) print(np.mean(np.abs(img_torch - img_onnx))) # # # # Verify the numerical correctness upto 3 decimal places # np.testing.assert_almost_equal(output_torch.data.numpy(), output_onnx[0], decimal=3) j = Image.fromarray(img_torch)
model = torchvision.models.alexnet(pretrained=True).cuda() torch.onnx.export(model, dummy_input, "alexnet.proto", verbose=True) #关键参数verbose=True使exporter可以打印出一种人类可读的网络表示 #验证 #conda install -c conda-forge onnx import onnx # Load the ONNX model model = onnx.load("alexnet.proto") # Check that the IR is well formed onnx.checker.check_model(model) # Print a human readable representation of the graph onnx.helper.printable_graph(model.graph) #pip install onnx-caffe2 # ...continuing from above import onnx_caffe2.backend as backend import numpy as np # or "CPU" rep = backend.prepare(model, device="CUDA:0") # For the Caffe2 backend: # rep.predict_net is the Caffe2 protobuf for the network # rep.workspace is the Caffe2 workspace for the network # (see the class onnx_caffe2.backend.Workspace) outputs = rep.run(np.random.randn(10, 3, 224, 224).astype(np.float32)) # To run networks with more than one input, pass a tuple # rather than a single numpy ndarray. print(outputs[0])