def test_models(model_name, input_shape, output_shape):
    """ Tests Googlenet model for both onnx import and export"""
    model_path, inputs, outputs = get_test_files(model_name)
    logging.info("Translating model from ONNX model zoo to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)
    params = {}
    params.update(arg_params)
    params.update(aux_params)

    dir_path = os.path.dirname(model_path)
    new_model_name = "exported_" + model_name + ".onnx"
    onnx_file = os.path.join(dir_path, new_model_name)

    logging.info("Translating converted model from mxnet to ONNX")
    converted_model_path = onnx_mxnet.export_model(sym, params, [input_shape], np.float32, onnx_file)

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model_path)

    metadata = onnx_mxnet.get_model_metadata(converted_model_path)
    assert len(metadata) == 2
    assert metadata.get('input_tensor_data')
    assert metadata.get('input_tensor_data')[0][1] == input_shape
    assert metadata.get('output_tensor_data')
    assert metadata.get('output_tensor_data')[0][1] == output_shape
    data_names = [input_name[0] for input_name in metadata.get('input_tensor_data')]

    logging.info("Running inference on onnx re-import model in mxnet")
    # run test for each test file
    for input_data, output_data in zip(inputs, outputs):
        result = forward_pass(sym, arg_params, aux_params, data_names, input_data)

        # verify the results
        npt.assert_equal(result.shape, output_data.shape)
        npt.assert_almost_equal(output_data, result, decimal=3)
    logging.info(model_name + " conversion successful")
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.

    :param: model_dir The directory where model files are stored.
    :return: a model
    """
    onnx_path = os.path.join(model_dir, "model.onnx")
    ctx = mx.cpu() # todo: pass into function
    # load onnx model symbol and parameters
    sym, arg_params, aux_params = onnx_mxnet.import_model(onnx_path)
    model_metadata = onnx_mxnet.get_model_metadata(onnx_path)
    # first index is name, second index is shape
    input_names = [inputs[0] for inputs in model_metadata.get('input_tensor_data')]
    input_symbols = [mx.sym.var(i) for i in input_names]
    net = gluon.nn.SymbolBlock(outputs=sym, inputs=input_symbols)
    net_params = net.collect_params()
    # set parameters (on correct context)
    for param in arg_params:
        if param in net_params:
            net_params[param]._load_init(arg_params[param], ctx=ctx)
    for param in aux_params:
        if param in net_params:
            net_params[param]._load_init(aux_params[param], ctx=ctx)
    # hybridize for increase performance
    net.hybridize()
    return net
Example #3
0
def test_bvlc_rcnn_ilsvrc13():
    """Tests the bvlc rcnn model"""
    model_path, inputs, outputs = get_test_files('bvlc_reference_rcnn_ilsvrc13')
    logging.info("Translating rcnn_ilsvrc13 model from ONNX to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)
    metadata = onnx_mxnet.get_model_metadata(model_path)
    assert len(metadata) == 2
    assert metadata.get('input_tensor_data')
    assert metadata.get('input_tensor_data') == [(u'data_0', (1, 3, 224, 224))]
    assert metadata.get('output_tensor_data')
    assert metadata.get('output_tensor_data') == [(u'fc-rcnn_1', (1, 200))]
    data_names = [input_name[0] for input_name in metadata.get('input_tensor_data')]

    # run test for each test file
    for input_data, output_data in zip(inputs, outputs):
        # create module
        mod = mx.mod.Module(symbol=sym, data_names=data_names, context=mx.cpu(), label_names=None)
        mod.bind(for_training=False, data_shapes=[(data_names[0], input_data.shape)], label_shapes=None)
        mod.set_params(arg_params=arg_params, aux_params=aux_params,
                       allow_missing=True, allow_extra=True)
        # run inference
        batch = namedtuple('Batch', ['data'])
        mod.forward(batch([mx.nd.array(input_data)]), is_train=False)

        # verify the results
        npt.assert_equal(mod.get_outputs()[0].shape, output_data.shape)
        npt.assert_almost_equal(output_data, mod.get_outputs()[0].asnumpy(), decimal=3)
    logging.info("rcnn_ilsvrc13 model conversion Successful")
Example #4
0
def test_bvlc_rcnn_ilsvrc13():
    """Tests the bvlc rcnn model"""
    model_path, inputs, outputs = get_test_files('bvlc_reference_rcnn_ilsvrc13')
    logging.info("Translating rcnn_ilsvrc13 model from ONNX to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)
    metadata = onnx_mxnet.get_model_metadata(model_path)
    assert len(metadata) == 2
    assert metadata.get('input_tensor_data')
    assert metadata.get('input_tensor_data') == [(u'data_0', (1, 3, 224, 224))]
    assert metadata.get('output_tensor_data')
    assert metadata.get('output_tensor_data') == [(u'fc-rcnn_1', (1, 200))]
    data_names = [input_name[0] for input_name in metadata.get('input_tensor_data')]

    # run test for each test file
    for input_data, output_data in zip(inputs, outputs):
        # create module
        mod = mx.mod.Module(symbol=sym, data_names=data_names, context=mx.cpu(), label_names=None)
        mod.bind(for_training=False, data_shapes=[(data_names[0], input_data.shape)], label_shapes=None)
        mod.set_params(arg_params=arg_params, aux_params=aux_params,
                       allow_missing=True, allow_extra=True)
        # run inference
        batch = namedtuple('Batch', ['data'])
        mod.forward(batch([mx.nd.array(input_data)]), is_train=False)

        # verify the results
        npt.assert_equal(mod.get_outputs()[0].shape, output_data.shape)
        npt.assert_almost_equal(output_data, mod.get_outputs()[0].asnumpy(), decimal=3)
    logging.info("rcnn_ilsvrc13 model conversion Successful")
def test_square():
    input1 = np.random.randint(1, 10, (2, 3)).astype("float32")

    ipsym = mx.sym.Variable("input1")
    square = mx.sym.square(data=ipsym)
    model = mx.mod.Module(symbol=square,
                          data_names=['input1'],
                          label_names=None)
    model.bind(for_training=False,
               data_shapes=[('input1', np.shape(input1))],
               label_shapes=None)
    model.init_params()

    args, auxs = model.get_params()
    params = {}
    params.update(args)
    params.update(auxs)

    converted_model = onnx_mxnet.export_model(square, params,
                                              [np.shape(input1)], np.float32,
                                              "square.onnx")

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
    result = forward_pass(sym, arg_params, aux_params, ['input1'], input1)

    numpy_op = np.square(input1)

    npt.assert_almost_equal(result, numpy_op)
def test_softmax():
    input1 = np.random.rand(1000, 1000).astype("float32")
    label1 = np.random.rand(1000)
    input_nd = mx.nd.array(input1)
    label_nd = mx.nd.array(label1)

    ipsym = mx.sym.Variable("ipsym")
    label = mx.sym.Variable('label')
    sym = mx.sym.SoftmaxOutput(data=ipsym,
                               label=label,
                               ignore_label=0,
                               use_ignore=False)
    ex = sym.bind(ctx=mx.cpu(0), args={'ipsym': input_nd, 'label': label_nd})
    ex.forward(is_train=True)
    softmax_out = ex.outputs[0].asnumpy()

    converted_model = onnx_mxnet.export_model(sym, {}, [(1000, 1000),
                                                        (1000, )], np.float32,
                                              "softmaxop.onnx")

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
    result = forward_pass(sym, arg_params, aux_params, ['ipsym'], input1)

    # Comparing result of forward pass before using onnx export, import
    npt.assert_almost_equal(result, softmax_out)
Example #7
0
def get_model(ctx=-1, model_path='./bestmodel.onnx'):
    onnx_file = model_path
    sym, arg, aux = onnx_mxnet.import_model(onnx_file)

    # ### Get input data names
    data_names = [
        graph_input for graph_input in sym.list_inputs()
        if graph_input not in arg and graph_input not in aux
    ]
    Batch = namedtuple('Batch', ['data'])

    test_image = np.random.rand(1, 3, 224, 224).astype('float32')
    if ctx == -1:
        context = mx.cpu()
    else:
        context = mx.gpu(ctx)
    mod = mx.mod.Module(symbol=sym,
                        data_names=data_names,
                        context=context,
                        label_names=None)
    mod.bind(for_training=False,
             data_shapes=[(data_names[0], test_image.shape)],
             label_shapes=None)
    mod.set_params(arg_params=arg,
                   aux_params=aux,
                   allow_missing=True,
                   allow_extra=True)
    return mod
Example #8
0
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.

    :param: model_dir The directory where model files are stored.
    :return: a model
    """
    onnx_path = os.path.join(model_dir, "model.onnx")
    ctx = mx.cpu() # todo: pass into function
    # load onnx model symbol and parameters
    sym, arg_params, aux_params = onnx_mxnet.import_model(onnx_path)
    model_metadata = onnx_mxnet.get_model_metadata(onnx_path)
    # first index is name, second index is shape
    input_names = [inputs[0] for inputs in model_metadata.get('input_tensor_data')]
    input_symbols = [mx.sym.var(i) for i in input_names]
    net = gluon.nn.SymbolBlock(outputs=sym, inputs=input_symbols)
    net_params = net.collect_params()
    # set parameters (on correct context)
    for param in arg_params:
        if param in net_params:
            net_params[param]._load_init(arg_params[param], ctx=ctx)
    for param in aux_params:
        if param in net_params:
            net_params[param]._load_init(aux_params[param], ctx=ctx)
    # hybridize for increase performance
    net.hybridize()
    return net
