class_docstr: References
  ----------
  * https://github.com/onnx/onnx/blob/master/docs/Operators.md
class_docstr_tok: ["References","--","--","--","--","--","*","https",":","\/\/github.com\/onnx\/onnx\/blob\/master\/docs\/Operators.md"]
code: def parse_network(self, graph, scaling_object, input_bounds):
      self._reset_state()
      self._graph = graph
  
      # initializers contain constant data
      initializers = dict()
      for initializer in self._graph.initializer:
          initializers[initializer.name] = numpy_helper.to_array(
              initializer
          )
  
      self._initializers = initializers
  
      # Build graph
      nodes = dict()
      nodes_by_output = dict()
      inputs = set()
      outputs = set()
      self._node_map = dict()
  
      network = NetworkDefinition(
          scaling_object=scaling_object,
          scaled_input_bounds=input_bounds,
      )
  
      network_input = None
      for input in self._graph.input:
          nodes[input.name] = ("input", input.type, [])
          nodes_by_output[input.name] = input.name
          inputs.add(input.name)
          # onnx inputs are tensors. Flatten tensors to a vector.
          dim_value = None
          size = []
          for dim in input.type.tensor_type.shape.dim:
              if dim.dim_value > 0:
                  if dim_value is None:
                      dim_value = 1
                  size.append(dim.dim_value)
                  dim_value *= dim.dim_value
          if dim_value is None:
              raise ValueError(
                  f'All dimensions in graph "{graph.name}" input tensor have 0 value.'
              )
          assert network_input is None
          network_input = InputLayer(size)
          self._node_map[input.name] = network_input
          network.add_layer(network_input)
  
      if network_input is None:
          raise ValueError(
              f'No valid input layer found in graph "{graph.name}".'
          )
  
      self._nodes = nodes
      self._nodes_by_output = nodes_by_output
      self._inputs = inputs
      self._outputs = outputs
  
      # The node.output field contains the name of this node
      # output.
      # Here map output name to node name.
      for node in self._graph.node:
          for output in node.output:
              nodes_by_output[output] = node.name
  
      self._constants = dict()
      for node in self._graph.node:
          # add node not connected to anything
          self._nodes[node.name] = ("node", node, [])
  
          # Map inputs by their output name
          node_inputs = [
              nodes_by_output[input]
              for input in node.input
              if input not in initializers
          ]
  
          if node_inputs:
              # Now connect inputs to the current node
              for input in node_inputs:
                  self._nodes[input][2].append(node.name)
          elif node.op_type == "Constant":
              for output in node.output:
                  value = _parse_constant_value(node)
                  self._constants[output] = value
          else:
              raise ValueError(
                  f'Nodes must have inputs or have op_type "Constant". Node "{node.name}" has no inputs and op_type "{node.op_type}".'
              )
  
      # traverse graph
      self._node_stack = list(inputs)
  
      self._weights = dict()
      self._biases = dict()
      self._activations = dict()
  
      while self._node_stack:
          node_name = self._node_stack.pop()
          type_, node, next_nodes = self._nodes[node_name]
  
          # no need to process inputs or outputs
          if type_ == "node":
              new_layer, new_layer_inputs = self._visit_node(
                  node, next_nodes
              )
              if new_layer is not None:
                  network.add_layer(new_layer)
                  for layer_input in new_layer_inputs:
                      network.add_edge(layer_input, new_layer)
          else:
              for next in next_nodes:
                  self._node_stack.append(next)
  
      return network
  
file_path: OMLT/src/omlt/io/onnx_parser.py
imports: import math
  import numpy
  from onnx import numpy_helper
  from omlt.neuralnet.layer import ConvLayer2D, DenseLayer, IndexMapper, InputLayer, PoolingLayer2D
  from omlt.neuralnet.network_definition import NetworkDefinition
label_desc: Use image node_id 3 for calling the NetworkParser obj's underlying member method code with example usage: obj.parse_network(graph, scaling_object, input_bounds) and returns: network