def test_transformer1(self): try: import onnx from dlpy.model_conversion.onnx_transforms import (Transformer, OpTypePattern, ConstToInitializer, InitReshape, InitUnsqueeze, FuseMulAddBN) from dlpy.model_conversion.onnx_graph import OnnxGraph from onnx import helper, numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') node1 = helper.make_node( 'Identity', inputs=['in'], outputs=['out'], name='Identity_1' ) graph_ = helper.make_graph( nodes=[node1], name='', inputs=[], outputs=[], initializer=[] ) graph = OnnxGraph.from_onnx(graph_) pattern = OpTypePattern('Identity') transform = Transformer(pattern) self.assertTrue(transform.match(graph.node[0]))
def test_const_to_initializer(self): try: import onnx from dlpy.model_conversion.onnx_transforms import ( Transformer, OpTypePattern, ConstToInitializer, InitReshape, InitUnsqueeze, FuseMulAddBN) from dlpy.model_conversion.onnx_graph import OnnxGraph from onnx import helper, numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') values = np.random.randn(5, 5).astype(np.float32) const_1 = helper.make_node('Constant', inputs=[], outputs=['constant_out'], name='Constant_1', value=onnx.helper.make_tensor( name='const_tensor', data_type=onnx.TensorProto.FLOAT, dims=values.shape, vals=values.flatten().astype(float), )) graph_ = helper.make_graph(nodes=[const_1], name='', inputs=[], outputs=[], initializer=[]) graph = OnnxGraph.from_onnx(graph_) graph = ConstToInitializer()(graph) self.assertEqual(len(graph.node), 0) self.assertTrue('constant_out' in graph.tensor_dict) t = graph.tensor_dict['constant_out'] self.assertTrue(np.array_equal(values, t))
def test_fuse_mul_add_bn(self): try: import onnx from dlpy.model_conversion.onnx_transforms import ( Transformer, OpTypePattern, ConstToInitializer, InitReshape, InitUnsqueeze, FuseMulAddBN) from dlpy.model_conversion.onnx_graph import OnnxGraph from onnx import helper, numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') nodes = [ helper.make_node( 'BatchNormalization', inputs=['data', 'bn_scale', 'bn_bias', 'bn_mean', 'bn_var'], outputs=['bn_out'], name='BatchNormalization_1'), helper.make_node('Mul', inputs=['bn_out', 'mul1'], outputs=['mul_out'], name='Mul_2'), helper.make_node('Add', inputs=['mul_out', 'add1'], outputs=['add_out'], name='Add_3') ] bn_scale = np.random.rand(64).astype('float32') bn_bias = np.random.rand(64).astype('float32') bn_mean = np.random.rand(64).astype('float32') bn_var = np.random.rand(64).astype('float32') mul1 = np.random.rand(64, 1, 1) add1 = np.random.rand(64, 1, 1) initializer = [ numpy_helper.from_array(bn_scale, name='bn_scale'), numpy_helper.from_array(bn_bias, name='bn_bias'), numpy_helper.from_array(bn_mean, name='bn_mean'), numpy_helper.from_array(bn_var, name='bn_var'), numpy_helper.from_array(mul1, name='mul1'), numpy_helper.from_array(add1, name='add1') ] graph_ = helper.make_graph(nodes=nodes, name='', inputs=[], outputs=[], initializer=initializer) graph = OnnxGraph.from_onnx(graph_) graph = FuseMulAddBN()(graph) self.assertEqual(len(graph.node), 1) self.assertEqual(graph.node[0].name, 'BatchNormalization_1') s = graph.tensor_dict['bn_scale'] b = graph.tensor_dict['bn_bias'] s_ = np.multiply(bn_scale, np.squeeze(mul1)) b_ = np.multiply(bn_bias, np.squeeze(mul1)) b_ = np.add(b_, np.squeeze(add1)) self.assertTrue(np.array_equal(s, s_)) self.assertTrue(np.array_equal(b, b_))
def test_init_reshape(self): try: import onnx from dlpy.model_conversion.onnx_transforms import ( Transformer, OpTypePattern, ConstToInitializer, InitReshape, InitUnsqueeze, FuseMulAddBN) from dlpy.model_conversion.onnx_graph import OnnxGraph from onnx import helper, numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') reshape_1 = helper.make_node('Reshape', inputs=['reshape_in', 'shape'], outputs=['reshape_out'], name='Reshape_1') reshape_in = np.random.rand(64).astype('float32') shape = np.array([8, 8]) init = numpy_helper.from_array(reshape_in, name='reshape_in') shape_init = numpy_helper.from_array(shape, name='shape') graph_ = helper.make_graph(nodes=[reshape_1], name='', inputs=[], outputs=[], initializer=[init, shape_init]) graph = OnnxGraph.from_onnx(graph_) graph = InitReshape()(graph) self.assertEqual(len(graph.node), 0) self.assertTrue('reshape_out' in graph.tensor_dict) t = graph.tensor_dict['reshape_out'] self.assertEqual(t.shape, (8, 8))
def test_graph1(self): try: import onnx from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) self.assertEqual(len(graph.node), 1) self.assertEqual(len(graph.initializer), 1) self.assertEqual(len(graph.input), 2) self.assertEqual(len(graph.output), 1) self.assertEqual(len(graph.uninitialized), 1) self.assertEqual(graph.node[0].name, 'Conv_0') self.assertTrue(not graph.node[0].parents) self.assertTrue(not graph.node[0].children) self.assertEqual(graph.initializer[0].name, 'conv0') self.assertEqual(graph.input[0].name, 'data0') self.assertEqual(graph.input[1].name, 'conv0') self.assertEqual(graph.output[0].name, 'output0') self.assertTrue('conv0' in graph.tensor_dict) self.assertEqual(graph.uninitialized[0].name, 'data0')
def test_const_to_initializer(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import helper values = np.random.randn(5, 5).astype(np.float32) const_1 = helper.make_node('Constant', inputs=[], outputs=['constant_out'], name='Constant_1', value=onnx.helper.make_tensor( name='const_tensor', data_type=onnx.TensorProto.FLOAT, dims=values.shape, vals=values.flatten().astype(float), )) graph_ = helper.make_graph(nodes=[const_1], name='', inputs=[], outputs=[], initializer=[]) graph = OnnxGraph.from_onnx(graph_) graph = ConstToInitializer()(graph) self.assertEqual(len(graph.node), 0) self.assertTrue('constant_out' in graph.tensor_dict) t = graph.tensor_dict['constant_out'] self.assertTrue(np.array_equal(values, t))
def test_init_reshape(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import helper, numpy_helper reshape_1 = helper.make_node('Reshape', inputs=['reshape_in', 'shape'], outputs=['reshape_out'], name='Reshape_1') reshape_in = np.random.rand(64).astype('float32') shape = np.array([8, 8]) init = numpy_helper.from_array(reshape_in, name='reshape_in') shape_init = numpy_helper.from_array(shape, name='shape') graph_ = helper.make_graph(nodes=[reshape_1], name='', inputs=[], outputs=[], initializer=[init, shape_init]) graph = OnnxGraph.from_onnx(graph_) graph = InitReshape()(graph) self.assertEqual(len(graph.node), 0) self.assertTrue('reshape_out' in graph.tensor_dict) t = graph.tensor_dict['reshape_out'] self.assertEqual(t.shape, (8, 8))
def test_init_unsqueeze(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import helper, numpy_helper unsqueeze_1 = helper.make_node('Unsqueeze', inputs=['unsqueeze_in'], outputs=['unsqueeze_out'], name='Unsqueeze_1', axes=[1, 2]) unsqueeze_in = np.random.rand(64).astype('float32') init = numpy_helper.from_array(unsqueeze_in, name='unsqueeze_in') graph_ = helper.make_graph(nodes=[unsqueeze_1], name='', inputs=[], outputs=[], initializer=[init]) graph = OnnxGraph.from_onnx(graph_) graph = InitUnsqueeze()(graph) self.assertEqual(len(graph.node), 0) self.assertTrue('unsqueeze_out' in graph.tensor_dict) t = graph.tensor_dict['unsqueeze_out'] t = np.squeeze(t) self.assertTrue(np.array_equal(unsqueeze_in, t))
def test_remove_node1(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) graph.remove_node('abcdef') self.assertEqual(len(graph.node), 1)
def test_remove_node(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) graph.remove_node('Conv_0') self.assertTrue(not graph.node)
def test_get_initializer1(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) init = graph.get_initializer('abcdef') self.assertEqual(init, None)
def test_get_input1(self): try: import onnx from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) i = graph.get_input('abcdef') self.assertEqual(i, None)
def test_graph_connection(self): try: import onnx from onnx import helper, numpy_helper, TensorProto from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode except: unittest.TestCase.skipTest(self, 'onnx package not found') input0 = helper.make_tensor_value_info('data0', TensorProto.FLOAT, [1, 3, 224, 224]) input1 = helper.make_tensor_value_info('conv0', TensorProto.FLOAT, [64, 3, 7, 7]) output0 = helper.make_tensor_value_info('output0', TensorProto.FLOAT, [1, 64, 122, 122]) conv_op = helper.make_node('Conv', inputs=['data0', 'conv0'], outputs=['conv_out'], kernel_shape=[7, 7], pads=[3, 3, 3, 3], strides=[2, 2]) identity_op = helper.make_node('Identity', inputs=['conv_out'], outputs=['output0']) conv0 = np.random.rand(64, 3, 7, 7).astype('float32') init0 = numpy_helper.from_array(conv0, name='conv0') graph_ = helper.make_graph(nodes=[conv_op, identity_op], name='', inputs=[input0, input1], outputs=[output0], initializer=[init0]) graph = OnnxGraph.from_onnx(graph_) self.assertEqual(len(graph.node), 2) self.assertEqual(graph.node[0].name, 'Conv_0') self.assertTrue(not graph.node[0].parents) self.assertEqual(len(graph.node[0].children), 1) self.assertEqual(graph.node[0].children[0].name, 'Identity_1') self.assertTrue('conv0' in graph.node[0].tensors) self.assertEqual(graph.node[1].name, 'Identity_1') self.assertEqual(len(graph.node[1].parents), 1) self.assertEqual(graph.node[1].parents[0].name, 'Conv_0') self.assertTrue(not graph.node[1].children) self.assertTrue(not graph.node[1].tensors)
def test_get_node(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) self.assertEqual(graph.get_node('Conv_0').name, 'Conv_0') self.assertEqual(graph.get_node_index('Conv_0'), 0) self.assertEqual(graph.get_node('abcdef'), None) self.assertEqual(graph.get_node_index('abcdef'), None)
def test_get_input(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) i = graph.get_input('data0') self.assertEqual(i.name, 'data0') self.assertEqual([d.dim_value for d in i.type.tensor_type.shape.dim], [1, 3, 224, 224])
def test_transformer3(self): try: import onnx from dlpy.model_conversion.onnx_transforms import (Transformer, OpTypePattern, ConstToInitializer, InitReshape, InitUnsqueeze, FuseMulAddBN) from dlpy.model_conversion.onnx_graph import OnnxGraph from onnx import helper, numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') nodes = [ helper.make_node('Unsqueeze', inputs=['unsqueeze_in'], outputs=['unsqueeze_out'], name='Unsqueeze_1', axes=[1, 2] ), helper.make_node('Mul', inputs=['unsqueeze_out', 'mul1'], outputs=['mul_out'], name='Mul_2' ), helper.make_node('Add', inputs=['mul_out', 'add1'], outputs=['add_out'], name='Add_3' ), ] graph_ = helper.make_graph( nodes=nodes, name='', inputs=[], outputs=[], initializer=[] ) graph = OnnxGraph.from_onnx(graph_) pattern = OpTypePattern('Add', name='op3') pattern = OpTypePattern('Mul', name='op2', outputs=[pattern]) pattern = OpTypePattern('Unsqueeze', name='op1', outputs=[pattern]) transform = Transformer(pattern) mapping = transform.get_mapping(graph.node[0]) self.assertEqual(len(mapping), 3) self.assertEqual(mapping['op3'].name, 'Add_3') self.assertEqual(mapping['op2'].name, 'Mul_2') self.assertEqual(mapping['op1'].name, 'Unsqueeze_1')
def test_make_model(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) model = graph.make_onnx() g = model.graph self.assertEqual(len(g.node), 1) self.assertEqual(g.node[0].name, 'Conv_0') self.assertEqual(len(g.input), 2)
def test_get_initializer(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import numpy_helper graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) init = graph.get_initializer('conv0') conv0 = numpy_helper.to_array(init) self.assertEqual(init.name, 'conv0') self.assertTrue(np.array_equal(conv0, graph.tensor_dict['conv0']))
def test_replace_input(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import helper, TensorProto graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) value_info = helper.make_tensor_value_info('data1', TensorProto.FLOAT, [1, 3, 299, 299]) graph.replace_input('data0', value_info) self.assertEqual(len(graph.input), 2) self.assertEqual(graph.input[0], value_info)
def test_clean_init(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) graph.remove_node('Conv_0') graph.clean_init() self.assertTrue(not graph.input) self.assertTrue(not graph.initializer) self.assertTrue(not graph.tensor_dict)
def test_add_input(self): try: import onnx from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode from onnx import helper, TensorProto except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) value_info = helper.make_tensor_value_info('data1', TensorProto.FLOAT, [1, 3, 299, 299]) graph.add_input(value_info) self.assertEqual(len(graph.input), 3) self.assertEqual(graph.input[-1], value_info)
def test_replace_initializer(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import numpy_helper graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) conv1 = np.random.rand(64, 3, 7, 7).astype('float32') init1 = numpy_helper.from_array(conv1, name='conv1') graph.replace_initializer('conv0', init1) self.assertEqual(len(graph.initializer), 1) self.assertEqual(graph.initializer[0], init1)
def test_add_initializer(self): try: import onnx from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode from onnx import numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) conv1 = np.random.rand(64, 3, 7, 7).astype('float32') init1 = numpy_helper.from_array(conv1, name='conv1') graph.add_initializer(init1) self.assertEqual(len(graph.initializer), 2) self.assertEqual(graph.initializer[1], init1)
def test_transformer2(self): try: import onnx from dlpy.model_conversion.onnx_transforms import (Transformer, OpTypePattern, ConstToInitializer, InitReshape, InitUnsqueeze, FuseMulAddBN) from dlpy.model_conversion.onnx_graph import OnnxGraph from onnx import helper, numpy_helper except: unittest.TestCase.skipTest(self, 'onnx package not found') nodes = [ helper.make_node('Unsqueeze', inputs=['unsqueeze_in'], outputs=['unsqueeze_out'], name='Unsqueeze_1', axes=[1, 2] ), helper.make_node('Mul', inputs=['unsqueeze_out', 'mul1'], outputs=['mul_out'], name='Mul_2' ), helper.make_node('Add', inputs=['mul_out', 'add1'], outputs=['add_out'], name='Add_3' ) ] graph_ = helper.make_graph( nodes=nodes, name='', inputs=[], outputs=[], initializer=[] ) graph = OnnxGraph.from_onnx(graph_) transform = Transformer() pattern = OpTypePattern('Unsqueeze', outputs=[OpTypePattern('Mul', outputs=['Add'])]) self.assertTrue(transform.match(graph.node[0], pattern)) self.assertFalse(transform.match(graph.node[1], pattern))
def test_insert_node1(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import helper graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) new_node = helper.make_node('Identity', inputs=[], outputs=[], name='test_node') new_node = OnnxNode(new_node) graph.insert_node('abcdef', new_node) self.assertEqual(len(graph.node), 1) self.assertEqual(graph.node[0].name, 'Conv_0')
def test_insert_node(self): try: import onnx from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode from onnx import helper except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) new_node = helper.make_node('Identity', inputs=[], outputs=[], name='test_node') new_node = OnnxNode(new_node) graph.insert_node('Conv_0', new_node) self.assertEqual(len(graph.node), 2) self.assertEqual(graph.node[1].name, 'test_node')
def test_replace_node1(self): try: import onnx from onnx import helper from dlpy.model_conversion.onnx_graph import OnnxGraph, OnnxNode except: unittest.TestCase.skipTest(self, 'onnx package not found') graph_ = self._generate_graph1() graph = OnnxGraph.from_onnx(graph_) node_ = graph.node[0] new_node = helper.make_node('Identity', inputs=node_.input, outputs=node_.output, name='test_node') new_node = OnnxNode(new_node) graph.replace_node('abcdef', new_node) self.assertEqual(len(graph.node), 1) self.assertEqual(graph.node[0].name, 'Conv_0')
def test_transformer1(self): try: import onnx except: unittest.TestCase.skipTest(self, 'onnx package not found') from onnx import helper, numpy_helper node1 = helper.make_node('Identity', inputs=['in'], outputs=['out'], name='Identity_1') graph_ = helper.make_graph(nodes=[node1], name='', inputs=[], outputs=[], initializer=[]) graph = OnnxGraph.from_onnx(graph_) pattern = OpTypePattern('Identity') transform = Transformer(pattern) self.assertTrue(transform.match(graph.node[0]))
def onnx_to_sas(model, model_name=None, output_layer=None): ''' Generate SAS model from ONNX model Parameters ---------- model : ONNX ModelProto Specifies the loaded ONNX model. model_name : string, optional Specifies the name of the model. output_layer : Layer object, optional Specifies the output layer of the model. If no output layer is specified, the last layer is automatically set as :class:`OutputLayer` with SOFTMAX activation. Returns ------- list List of Layers ''' # run transforms graph_ = OnnxGraph.from_onnx(model.graph) transforms = [ ConstToInitializer(), InitReshape(), InitUnsqueeze(), FuseMulAddBN() ] for transform in transforms: transform(graph_) model = graph_.make_onnx() # verify model ops are supported for n in model.graph.node: if n.op_type not in _onnx_ops + list(_act_map.keys()): raise OnnxParseError('Unsupported op: ' + n.op_type) # get shapes of tensors in graph model = infer_shapes(model) graph_def = model.graph dlpy_layers = [] if model_name is None: model_name = graph_def.name # nodes that correspond to sas deeplearn layers sas_computation_nodes = onnx_filter_sas_layers(graph_def) # initializer: TensorProtos representing values to initialize # initialized: A list of names of the initialized tensors if graph_def.initializer: init_tensors = onnx_initializer_to_tensors(graph_def.initializer) initialized = [init.name for init in graph_def.initializer] else: init_tensors = [] initialized = [] tensor_dict = dict(init_tensors) # determine SAS input layers from uninitialized input ValueInfo uninitialized = [value_info for value_info in graph_def.input if value_info.name not in initialized] if not uninitialized: raise OnnxParseError('Unable to determine input layer.') elif len(uninitialized) > 1: # TODO: support multipe input layers raise OnnxParseError('Unable to determine input layer.') else: scale_node = None for node in graph_def.node: if node.op_type == 'ImageScaler': scale_node = node input_layer = onnx_input_layer(uninitialized[0], scale_node) dlpy_layers.append(input_layer) # create SAS layers from the ONNX nodes for node in sas_computation_nodes: layer = onnx_extract_sas_layer(graph_def, node, dlpy_layers) dlpy_layers.append(layer) # apply activations for node in graph_def.node: if node.op_type in _act_map.keys(): # handle output layer activations separately if node.op_type == 'Softmax': continue previous = onnx_find_previous_compute_layer(graph_def, node) if len(previous) != 1: print('Warning: Unable to apply activation for node ' + str(node.name) + '.') continue for layer in dlpy_layers: # TODO: better checks for valid activations if layer.name == previous[0].name: if 'act' in layer.config.keys(): layer.config.update(act=_act_map.get(node.op_type)) else: print('Warning: Unable to apply activation for ' + layer.name + ' layer.') # apply dropout for node in graph_def.node: if node.op_type == 'Dropout': previous = onnx_find_previous_compute_layer(graph_def, node) if len(previous) != 1: print('Warning: Unable to apply dropout. ' 'More than one source layer found.') continue for layer in dlpy_layers: if layer.name == previous[0].name: if 'dropout' in layer.config.keys(): layer.config.update(dropout=node.attribute[0].f) else: print('Warning: Unable to apply dropout for' + layer.name + ' layer') # write weights hdf5 hdf5_out = write_weights_hdf5(dlpy_layers, graph_def, tensor_dict, model_name) # add output layer # if output_layer is not specified, output layer defaults to SOFTMAX if output_layer is None: # if previous layer is fc, we can replace it with output layer if dlpy_layers[-1].type == 'fc': last_layer = dlpy_layers.pop() out_layer = OutputLayer(name=last_layer.name, act='SOFTMAX', n=last_layer.config['n'], src_layers=last_layer.src_layers) dlpy_layers.append(out_layer) # if previous layer is not fc, default to loss layer only else: n = dlpy_layers[-1].output_size[-1] out_layer = OutputLayer(name='output', act='IDENTITY', n=n, include_bias=False, src_layers=[dlpy_layers[-1]]) dlpy_layers.append(out_layer) identity = np.identity(n).astype(np.float32) f = h5py.File(hdf5_out) f['output/output/kernel:0'] = identity f.close() else: # connect output_layer to previous layer output_layer.src_layers = [dlpy_layers[-1]] if not output_layer.name: output_layer.name = 'output' dlpy_layers.append(output_layer) return dlpy_layers