def _check_onnx_export(net,
                       group_outputs=False,
                       shape_type=tuple,
                       extra_params={}):
    net.initialize()
    data = nd.random.uniform(0, 1, (1, 1024))
    output = _force_list(net(data))  # initialize weights
    net_sym = _optional_group(net(sym.Variable('data')), group_outputs)
    net_params = {
        name: param._reduce()
        for name, param in net.collect_params().items()
    }
    net_params.update(extra_params)
    with tempfile.TemporaryDirectory() as tmpdirname:
        onnx_file_path = os.path.join(tmpdirname, 'net.onnx')
        export_path = onnx_mxnet.export_model(
            sym=net_sym,
            params=net_params,
            input_shape=[shape_type(data.shape)],
            onnx_file_path=onnx_file_path)
        assert export_path == onnx_file_path
        # Try importing the model to symbol
        _assert_sym_equal(net_sym, onnx_mxnet.import_model(export_path)[0])

        # Try importing the model to gluon
        imported_net = onnx_mxnet.import_to_gluon(export_path, ctx=None)
        _assert_sym_equal(
            net_sym,
            _optional_group(imported_net(sym.Variable('data')), group_outputs))

        # Confirm network outputs are the same
        imported_net_output = _force_list(imported_net(data))
        for out, imp_out in zip(output, imported_net_output):
            mx.test_utils.assert_almost_equal(out.asnumpy(), imp_out.asnumpy())
def _check_onnx_export(net, group_outputs=False, shape_type=tuple, extra_params={}):
    net.initialize()
    data = nd.random.uniform(0, 1, (1, 1024))
    output = _force_list(net(data))  # initialize weights
    net_sym = _optional_group(net(sym.Variable('data')), group_outputs)
    net_params = {name:param._reduce() for name, param in net.collect_params().items()}
    net_params.update(extra_params)
    with tempfile.TemporaryDirectory() as tmpdirname:
        onnx_file_path = os.path.join(tmpdirname, 'net.onnx')
        export_path = onnx_mxnet.export_model(
            sym=net_sym,
            params=net_params,
            input_shape=[shape_type(data.shape)],
            onnx_file_path=onnx_file_path)
        assert export_path == onnx_file_path
        # Try importing the model to symbol
        _assert_sym_equal(net_sym, onnx_mxnet.import_model(export_path)[0])

        # Try importing the model to gluon
        imported_net = onnx_mxnet.import_to_gluon(export_path, ctx=None)
        _assert_sym_equal(net_sym, _optional_group(imported_net(sym.Variable('data')), group_outputs))

        # Confirm network outputs are the same
        imported_net_output = _force_list(imported_net(data))
        for out, imp_out in zip(output, imported_net_output):
            mx.test_utils.assert_almost_equal(out.asnumpy(), imp_out.asnumpy())
