parameters: (self, sym, params, in_shape, in_type, verbose=False)
return_statement: return graph
docstring: Convert MXNet graph to ONNX graph
  
          Parameters
          ----------
          sym : :class:`~mxnet.symbol.Symbol`
              MXNet symbol object
          params : dict of ``str`` to :class:`~mxnet.ndarray.NDArray`
              Dict of converted parameters stored in ``mxnet.ndarray.NDArray`` format
          in_shape : List of tuple
              Input shape of the model e.g [(1,3,224,224)]
          in_type : data type
              Input data type e.g. np.float32
          verbose : Boolean
              If true will print logs of the model conversion
  
          Returns
          -------
          graph : GraphProto
              ONNX graph
docstring_summary: Convert MXNet graph to ONNX graph
docstring_tokens: Convert MXNet graph to ONNX graph
function: def create_onnx_graph_proto(self, sym, params, in_shape, in_type, verbose=False):
          """Convert MXNet graph to ONNX graph
  
          Parameters
          ----------
          sym : :class:`~mxnet.symbol.Symbol`
              MXNet symbol object
          params : dict of ``str`` to :class:`~mxnet.ndarray.NDArray`
              Dict of converted parameters stored in ``mxnet.ndarray.NDArray`` format
          in_shape : List of tuple
              Input shape of the model e.g [(1,3,224,224)]
          in_type : data type
              Input data type e.g. np.float32
          verbose : Boolean
              If true will print logs of the model conversion
  
          Returns
          -------
          graph : GraphProto
              ONNX graph
          """
          try:
              from onnx import (checker, helper, NodeProto, ValueInfoProto, TensorProto)
              from onnx.helper import make_tensor_value_info
          except ImportError:
              raise ImportError("Onnx and protobuf need to be installed. "
                                + "Instructions to install - https://github.com/onnx/onnx")
  
          # When MXNet model is saved to json file , MXNet adds a node for label.
          # The name of this node is, name of the last node + "_label" ( i.e if last node
          # name is "Softmax", this node will have a name "Softmax_label". Also, the new node
          # will always be second last node in the json graph.
          # Deriving the output_label name.
          output_label = sym.get_internals()[len(sym.get_internals()) - 1].name + "_label"
  
          weights = MXNetGraph.convert_weights_to_numpy(params)
  
          mx_graph = json.loads(sym.tojson())["nodes"]
  
          initializer = []
          all_processed_nodes = []
          onnx_processed_nodes = []
          onnx_processed_inputs = []
          onnx_processed_outputs = []
          index_lookup = []
  
          # Determine output shape
          graph_outputs = MXNetGraph.get_outputs(sym, params, in_shape, output_label)
  
          graph_input_idx = 0
          for idx, node in enumerate(mx_graph):
              op = node["op"]
              name = node["name"]
              if verbose:
                  logging.info("Converting idx: %d, op: %s, name: %s", idx, op, name)
  
              # A node is an input node if its op_name is "null" and is not
              # in params dict
              if op == "null" and name not in params:
                  # Handling graph input
  
                  # Skipping output_label node, as this node is not part of graph
                  # Refer "output_label" assignment above for more details.
                  if name == output_label:
                      continue
                  converted = MXNetGraph.convert_layer(
                      node,
                      is_input=True,
                      mx_graph=mx_graph,
                      weights=weights,
                      in_shape=in_shape[graph_input_idx],
                      in_type=in_type,
                      proc_nodes=all_processed_nodes,
                      initializer=initializer,
                      index_lookup=index_lookup)
                  graph_input_idx += 1
  
              else:
                  # Handling graph layers
                  converted = MXNetGraph.convert_layer(
                      node,
                      is_input=False,
                      mx_graph=mx_graph,
                      weights=weights,
                      in_shape=in_shape,
                      in_type=in_type,
                      proc_nodes=all_processed_nodes,
                      initializer=initializer,
                      index_lookup=index_lookup,
                      idx=idx
                  )
  
              if isinstance(converted, list):
                  # Iterate for all converted nodes
                  for converted_node in converted:
                      # If converted node is ValueInfoProto, add it in inputs
                      if isinstance(converted_node, ValueInfoProto):
                          onnx_processed_inputs.append(converted_node)
                      # If converted node is NodeProto, add it in processed nodes list
                      elif isinstance(converted_node, NodeProto):
                          onnx_processed_nodes.append(converted_node)
                          # some operators have multiple outputs,
                          # therefore, check all output node names
                          node_names = list(converted_node.output)
                          for nodename in node_names:
                              if nodename in graph_outputs:
                                  onnx_processed_outputs.append(
                                      make_tensor_value_info(
                                          name=nodename,
                                          elem_type=in_type,
                                          shape=graph_outputs[nodename]
                                      )
                                  )
                                  if verbose:
                                      logging.info("Output node is: %s", nodename)
                      elif isinstance(converted_node, TensorProto):
                          raise ValueError("Did not expect TensorProto")
                      else:
                          raise ValueError("node is of an unrecognized type: %s" % type(node))
  
                      all_processed_nodes.append(converted_node)
  
                  if idx > 0:
                      # Handling extra node added to the graph if the MXNet model was
                      # saved to json file,
                      # refer "output_label" initialization above for more details.
                      # if extra node was added then prev_index to the last node is adjusted.
                      if idx == (len(mx_graph) - 1) and \
                              mx_graph[len(mx_graph)-2]["name"] == output_label:
                          prev_index = index_lookup[idx - 2]
                      else:
                          prev_index = index_lookup[idx - 1]
  
                      index_lookup.append(prev_index+len(converted))
                  else:
                      index_lookup.append(len(converted) - 1)
              else:
                  logging.info("Operator converter function should always return a list")
  
          graph = helper.make_graph(
              onnx_processed_nodes,
              "mxnet_converted_model",
              onnx_processed_inputs,
              onnx_processed_outputs
          )
  
          graph.initializer.extend(initializer)
  
          checker.check_graph(graph)
          return graph
