Beispiel #1
0
    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]))
Beispiel #2
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))
Beispiel #3
0
    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_))
Beispiel #4
0
    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')
Beispiel #6
0
    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))
Beispiel #7
0
    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))
Beispiel #8
0
    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])
Beispiel #16
0
    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)
Beispiel #24
0
    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')
Beispiel #28
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