def model_fn(model_dir):
    sym, arg_params, aux_params = onnx_mxnet.import_model(
        os.path.join(model_dir, 'model.onnx'))
    mod = mx.mod.Module(symbol=sym, data_names=['data'], label_names=None)
    mod.bind(for_training=False, data_shapes=[('data', [100, 1, 28, 28])])
    mod.set_params(arg_params=arg_params, aux_params=aux_params)
    return mod
Example #12
0
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.
    :param: model_dir The directory where model files are stored.
    :return: a model
    """
    if len(mx.test_utils.list_gpus()) == 0:
        ctx = mx.cpu()
    else:
        ctx = mx.gpu(0)

    det_threshold = [0.6, 0.7, 0.8]
    detector = MtcnnDetector(
        model_folder=f"{model_dir}/mtcnn-model",
        ctx=mx.cpu(),
        num_worker=1,
        accurate_landmark=True,
        threshold=det_threshold,
    )
    image_size = (112, 112)
    sym, arg_params, aux_params = onnx_mxnet.import_model(f"{model_dir}/resnet100.onnx")
    # create module
    mod = mx.mod.Module(symbol=sym, context=ctx, label_names=None)
    mod.bind(
        for_training=False, data_shapes=[("data", (1, 3, image_size[0], image_size[1]))]
    )
    mod.set_params(arg_params=arg_params, aux_params=aux_params)

    return (detector, mod)
def test_model_accuracy(model_name, input_shape):
    """ Imports ONNX model, runs inference, exports and imports back
        run inference, compare result with the previous inference result"""
    model_path, inputs, outputs = get_test_files(model_name)
    logging.info("Translating model from ONNX model zoo to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)

    metadata = onnx_mxnet.get_model_metadata(model_path)
    data_names = [
        input_name[0] for input_name in metadata.get('input_tensor_data')
    ]

    expected_result = []
    for input_data, output_data in zip(inputs, outputs):
        result = forward_pass(sym, arg_params, aux_params, data_names,
                              input_data)
        expected_result.append(result)

    params = {}
    params.update(arg_params)
    params.update(aux_params)

    dir_path = os.path.dirname(model_path)
    new_model_name = "exported_" + model_name + ".onnx"
    onnx_file = os.path.join(dir_path, new_model_name)

    logging.info("Translating converted model from mxnet to ONNX")
    converted_model_path = onnx_mxnet.export_model(sym, params, [input_shape],
                                                   np.float32, onnx_file)

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model_path)

    metadata = onnx_mxnet.get_model_metadata(converted_model_path)
    data_names = [
        input_name[0] for input_name in metadata.get('input_tensor_data')
    ]

    actual_result = []
    for input_data, output_data in zip(inputs, outputs):
        result = forward_pass(sym, arg_params, aux_params, data_names,
                              input_data)
        actual_result.append(result)

    # verify the results
    for expected, actual in zip(expected_result, actual_result):
        npt.assert_equal(expected.shape, actual.shape)
        npt.assert_almost_equal(expected, actual, decimal=3)
Example #14
0
    def test_import_export(self):
        for test in test_cases:
            test_name, mxnet_op, onnx_name, inputs, attrs, mxnet_specific, fix_attrs, check_value, check_shape = test
            with self.subTest(test_name):
                names, input_tensors, inputsym = get_input_tensors(inputs)
                if inputs:
                    test_op = mxnet_op(*inputsym, **attrs)
                    mxnet_output = forward_pass(test_op, None, None, names, inputs)
                    outputshape = np.shape(mxnet_output)
                else:
                    test_op = mxnet_op(**attrs)
                    shape = attrs.get('shape', (1,))
                    x = mx.nd.zeros(shape, dtype='float32')
                    xgrad = mx.nd.zeros(shape, dtype='float32')
                    exe = test_op.bind(ctx=mx.cpu(), args={'x': x}, args_grad={'x': xgrad})
                    mxnet_output = exe.forward(is_train=False)[0].asnumpy()
                    outputshape = np.shape(mxnet_output)

                if mxnet_specific:
                    onnxmodelfile = onnx_mxnet.export_model(test_op, {}, [np.shape(ip) for ip in inputs],
                                                            np.float32,
                                                            onnx_name + ".onnx")
                    onnxmodel = load_model(onnxmodelfile)
                else:
                    onnx_attrs = _fix_attributes(attrs, fix_attrs)
                    onnxmodel = get_onnx_graph(test_name, names, input_tensors, onnx_name, outputshape, onnx_attrs)

                bkd_rep = backend.prepare(onnxmodel, operation='export')
                output = bkd_rep.run(inputs)

                if check_value:
                    npt.assert_almost_equal(output[0], mxnet_output)

                if check_shape:
                    npt.assert_equal(output[0].shape, outputshape)

        input1 = get_rnd((1, 10, 2, 3))
        ipsym = mx.sym.Variable("input1")
        for test in test_scalar_ops:
            if test == 'Add':
                outsym = 2 + ipsym
            if test == "Sub":
                outsym = ipsym - 2
            if test == "rSub":
                outsym = ipsym.__rsub__(2)
            if test == "Mul":
                outsym = 2 * ipsym
            if test == "Div":
                outsym = ipsym / 2
            if test == "Pow":
                outsym = ipsym ** 2
            forward_op = forward_pass(outsym, None, None, ['input1'], input1)
            converted_model = onnx_mxnet.export_model(outsym, {}, [np.shape(input1)], np.float32,
                                                      onnx_file_path=outsym.name + ".onnx")

            sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
        result = forward_pass(sym, arg_params, aux_params, ['input1'], input1)

        npt.assert_almost_equal(result, forward_op)
Example #15
0
    def test_import_export(self):
        for test in test_cases:
            test_name, mxnet_op, onnx_name, inputs, attrs, mxnet_specific, fix_attrs, check_value, check_shape = test
            with self.subTest(test_name):
                names, input_tensors, inputsym = get_input_tensors(inputs)
                if inputs:
                    test_op = mxnet_op(*inputsym, **attrs)
                    mxnet_output = forward_pass(test_op, None, None, names, inputs)
                    outputshape = np.shape(mxnet_output)
                else:
                    test_op = mxnet_op(**attrs)
                    shape = attrs.get('shape', (1,))
                    x = mx.nd.zeros(shape, dtype='float32')
                    xgrad = mx.nd.zeros(shape, dtype='float32')
                    exe = test_op.bind(ctx=mx.cpu(), args={'x': x}, args_grad={'x': xgrad})
                    mxnet_output = exe.forward(is_train=False)[0].asnumpy()
                    outputshape = np.shape(mxnet_output)

                if mxnet_specific:
                    onnxmodelfile = onnx_mxnet.export_model(test_op, {}, [np.shape(ip) for ip in inputs],
                                                            np.float32,
                                                            onnx_name + ".onnx")
                    onnxmodel = load_model(onnxmodelfile)
                else:
                    onnx_attrs = _fix_attributes(attrs, fix_attrs)
                    onnxmodel = get_onnx_graph(test_name, names, input_tensors, onnx_name, outputshape, onnx_attrs)

                bkd_rep = backend.prepare(onnxmodel, operation='export')
                output = bkd_rep.run(inputs)

                if check_value:
                    npt.assert_almost_equal(output[0], mxnet_output)

                if check_shape:
                    npt.assert_equal(output[0].shape, outputshape)

        input1 = get_rnd((1, 10, 2, 3))
        ipsym = mx.sym.Variable("input1")
        for test in test_scalar_ops:
            if test == 'Add':
                outsym = 2 + ipsym
            if test == "Sub":
                outsym = ipsym - 2
            if test == "rSub":
                outsym = ipsym.__rsub__(2)
            if test == "Mul":
                outsym = 2 * ipsym
            if test == "Div":
                outsym = ipsym / 2
            if test == "Pow":
                outsym = ipsym ** 2
            forward_op = forward_pass(outsym, None, None, ['input1'], input1)
            converted_model = onnx_mxnet.export_model(outsym, {}, [np.shape(input1)], np.float32,
                                                      onnx_file_path=outsym.name + ".onnx")

            sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
        result = forward_pass(sym, arg_params, aux_params, ['input1'], input1)

        npt.assert_almost_equal(result, forward_op)
def import_onnx():
    """Import the onnx model into mxnet"""
    model_url = 'https://s3.amazonaws.com/onnx-mxnet/examples/super_resolution.onnx'
    download(model_url, 'super_resolution.onnx')

    LOGGER.info("Converting onnx format to mxnet's symbol and params...")
    sym, arg_params, aux_params = onnx_mxnet.import_model('super_resolution.onnx')
    LOGGER.info("Successfully Converted onnx format to mxnet's symbol and params...")
    return sym, arg_params, aux_params
def import_onnx():
    """Import the onnx model into mxnet"""
    model_url = 'https://s3.amazonaws.com/onnx-mxnet/examples/super_resolution.onnx'
    download(model_url, 'super_resolution.onnx')

    LOGGER.info("Converting onnx format to mxnet's symbol and params...")
    sym, arg_params, aux_params = onnx_mxnet.import_model('super_resolution.onnx')
    LOGGER.info("Successfully Converted onnx format to mxnet's symbol and params...")
    return sym, arg_params, aux_params
Example #18
0
def get_model():
    ctx = mx.gpu(0)
    sym, arg_params, aux_params = onnx_mxnet.import_model('zface.onnx')
    all_layers = sym.get_internals()
    sym = all_layers['fc1_output']
    model = mx.mod.Module(sym, context=ctx, label_names=None)
    model.bind(data_shapes=[('data', (1, 3, 112, 112))])
    model.set_params(arg_params, aux_params)
    return model
Example #19
0
def onnx():
    # Import the ONNX model into MXNet's symbolic interface
    sym, arg, aux = onnx_mxnet.import_model("torch.onnx")
    print("Loaded torch_model.onnx!")
    print(sym.get_internals())
    sym.save("./model/torch.json")
    save_dict = {('arg:%s' % k): v.as_in_context(mx.cpu(0)) for k, v in arg.items()}
    save_dict.update({('aux:%s' % k): v.as_in_context(mx.cpu(0)) for k, v in aux.items()})
    mx.nd.save("./model/torch.params", save_dict)
Example #20
0
def test_nodims_import():
    # Download test model without dims mentioned in params
    test_model = download(test_model_path, dirname=CURR_PATH.__str__())
    input_data = np.array([0.2, 0.5])
    nd_data = mx.nd.array(input_data).expand_dims(0)
    sym, arg_params, aux_params = onnx_mxnet.import_model(test_model)
    model_metadata = onnx_mxnet.get_model_metadata(test_model)
    input_names = [inputs[0] for inputs in model_metadata.get('input_tensor_data')]
    output_data = forward_pass(sym, arg_params, aux_params, input_names, nd_data)
    assert(output_data.shape == (1,1))
Example #21
0
    def get_model_results(modelpath):
        symbol, args, aux = onnx_mxnet.import_model(modelpath)

        data = onnx_mxnet.get_model_metadata(modelpath)
        data_names = [input_name[0] for input_name in data.get('input_tensor_data')]

        result = []
        for input_data, output_data in zip(inputs, outputs):
            output = forward_pass(symbol, args, aux, data_names, input_data)
            result.append(output)
        return symbol, args, aux, result, data
def test_model_accuracy(model_name, input_shape):
    """ Imports ONNX model, runs inference, exports and imports back
        run inference, compare result with the previous inference result"""
    model_path, inputs, outputs = get_test_files(model_name)
    logging.info("Translating model from ONNX model zoo to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)

    metadata = onnx_mxnet.get_model_metadata(model_path)
    data_names = [input_name[0] for input_name in metadata.get('input_tensor_data')]

    expected_result= []
    for input_data, output_data in zip(inputs, outputs):
        result = forward_pass(sym, arg_params, aux_params, data_names, input_data)
        expected_result.append(result)

    params = {}
    params.update(arg_params)
    params.update(aux_params)

    dir_path = os.path.dirname(model_path)
    new_model_name = "exported_" + model_name + ".onnx"
    onnx_file = os.path.join(dir_path, new_model_name)

    logging.info("Translating converted model from mxnet to ONNX")
    converted_model_path = onnx_mxnet.export_model(sym, params, [input_shape], np.float32,
                                                   onnx_file)

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model_path)

    metadata = onnx_mxnet.get_model_metadata(converted_model_path)
    data_names = [input_name[0] for input_name in metadata.get('input_tensor_data')]

    actual_result = []
    for input_data, output_data in zip(inputs, outputs):
        result = forward_pass(sym, arg_params, aux_params, data_names, input_data)
        actual_result.append(result)

    # verify the results
    for expected, actual in zip(expected_result, actual_result):
        npt.assert_equal(expected.shape, actual.shape)
        npt.assert_almost_equal(expected, actual, decimal=3)
Example #23
0
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.
    :param: model_dir The directory where model files are stored.
    :return: a Module object
    """
    sym, arg_params, aux_params = onnx_mxnet.import_model('%s/resnet50v2.onnx' % model_dir) 
    # create module
    mod = mx.mod.Module(symbol=sym, data_names=['data'], label_names=None)
    mod.bind(for_training=False, data_shapes=[('data', [1, 3, 224, 224])], label_shapes=mod._label_shapes)
    mod.set_params(arg_params=arg_params, aux_params=aux_params, allow_missing=True, allow_extra=True)
    return mod
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.

    :param: model_dir The directory where model files are stored.
    :return: a model
    """
    sym, arg_params, aux_params = onnx_mxnet.import_model('%s/super_resolution.onnx' % model_dir) 
    # create module
    mod = mx.mod.Module(symbol=sym, data_names=['1'], label_names=None)
    mod.bind(for_training=False, data_shapes=[('1', [1, 1, 224, 224])])
    mod.set_params(arg_params=arg_params, aux_params=aux_params)
    return mod
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.

    :param: model_dir The directory where model files are stored.
    :return: a Module object
    """
    sym, arg_params, aux_params = onnx_mxnet.import_model('%s/resnet152v1.onnx' % model_dir) 
    # create module
    mod = mx.mod.Module(symbol=sym, data_names=['data'], label_names=None)
    mod.bind(for_training=False, data_shapes=[('data', [1, 3, 224, 224])], label_shapes=mod._label_shapes)
    mod.set_params(arg_params=arg_params, aux_params=aux_params, allow_missing=True, allow_extra=True)
    return mod