function_tokens: def create_onnx_graph_proto ( self , sym , params , in_shape , in_type , verbose = False ) : try : from onnx import ( checker , helper , NodeProto , ValueInfoProto , TensorProto ) from onnx . helper import make_tensor_value_info except ImportError : raise ImportError ( "Onnx and protobuf need to be installed. " + "Instructions to install - https://github.com/onnx/onnx" ) # When MXNet model is saved to json file , MXNet adds a node for label. # The name of this node is, name of the last node + "_label" ( i.e if last node # name is "Softmax", this node will have a name "Softmax_label". Also, the new node # will always be second last node in the json graph. # Deriving the output_label name. output_label = sym . get_internals ( ) [ len ( sym . get_internals ( ) ) - 1 ] . name + "_label" weights = MXNetGraph . convert_weights_to_numpy ( params ) mx_graph = json . loads ( sym . tojson ( ) ) [ "nodes" ] initializer = [ ] all_processed_nodes = [ ] onnx_processed_nodes = [ ] onnx_processed_inputs = [ ] onnx_processed_outputs = [ ] index_lookup = [ ] # Determine output shape graph_outputs = MXNetGraph . get_outputs ( sym , params , in_shape , output_label ) graph_input_idx = 0 for idx , node in enumerate ( mx_graph ) : op = node [ "op" ] name = node [ "name" ] if verbose : logging . info ( "Converting idx: %d, op: %s, name: %s" , idx , op , name ) # A node is an input node if its op_name is "null" and is not # in params dict if op == "null" and name not in params : # Handling graph input # Skipping output_label node, as this node is not part of graph # Refer "output_label" assignment above for more details. if name == output_label : continue converted = MXNetGraph . convert_layer ( node , is_input = True , mx_graph = mx_graph , weights = weights , in_shape = in_shape [ graph_input_idx ] , in_type = in_type , proc_nodes = all_processed_nodes , initializer = initializer , index_lookup = index_lookup ) graph_input_idx += 1 else : # Handling graph layers converted = MXNetGraph . convert_layer ( node , is_input = False , mx_graph = mx_graph , weights = weights , in_shape = in_shape , in_type = in_type , proc_nodes = all_processed_nodes , initializer = initializer , index_lookup = index_lookup , idx = idx ) if isinstance ( converted , list ) : # Iterate for all converted nodes for converted_node in converted : # If converted node is ValueInfoProto, add it in inputs if isinstance ( converted_node , ValueInfoProto ) : onnx_processed_inputs . append ( converted_node ) # If converted node is NodeProto, add it in processed nodes list elif isinstance ( converted_node , NodeProto ) : onnx_processed_nodes . append ( converted_node ) # some operators have multiple outputs, # therefore, check all output node names node_names = list ( converted_node . output ) for nodename in node_names : if nodename in graph_outputs : onnx_processed_outputs . append ( make_tensor_value_info ( name = nodename , elem_type = in_type , shape = graph_outputs [ nodename ] ) ) if verbose : logging . info ( "Output node is: %s" , nodename ) elif isinstance ( converted_node , TensorProto ) : raise ValueError ( "Did not expect TensorProto" ) else : raise ValueError ( "node is of an unrecognized type: %s" % type ( node ) ) all_processed_nodes . append ( converted_node ) if idx > 0 : # Handling extra node added to the graph if the MXNet model was # saved to json file, # refer "output_label" initialization above for more details. # if extra node was added then prev_index to the last node is adjusted. if idx == ( len ( mx_graph ) - 1 ) and mx_graph [ len ( mx_graph ) - 2 ] [ "name" ] == output_label : prev_index = index_lookup [ idx - 2 ] else : prev_index = index_lookup [ idx - 1 ] index_lookup . append ( prev_index + len ( converted ) ) else : index_lookup . append ( len ( converted ) - 1 ) else : logging . info ( "Operator converter function should always return a list" ) graph = helper . make_graph ( onnx_processed_nodes , "mxnet_converted_model" , onnx_processed_inputs , onnx_processed_outputs ) graph . initializer . extend ( initializer ) checker . check_graph ( graph ) return graph