(model: Union[str, onnx.ModelProto],
             check_n: int = 0,
             perform_optimization: bool = True,
             skip_fuse_bn: bool = False,
             input_shapes: Optional[TensorShapesWithOptionalKey] = None,
             skipped_optimizers: Optional[Sequence[str]] = None,
             skip_shape_inference=False,
             input_data: Optional[Tensors] = None,
             dynamic_input_shape: bool = False,
             custom_lib: Optional[str] = None)
return model, check_ok
:param model: onnx ModelProto object or file path
    :param check_n: The simplified model will be checked for `check_n` times by random inputs
    :param perform_optimization: Whether to run onnx optimizer on the model
    :param skip_fuse_bn: Skip fuse_bn_into_conv onnx optimizer
    :param input_shapes: If the model has dynamic input shape, user must pass a fixed input shape 
            for generating random inputs and checking equality. (Also see "dynamic_input_shape" param)
    :param skipped_optimizers: Skip some specific onnx optimizers
    :param skip_shape_inference: Skip shape inference (sometimes shape inference will crash)
    :param input_data: Feed custom input data for checking if needed
    :param dynamic_input_shape: Indicates whether the input shape should be dynamic. Note that
            input_shapes is also needed even if dynamic_input_shape is True,
            the value of input_shapes will be used when generating random inputs for checking equality.
            If 'dynamic_input_shape' is False, the input shape in simplified model will be overwritten
            by the value of 'input_shapes' param.
    :param custom_lib: onnxruntime custom ops's shared library
    :return: A tuple (simplified model, success(True) or failed(False))
:param model: onnx ModelProto object or file path
    :param check_n: The simplified model will be checked for `check_n` times by random inputs
    :param perform_optimization: Whether to run onnx optimizer on the model
    :param skip_fuse_bn: Skip fuse_bn_into_conv onnx optimizer
    :param input_shapes: If the model has dynamic input shape, user must pass a fixed input shape 
            for generating random inputs and checking equality. (Also see "dynamic_input_shape" param)
    :param skipped_optimizers: Skip some specific onnx optimizers
    :param skip_shape_inference: Skip shape inference (sometimes shape inference will crash)
    :param input_data: Feed custom input data for checking if needed
    :param dynamic_input_shape: Indicates whether the input shape should be dynamic. Note that
            input_shapes is also needed even if dynamic_input_shape is True,
            the value of input_shapes will be used when generating random inputs for checking equality.
            If 'dynamic_input_shape' is False, the input shape in simplified model will be overwritten
            by the value of 'input_shapes' param.
    :param custom_lib: onnxruntime custom ops's shared library
    :return: A tuple (simplified model, success(True) or failed(False))
: param model : onnx ModelProto object or file path : param check_n : The simplified model will be checked for check_n times by random inputs : param perform_optimization : Whether to run onnx optimizer on the model : param skip_fuse_bn : Skip fuse_bn_into_conv onnx optimizer : param input_shapes : If the model has dynamic input shape user must pass a fixed input shape for generating random inputs and checking equality . ( Also see dynamic_input_shape param ) : param skipped_optimizers : Skip some specific onnx optimizers : param skip_shape_inference : Skip shape inference ( sometimes shape inference will crash ) : param input_data : Feed custom input data for checking if needed : param dynamic_input_shape : Indicates whether the input shape should be dynamic . Note that input_shapes is also needed even if dynamic_input_shape is True the value of input_shapes will be used when generating random inputs for checking equality . If dynamic_input_shape is False the input shape in simplified model will be overwritten by the value of input_shapes param . : param custom_lib : onnxruntime custom ops s shared library : return : A tuple ( simplified model success ( True ) or failed ( False ))
def simplify(model: Union[str, onnx.ModelProto],
             check_n: int = 0,
             perform_optimization: bool = True,
             skip_fuse_bn: bool = False,
             input_shapes: Optional[TensorShapesWithOptionalKey] = None,
             skipped_optimizers: Optional[Sequence[str]] = None,
             skip_shape_inference=False,
             input_data: Optional[Tensors] = None,
             dynamic_input_shape: bool = False,
             custom_lib: Optional[str] = None) -> Tuple[onnx.ModelProto, bool]:
    """
    :param model: onnx ModelProto object or file path
    :param check_n: The simplified model will be checked for `check_n` times by random inputs
    :param perform_optimization: Whether to run onnx optimizer on the model
    :param skip_fuse_bn: Skip fuse_bn_into_conv onnx optimizer
    :param input_shapes: If the model has dynamic input shape, user must pass a fixed input shape 
            for generating random inputs and checking equality. (Also see "dynamic_input_shape" param)
    :param skipped_optimizers: Skip some specific onnx optimizers
    :param skip_shape_inference: Skip shape inference (sometimes shape inference will crash)
    :param input_data: Feed custom input data for checking if needed
    :param dynamic_input_shape: Indicates whether the input shape should be dynamic. Note that
            input_shapes is also needed even if dynamic_input_shape is True,
            the value of input_shapes will be used when generating random inputs for checking equality.
            If 'dynamic_input_shape' is False, the input shape in simplified model will be overwritten
            by the value of 'input_shapes' param.
    :param custom_lib: onnxruntime custom ops's shared library
    :return: A tuple (simplified model, success(True) or failed(False))
    """
    if input_shapes is None:
        input_shapes = {}
    if input_data is None:
        input_data = {}

    if type(model) == str:
        model = onnx.load(model)
    assert(isinstance(model, onnx.ModelProto))
    onnx.checker.check_model(model)
    model_ori = copy.deepcopy(model)

    input_names = get_input_names(model)
    for input_name, data in input_data.items():
        if input_name not in input_names:
            raise RuntimeError(
                'The model doesn\'t have input named "{}"'.format(input_name))

        shape = list(input_data[input_name].shape)

        # special case for single constant variables (with shape [])
        if len(shape) == 0:
            shape = [input_data[input_name].size]
        if input_name in input_shapes and shape != input_shapes[input_name]:
            raise RuntimeError('The shape of input_data[{}] is not the same with input_shape[{}]'.format(
                input_name, input_name))
        elif input_name not in input_shapes:
            input_shapes[input_name] = shape

    updated_input_shapes = check_and_update_input_shapes(model, input_shapes, dynamic_input_shape)

    def infer_shapes_and_optimize(model: onnx.ModelProto) -> onnx.ModelProto:
        def infer_shapes_if_applicable(model: onnx.ModelProto) -> onnx.ModelProto:
            if not skip_shape_inference:
                model = infer_shapes(model)
            return model

        def optimize_if_applicable(model: onnx.ModelProto) -> onnx.ModelProto:
            if perform_optimization:
                model = optimize(model, skip_fuse_bn, skipped_optimizers)
            return model

        return fixed_point(model, infer_shapes_if_applicable, optimize_if_applicable)

    def constant_folding(model: onnx.ModelProto) -> onnx.ModelProto:
        const_nodes = get_constant_nodes(
            model, dynamic_input_shape=dynamic_input_shape)
        res = forward_for_node_outputs(model,
                                       const_nodes,
                                       input_shapes=updated_input_shapes,
                                       input_data=input_data,
                                       custom_lib=custom_lib)
        const_nodes = clean_constant_nodes(const_nodes, res)
        model = eliminate_const_nodes(model, const_nodes, res)
        onnx.checker.check_model(model)
        return model

    model = fixed_point(model, infer_shapes_and_optimize, constant_folding)

    check_ok = check(model_ori, model, check_n,
                     input_shapes=updated_input_shapes, custom_lib=custom_lib)

    return model, check_ok