def model_fn(model_dir):
    """
    Load the onnx model. Called once when hosting service starts.

    :param: model_dir The directory where model files are stored.
    :return: a model
    """
    sym, arg_params, aux_params = onnx_mxnet.import_model(
        "%s/super_resolution.onnx" % model_dir)
    # create module
    mod = mx.mod.Module(symbol=sym, data_names=["1"], label_names=None)
    mod.bind(for_training=False, data_shapes=[("1", [1, 1, 224, 224])])
    mod.set_params(arg_params=arg_params, aux_params=aux_params)
    return mod
def test_fully_connected():
    def random_arrays(*shapes):
        """Generate some random numpy arrays."""
        arrays = [np.random.randn(*s).astype("float32") for s in shapes]
        if len(arrays) == 1:
            return arrays[0]
        return arrays

    data_names = ['x', 'w', 'b']

    dim_in, dim_out = (3, 4)
    input_data = random_arrays((4, dim_in), (dim_out, dim_in), (dim_out, ))

    ipsym = []
    data_shapes = []
    data_forward = []
    for idx in range(len(data_names)):
        val = input_data[idx]
        data_shapes.append((data_names[idx], np.shape(val)))
        data_forward.append(mx.nd.array(val))
        ipsym.append(mx.sym.Variable(data_names[idx]))

    op = mx.sym.FullyConnected(data=ipsym[0],
                               weight=ipsym[1],
                               bias=ipsym[2],
                               num_hidden=dim_out,
                               name='FC')

    model = mx.mod.Module(op, data_names=data_names, label_names=None)
    model.bind(for_training=False, data_shapes=data_shapes, label_shapes=None)

    model.init_params()

    args, auxs = model.get_params()
    params = {}
    params.update(args)
    params.update(auxs)

    converted_model = onnx_mxnet.export_model(
        op, params, [shape[1] for shape in data_shapes], np.float32, "fc.onnx")

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
    result = forward_pass(sym, arg_params, aux_params, data_names, input_data)

    numpy_op = np.dot(input_data[0], input_data[1].T) + input_data[2]

    npt.assert_almost_equal(result, numpy_op)
