(builder, node, graph, err)
convert to CoreML BatchNorm Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L1633
convert to CoreML BatchNorm Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L1633
convert to CoreML BatchNorm Layer : https : // github . com / apple / coremltools / blob / 655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492 / mlmodel / format / NeuralNetwork . proto#L1633
def _convert_instancenorm(builder, node, graph, err):  # type: (NeuralNetworkBuilder, Node, Graph, ErrorHandling) -> None
    '''
    convert to CoreML BatchNorm Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L1633
    '''
    epsilon = node.attrs.get("epsilon", 1e-5)
    if node.inputs[1] not in node.input_tensors or node.inputs[2] not in node.input_tensors:
        return err.unsupported_op_configuration(builder, node, graph, "CoreML InstanceNorm requires Scale and Bias to be known")
    
    scale = node.input_tensors[node.inputs[1]]
    bias = node.input_tensors[node.inputs[2]]

    rank = builder._get_rank(node.inputs[0])
    # ONNX converts B x C tensor into B x C x 1 hence
    # Rank 2 BN is mapped to Rank 3 BN
    if rank == 3:
        # 1D Batch Norm
        add_bn_with_expansion(builder, node, err, node.name, node.inputs[0], node.outputs[0], scale.shape[0],
                              scale, bias, epsilon=epsilon, compute_mean_var=True,
                              instance_normalization=True, axes_for_expansion=[0, 3])
    elif rank == 4:
        # 2D Batch Norm
        add_bn_with_expansion(builder, node, err, node.name, node.inputs[0], node.outputs[0], scale.shape[0],
                              scale, bias, epsilon=epsilon, compute_mean_var=True,
                              instance_normalization=True, axes_for_expansion=[])
    else:
        # Unsupported 1D, 3D and above
        err.unsupported_op_configuration(builder, node, graph, "provided number axes {} not supported".format(rank))
def _convert_instancenorm ( builder , node , graph , err ) : # type: (NeuralNetworkBuilder, Node, Graph, ErrorHandling) -> None epsilon = node . attrs . get ( "epsilon" , 1e-5 ) if node . inputs [ 1 ] not in node . input_tensors or node . inputs [ 2 ] not in node . input_tensors : return err . unsupported_op_configuration ( builder , node , graph , "CoreML InstanceNorm requires Scale and Bias to be known" ) scale = node . input_tensors [ node . inputs [ 1 ] ] bias = node . input_tensors [ node . inputs [ 2 ] ] rank = builder . _get_rank ( node . inputs [ 0 ] ) # ONNX converts B x C tensor into B x C x 1 hence # Rank 2 BN is mapped to Rank 3 BN if rank == 3 : # 1D Batch Norm add_bn_with_expansion ( builder , node , err , node . name , node . inputs [ 0 ] , node . outputs [ 0 ] , scale . shape [ 0 ] , scale , bias , epsilon = epsilon , compute_mean_var = True , instance_normalization = True , axes_for_expansion = [ 0 , 3 ] ) elif rank == 4 : # 2D Batch Norm add_bn_with_expansion ( builder , node , err , node . name , node . inputs [ 0 ] , node . outputs [ 0 ] , scale . shape [ 0 ] , scale , bias , epsilon = epsilon , compute_mean_var = True , instance_normalization = True , axes_for_expansion = [ ] ) else : # Unsupported 1D, 3D and above err . unsupported_op_configuration ( builder , node , graph , "provided number axes {} not supported" . format ( rank ) )