def simplify ( model : Union [ str , onnx . ModelProto ] , check_n : int = 0 , perform_optimization : bool = True , skip_fuse_bn : bool = False , input_shapes : Optional [ TensorShapesWithOptionalKey ] = None , skipped_optimizers : Optional [ Sequence [ str ] ] = None , skip_shape_inference = False , input_data : Optional [ Tensors ] = None , dynamic_input_shape : bool = False , custom_lib : Optional [ str ] = None ) -> Tuple [ onnx . ModelProto , bool ] : if input_shapes is None : input_shapes = { } if input_data is None : input_data = { } if type ( model ) == str : model = onnx . load ( model ) assert ( isinstance ( model , onnx . ModelProto ) ) onnx . checker . check_model ( model ) model_ori = copy . deepcopy ( model ) input_names = get_input_names ( model ) for input_name , data in input_data . items ( ) : if input_name not in input_names : raise RuntimeError ( 'The model doesn\'t have input named "{}"' . format ( input_name ) ) shape = list ( input_data [ input_name ] . shape ) # special case for single constant variables (with shape []) if len ( shape ) == 0 : shape = [ input_data [ input_name ] . size ] if input_name in input_shapes and shape != input_shapes [ input_name ] : raise RuntimeError ( 'The shape of input_data[{}] is not the same with input_shape[{}]' . format ( input_name , input_name ) ) elif input_name not in input_shapes : input_shapes [ input_name ] = shape updated_input_shapes = check_and_update_input_shapes ( model , input_shapes , dynamic_input_shape ) def infer_shapes_and_optimize ( model : onnx . ModelProto ) -> onnx . ModelProto : def infer_shapes_if_applicable ( model : onnx . ModelProto ) -> onnx . ModelProto : if not skip_shape_inference : model = infer_shapes ( model ) return model def optimize_if_applicable ( model : onnx . ModelProto ) -> onnx . ModelProto : if perform_optimization : model = optimize ( model , skip_fuse_bn , skipped_optimizers ) return model return fixed_point ( model , infer_shapes_if_applicable , optimize_if_applicable ) def constant_folding ( model : onnx . ModelProto ) -> onnx . ModelProto : const_nodes = get_constant_nodes ( model , dynamic_input_shape = dynamic_input_shape ) res = forward_for_node_outputs ( model , const_nodes , input_shapes = updated_input_shapes , input_data = input_data , custom_lib = custom_lib ) const_nodes = clean_constant_nodes ( const_nodes , res ) model = eliminate_const_nodes ( model , const_nodes , res ) onnx . checker . check_model ( model ) return model model = fixed_point ( model , infer_shapes_and_optimize , constant_folding ) check_ok = check ( model_ori , model , check_n , input_shapes = updated_input_shapes , custom_lib = custom_lib ) return model , check_ok