def get_model(ctx, model_path):
    # import ONNX model into MXNet symbols and params
    sym, arg, aux = import_model(model_path)
    # define network module
    mod = mx.mod.Module(symbol=sym,
                        data_names=['data'],
                        context=ctx,
                        label_names=None)
    # bind parameters to the network
    mod.bind(for_training=False,
             data_shapes=[('data', (1, 3, im.shape[0], im.shape[1]))],
             label_shapes=mod._label_shapes)
    mod.set_params(arg_params=arg,
                   aux_params=aux,
                   allow_missing=True,
                   allow_extra=True)
    return mod
Example #29
0
def convertToMxNetAndBack(fileName, outputFileName, inputs):
    from mxnet.gluon.model_zoo import vision
    import mxnet.contrib.onnx as onnx_mxnet
    import mxnet
    ret = None
    if "resnet" in fileName:
        model = vision.resnet50_v2(pretrained=True)
        model.hybridize()
        ret = [model(mxnet.nd.array(inputs[0][0]))]
        model.export("mxnet-model")
        sym = "./mxnet-model-symbol.json"
        arg = "./mxnet-model-0000.params"
    else:
        sym, arg, aux = onnx_mxnet.import_model(fileName)
    onnx_mxnet.export_model(sym, arg, getOnnxInputShapes(fileName), np.float32,
                            outputFileName)
    return ret
Example #30
0
def convert_onnx_model(model_path, onnx_file):
    """
    Util to convert onnx model to MXNet model
    :param model_path:
    :param onnx_file:
    :return:
    """
    from mxnet.contrib import onnx as onnx_mxnet
    import onnx
    model_name = os.path.splitext(os.path.basename(onnx_file))[0]
    symbol_file = '%s-symbol.json' % model_name
    params_file = '%s-0000.params' % model_name
    signature_file = 'signature.json'
    # Find input symbol name and shape
    model_proto = onnx.load(os.path.join(model_path, onnx_file))
    graph = model_proto.graph
    _params = set()
    for tensor_vals in graph.initializer:
        _params.add(tensor_vals.name)

    input_data = []
    for graph_input in graph.input:
        shape = []
        if graph_input.name not in _params:
            for val in graph_input.type.tensor_type.shape.dim:
                shape.append(val.dim_value)
            input_data.append((graph_input.name, tuple(shape)))

    sym, arg_params, aux_params = onnx_mxnet.import_model(os.path.join(model_path, onnx_file))
    # UNION of argument and auxillary parameters
    params = dict(arg_params, **aux_params)
    # rewrite input data_name correctly
    with open(os.path.join(model_path, signature_file), 'r') as f:
        data = json.loads(f.read())
        data['inputs'][0]['data_name'] = input_data[0][0]
    with open(os.path.join(model_path, signature_file), 'w') as f:
        f.write(json.dumps(data, indent=2))

    with open(os.path.join(model_path, symbol_file), 'w') as f:
        f.write(sym.tojson())

    save_dict = {('arg:%s' % k): v.as_in_context(mx.cpu()) for k, v in params.items()}
    mx.nd.save(os.path.join(model_path, params_file), save_dict)
    return symbol_file, params_file
Example #31
0
def mod_inference(matrix):
    random_input = np.random.rand(batch_size, channel, single_sentence_length,
                                  embedding_size)
    sym, arg_params, aux_params = onnx_mxnet.import_model('kim_model.onnx')
    mod = mx.mod.Module(symbol=sym,
                        data_names=['1'],
                        context=mx.cpu(),
                        label_names=None)
    mod.bind(for_training=False,
             data_shapes=[('1', random_input.shape)],
             label_shapes=None)
    mod.set_params(arg_params=arg_params,
                   aux_params=aux_params,
                   allow_missing=True)

    Batch = namedtuple('Batch', ['data'])
    mod.forward(Batch([mx.nd.array(matrix)]))
    output = mod.get_outputs()[0]
    return output
def test_softmax():
    input1 = np.random.rand(1000, 1000).astype("float32")
    label1 = np.random.rand(1000)
    input_nd = mx.nd.array(input1)
    label_nd = mx.nd.array(label1)

    ipsym = mx.sym.Variable("ipsym")
    label = mx.sym.Variable('label')
    sym = mx.sym.SoftmaxOutput(data=ipsym, label=label, ignore_label=0, use_ignore=False)
    ex = sym.bind(ctx=mx.cpu(0), args={'ipsym': input_nd, 'label': label_nd})
    ex.forward(is_train=True)
    softmax_out = ex.outputs[0].asnumpy()

    converted_model = onnx_mxnet.export_model(sym, {}, [(1000, 1000), (1000,)], np.float32, "softmaxop.onnx")

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
    result = forward_pass(sym, arg_params, aux_params, ['ipsym'], input1)

    # Comparing result of forward pass before using onnx export, import
    npt.assert_almost_equal(result, softmax_out)
def test_square():
    input1 = np.random.randint(1, 10, (2, 3)).astype("float32")

    ipsym = mx.sym.Variable("input1")
    square = mx.sym.square(data=ipsym)
    model = mx.mod.Module(symbol=square, data_names=['input1'], label_names=None)
    model.bind(for_training=False, data_shapes=[('input1', np.shape(input1))], label_shapes=None)
    model.init_params()

    args, auxs = model.get_params()
    params = {}
    params.update(args)
    params.update(auxs)

    converted_model = onnx_mxnet.export_model(square, params, [np.shape(input1)], np.float32, "square.onnx")

    sym, arg_params, aux_params = onnx_mxnet.import_model(converted_model)
    result = forward_pass(sym, arg_params, aux_params, ['input1'], input1)

    numpy_op = np.square(input1)

    npt.assert_almost_equal(result, numpy_op)
Example #34
0
def test_bvlc_rcnn_ilsvrc13():
    """Tests the bvlc rcnn model"""
    model_path, inputs, outputs = get_test_files('bvlc_reference_rcnn_ilsvrc13')
    logging.info("Translating rcnn_ilsvrc13 model from ONNX to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)

    # run test for each test file
    for input_data, output_data in zip(inputs, outputs):
        # create module
        data_names = [graph_input for graph_input in sym.list_inputs()
                      if graph_input not in arg_params and graph_input not in aux_params]
        mod = mx.mod.Module(symbol=sym, data_names=data_names, context=mx.cpu(), label_names=None)
        mod.bind(for_training=False, data_shapes=[(data_names[0], input_data.shape)], label_shapes=None)
        mod.set_params(arg_params=arg_params, aux_params=aux_params,
                       allow_missing=True, allow_extra=True)
        # run inference
        batch = namedtuple('Batch', ['data'])
        mod.forward(batch([mx.nd.array(input_data)]), is_train=False)

        # verify the results
        npt.assert_equal(mod.get_outputs()[0].shape, output_data.shape)
        npt.assert_almost_equal(output_data, mod.get_outputs()[0].asnumpy(), decimal=3)
    logging.info("rcnn_ilsvrc13 model conversion Successful")
Example #35
0
def test_bvlc_rcnn_ilsvrc13():
    """Tests the bvlc rcnn model"""
    model_path, inputs, outputs = get_test_files('bvlc_reference_rcnn_ilsvrc13')
    logging.info("Translating rcnn_ilsvrc13 model from ONNX to Mxnet")
    sym, arg_params, aux_params = onnx_mxnet.import_model(model_path)

    # run test for each test file
    for input_data, output_data in zip(inputs, outputs):
        # create module
        data_names = [graph_input for graph_input in sym.list_inputs()
                      if graph_input not in arg_params and graph_input not in aux_params]
        mod = mx.mod.Module(symbol=sym, data_names=data_names, context=mx.cpu(), label_names=None)
        mod.bind(for_training=False, data_shapes=[(data_names[0], input_data.shape)], label_shapes=None)
        mod.set_params(arg_params=arg_params, aux_params=aux_params,
                       allow_missing=True, allow_extra=True)
        # run inference
        batch = namedtuple('Batch', ['data'])
        mod.forward(batch([mx.nd.array(input_data)]), is_train=False)

        # verify the results
        npt.assert_equal(mod.get_outputs()[0].shape, output_data.shape)
        npt.assert_almost_equal(output_data, mod.get_outputs()[0].asnumpy(), decimal=3)
    logging.info("rcnn_ilsvrc13 model conversion Successful")
Example #36
0
    def test_convert_and_compare_prediction(self):
        # get data iterators and set basic hyperparams
        num_epochs = 10
        mnist = mx.test_utils.get_mnist()
        batch_size = 1000
        train_iter = mx.io.NDArrayIter(mnist['train_data'],
                                       mnist['train_label'],
                                       batch_size,
                                       shuffle=True)
        val_iter = mx.io.NDArrayIter(mnist['test_data'], mnist['test_label'],
                                     batch_size)
        test_iter = mx.io.NDArrayIter(mnist['test_data'], mnist['test_label'],
                                      batch_size)
        model_name = 'lenet5'
        model_file = '%s-symbol.json' % model_name
        params_file = '%s-%04d.params' % (model_name, num_epochs)
        onnx_file = "%s.onnx" % model_name
        test_gpu_id = 0
        gpu_id = check_gpu_id(test_gpu_id)
        if not gpu_id:
            print("\nWARNING: GPU id %d is invalid on this machine" %
                  test_gpu_id)
            gpu_id = None

        # If trained model exists, re-use cached version. Otherwise, train model.
        if not (os.path.exists(model_file) and os.path.exists(params_file)):
            print("\n\nTraining LeNet-5 on MNIST data")
            trained_lenet = train_lenet5(num_epochs, gpu_id, train_iter,
                                         val_iter, test_iter, batch_size)
            print("Training finished. Saving model")
            trained_lenet.save_checkpoint(model_name, num_epochs)
            # delete object so we can verify correct loading of the checkpoint from disk
            del trained_lenet
        else:
            print("\n\nTrained model exists. Skipping training.")

        # Load serialized MxNet model (model-symbol.json + model-epoch.params)

        trained_lenet = mx.mod.Module.load(model_name, num_epochs)
        trained_lenet.bind(data_shapes=test_iter.provide_data,
                           label_shapes=None,
                           for_training=False,
                           force_rebind=True)

        # Run inference in MxNet from json/params serialized model
        test_iter = mx.io.NDArrayIter(mnist['test_data'], mnist['test_label'],
                                      batch_size)
        pred_softmax = trained_lenet.predict(test_iter).asnumpy()
        pred_classes = np.argmax(pred_softmax, axis=1)

        # Create and save ONNX model
        print("\nConverting trained MxNet model to ONNX")
        model = from_mxnet(model_file,
                           params_file, [1, 1, 28, 28],
                           np.float32,
                           log=True)
        with open(onnx_file, "wb") as f:
            serialized = model.SerializeToString()
            f.write(serialized)
            print("\nONNX file %s serialized to disk" % onnx_file)

        print(
            "\nLoading ONNX file and comparing results to original MxNet output."
        )

        # ONNX load and inference step
        onnx_sym, onnx_arg_params, onnx_aux_params = import_model(onnx_file)
        onnx_mod = mx.mod.Module(symbol=onnx_sym,
                                 data_names=['data'],
                                 context=mx.cpu(),
                                 label_names=None)

        # Need to rename data argument from 'data' to 'input_0' because that's how
        # the MxNet ONNX importer expects it by default
        test_iter = mx.io.NDArrayIter(data={'data': mnist['test_data']},
                                      label=None,
                                      batch_size=batch_size)

        onnx_mod.bind(data_shapes=test_iter.provide_data,
                      label_shapes=None,
                      for_training=False,
                      force_rebind=True)
        onnx_mod.set_params(arg_params=onnx_arg_params,
                            aux_params=onnx_aux_params,
                            allow_missing=True)

        onnx_pred_softmax = onnx_mod.predict(test_iter).asnumpy()
        onnx_pred_classes = np.argmax(pred_softmax, axis=1)

        pred_matches = onnx_pred_classes == pred_classes
        pred_match_ct = pred_matches.sum()
        pred_total_ct = np.size(pred_matches)
        pct_match = 100.0 * pred_match_ct / pred_total_ct

        print(
            "\nOriginal MxNet predictions and ONNX-based predictions after export and re-import:"
        )
        print("Total examples tested: %d" % pred_total_ct)
        print("Matches: %d" % pred_match_ct)
        print("Percent match: %.2f\n" % pct_match)

        assert pred_match_ct == pred_total_ct, "Not all predictions from the ONNX representation match"
Example #37
0
import mxnet as mx
import numpy as np
import logging
import pprint
import mxnet.contrib.onnx as onnx_mxnet
from model import Model
from collections import namedtuple
import sys
import os
import random
import numpy as np

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

sym, arg_params, aux_params = onnx_mxnet.import_model('test.onnx')
word_to_ix = {"hello": 0, "world": 1}
lookup_tensor = np.array([word_to_ix["hello"]])
print(sym)
mx.viz.plot_network(sym,
                    shape={"input_0": lookup_tensor.shape},
                    node_attrs={
                        "shape": 'oval',
                        "fixedsize": 'false'
                    })
Example #38
0
# Convert an ONNX model to MXNet model

import mxnet as mx
from mxnet.contrib import onnx as onnx_mxnet
import numpy as np
import os

curr_dir = os.path.dirname(__file__)

# Import the ONNX model into MXNet's symbolic interface
sym, arg, aux = onnx_mxnet.import_model(curr_dir + "/vgg16.onnx")
print("Loaded vgg16.onnx!")
print(sym.get_internals())
    def convert_onnx_model(model_path, onnx_file, model_name):
        """
        Util to convert onnx model to MXNet model
        :param model_name:
        :param model_path:
        :param onnx_file:
        :return:
        """
        try:
            import mxnet as mx
            from mxnet.contrib import onnx as onnx_mxnet
        except ImportError:
            raise ModelArchiverError("MXNet package is not installed. Run command: pip install mxnet to install it.")

        try:
            import onnx
        except ImportError:
            raise ModelArchiverError("Onnx package is not installed. Run command: pip install onnx to install it.")

        symbol_file = '%s-symbol.json' % model_name
        params_file = '%s-0000.params' % model_name
        signature_file = 'signature.json'
        # Find input symbol name and shape
        try:
            model_proto = onnx.load(os.path.join(model_path, onnx_file))
        except:
            logging.error("Failed to load the %s model. Verify if the model file is valid", onnx_file)
            raise

        graph = model_proto.graph
        _params = set()
        for tensor_vals in graph.initializer:
            _params.add(tensor_vals.name)

        input_data = []
        for graph_input in graph.input:
            shape = []
            if graph_input.name not in _params:
                for val in graph_input.type.tensor_type.shape.dim:
                    shape.append(val.dim_value)
                input_data.append((graph_input.name, tuple(shape)))

        try:
            sym, arg_params, aux_params = onnx_mxnet.import_model(os.path.join(model_path, onnx_file))
            # UNION of argument and auxillary parameters
            params = dict(arg_params, **aux_params)
        except:
            logging.error("Failed to import %s file to onnx. Verify if the model file is valid", onnx_file)
            raise

        try:
            # rewrite input data_name correctly
            with open(os.path.join(model_path, signature_file), 'r') as f:
                data = json.loads(f.read())
                data['inputs'][0]['data_name'] = input_data[0][0]
                data['inputs'][0]['data_shape'] = [int(i) for i in input_data[0][1]]
            with open(os.path.join(model_path, signature_file), 'w') as f:
                f.write(json.dumps(data, indent=2))

            with open(os.path.join(model_path, symbol_file), 'w') as f:
                f.write(sym.tojson())
        except:
            logging.error("Failed to write the signature or symbol files for %s model", onnx_file)
            raise

        save_dict = {('arg:%s' % k): v.as_in_context(mx.cpu()) for k, v in params.items()}
        mx.nd.save(os.path.join(model_path, params_file), save_dict)
        return symbol_file, params_file
Example #40
0
def load_net_params_mxnet(net, params_path):
    # Import the ONNX model into MXNet's symbolic interface
    sym, arg_params, aux_params = onnx_mxnet.import_model(params_path)
    print("Loaded torch_model.onnx!")
    net_params = net.collect_params()
    ctx = mx.gpu(0)
    for param in aux_params:
        temp = param
        param = 'resnetv10_' + param.replace('.', '_').replace(
            'bias', 'beta').replace('bn', 'batchnorm')  # .replace()
        if 'batchnorm' in param:
            param = param.replace(
                'batchnorm' + param.split('batchnorm')[1][0],
                'batchnorm' + str(int(param.split('batchnorm')[1][0]) - 1))
        if 'layer' in param:
            param = param.replace('layer', 'stage')
            i, j = map(int, param.split('stage')[1].split('_')[:2])
            if i < 2 and j == 1: t = 2
            if i >= 2 and j == 1: t = 3
            if j == 1:
                if 'batchnorm' in param:
                    param = param.replace(
                        'batchnorm' + param.split('batchnorm')[1][0],
                        'batchnorm' +
                        str(int(param.split('batchnorm')[1][0]) + t))
            if 'downsample_1' in param:
                param = param.replace('downsample_1', 'batchnorm2')
            param = '_'.join(param.split('_%d_' % j))
        net_params[param]._load_init(aux_params[temp], ctx=ctx)
    for param in arg_params:
        temp = param
        param = 'resnetv10_' + param.replace('.', '_').replace(
            'bias', 'beta').replace('bn', 'batchnorm')  #.replace()
        if 'conv' in param:
            param = param.replace(
                'conv' + param.split('conv')[1][0],
                'conv' + str(int(param.split('conv')[1][0]) - 1))
        if 'batchnorm' in param:
            param = param.replace(
                'batchnorm' + param.split('batchnorm')[1][0],
                'batchnorm' + str(int(param.split('batchnorm')[1][0]) - 1))
            param = param.replace('weight', 'gamma')
        if 'layer' in param:
            param = param.replace('layer', 'stage')
            i, j = map(int, param.split('stage')[1].split('_')[:2])
            if i < 2 and j == 1: t = 2
            if i >= 2 and j == 1: t = 3
            if j == 1:
                if 'conv' in param:
                    param = param.replace(
                        'conv' + param.split('conv')[1][0],
                        'conv' + str(int(param.split('conv')[1][0]) + t))
                if 'batchnorm' in param:
                    param = param.replace(
                        'batchnorm' + param.split('batchnorm')[1][0],
                        'batchnorm' +
                        str(int(param.split('batchnorm')[1][0]) + t))
                    param = param.replace('weight', 'gamma')
            if 'downsample' in param:
                if 'downsample_0' in param:
                    param = param.replace('downsample_0', 'conv2')
                if 'downsample_1' in param:
                    if 'weight' in param:
                        param = param.replace('downsample_1_weight',
                                              'batchnorm2_gamma')
                    if 'beta' in param:
                        param = param.replace('downsample_1_beta',
                                              'batchnorm2_beta')
            param = '_'.join(param.split('_%d_' % j))
        if 'fc' in param:
            param = param.replace('fc_weight', 'dense0_weight').replace(
                'fc_beta', 'dense0_bias')
        net_params[param]._load_init(arg_params[temp], ctx=ctx)
    net.hybridize()
    return net
    'use_random_crop': False,
    'use_mirror': False,
    'ds_rate': 8,
    'convert_label': True,
    'multi_thread': False,
    'cell_width': 2,
    'random_bound': [120, 120],
}
val_dataloader = loader('val.lst', val_args)

# ### Load ONNX model

# In[5]:

# import ONNX model into MXNet symbols and params
sym, arg, aux = import_model(model_path)
# define network module
mod = mx.mod.Module(symbol=sym,
                    data_names=['data'],
                    context=ctx,
                    label_names=None)
# bind parameters to the network
mod.bind(for_training=False,
         data_shapes=[('data', (batch_size, 3, 800, 800))],
         label_shapes=mod._label_shapes)
mod.set_params(arg_params=arg,
               aux_params=aux,
               allow_missing=True,
               allow_extra=True)

# ### Compute evaluations