Ejemplo n.º 1
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)
Ejemplo n.º 2
0
def save(model_dir, model):
    tmp_dir = tempfile.mkdtemp()

    symbol_file = os.path.join(tmp_dir, 'model-symbol.json')
    params_file = os.path.join(tmp_dir, 'model-0000.params')

    model.symbol.save(symbol_file)
    model.save_params(params_file)

    data_shapes = [[dim for dim in data_desc.shape] for data_desc in model.data_shapes]
    output_path = os.path.join(model_dir, 'model.onnx')

    onnx_mxnet.export_model(symbol_file, params_file, data_shapes, np.float32, output_path)

    shutil.rmtree(tmp_dir)
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 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")
Ejemplo n.º 5
0
 def test_exports(self):
     input_shape = (2,1,3,1)
     for test in export_test_cases:
         test_name, onnx_name, mx_op, attrs = test
         input_sym = mx.sym.var('data')
         outsym = mx_op(input_sym, **attrs)
         converted_model = onnx_mxnet.export_model(outsym, {}, [input_shape], np.float32,
                                                   onnx_file_path=outsym.name + ".onnx")
         model = load_model(converted_model)
         checker.check_model(model)
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_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)
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)
Ejemplo n.º 9
0
    def converter(self):
        self._parse_input()
        self._parase_modelfile()
        os.makedirs(self.output_dir, exist_ok=True)
        out_path = os.path.join(self.output_dir, 'model', self.model_name)
        converted_model_path = onnx_mxnet.export_model(self.symbol_json,
                                                       self.params_path,
                                                       self.input_shape,
                                                       self.data_type,
                                                       out_path)

        model_proto = onnx.load(converted_model_path)
        checker.check_graph(model_proto.graph)

        # fix mxnet bn bugs https://github.com/onnx/models/issues/156
        model = onnx.load(out_path)
        for node in model.graph.node:
            if (node.op_type == "BatchNormalization"):
                for attr in node.attribute:
                    if (attr.name == "spatial"):
                        attr.i = 1
        onnx.save(model, out_path)

        super().write_output_ormbfile(self.input_dir, self.output_dir)
Ejemplo n.º 10
0
def main():
    parser = argparse.ArgumentParser(
        description='convert arcface models to onnx')
    # general
    parser.add_argument('--prefix',
                        default='fcn_resnet101_voc',
                        help='prefix to load model.')
    parser.add_argument('--epoch',
                        default=0,
                        type=int,
                        help='epoch number to load model.')
    parser.add_argument('--input_shape',
                        nargs='+',
                        default=[1, 3, 640, 640],
                        type=int,
                        help='input shape.')
    args = parser.parse_args()
    converted_onnx_filename = args.prefix + '.onnx'
    net = model_zoo.get_model(args.prefix, pretrained=True)
    x = nd.zeros(args.input_shape)
    net.hybridize()
    net(x)
    net.export(args.prefix)
    sym, arg_params, aux_params = mx.model.load_checkpoint(
        args.prefix, args.epoch)
    model = get_sym_train(sym)
    # scale_dict = get_scales(model, args.input_shape)
    mx.model.save_checkpoint(args.prefix + '_transpose', args.epoch, model,
                             arg_params, aux_params)
    converted_onnx_filename = onnx_mxnet.export_model(
        args.prefix + '_transpose-symbol.json',
        f'{args.prefix}_transpose-{args.epoch:04d}.params', [args.input_shape],
        np.float32, converted_onnx_filename)

    model_proto = onnx.load(converted_onnx_filename)
    onnx.checker.check_model(model_proto)
Ejemplo n.º 11
0
def export(
        originpath="weights",
        newpath="exportweights",
        load_name="512_512_ADAM_PVGG16_512",
        load_period=1,
        target_size=(768, 768),
        box_sizes300=[21, 45, 101.25, 157.5, 213.75, 270, 326.25],
        box_ratios300=[[1, 2, 0.5]] +  # conv4_3
    [[1, 2, 0.5, 3, 1.0 / 3]] * 3 +  # conv7, conv8_2, conv9_2, conv10_2
    [[1, 2, 0.5]] * 2,  # conv11_2, conv12_2
        box_sizes512=[21, 51.2, 133.12, 215.04, 296.96, 378.88, 460.8, 542.72],
        box_ratios512=[[1, 2, 0.5]] +  # conv4_3
    [[1, 2, 0.5, 3, 1.0 / 3]] * 4 +  # conv7, conv8_2, conv9_2, conv10_2
    [[1, 2, 0.5]] * 2,  # conv11_2, conv12_2
        anchor_box_offset=(0.5, 0.5),
        anchor_box_clip=False,
        dtype=np.float32):

    _, test_dataset = testdataloader()

    weight_path = os.path.join(originpath, load_name)
    if not os.path.exists(weight_path):
        raise FileExistsError

    params = os.path.join(weight_path, f'{load_period}.params')

    temp = load_name.split("_")

    version = int(temp[-1])
    if version == 300:
        box_sizes = box_sizes300
        box_ratios = box_ratios300
    elif version == 512:
        box_sizes = box_sizes512
        box_ratios = box_ratios512

    net = SSD_VGG16_Except_Anchor(version=int(load_name.split("_")[-1]),
                                  input_size=target_size,
                                  box_sizes=box_sizes,
                                  box_ratios=box_ratios,
                                  num_classes=test_dataset.num_class)
    net.load_parameters(params, allow_missing=True, ignore_extra=True)
    '''
    vgg16을 AnchorNet에서 선언한 순간 내부의 auxiliary param으로 인식하기 때문에 반드시 initialization을 해줘야 하는데,
    (외부에서 선언해서 보내면 이럴 필요없고 net.export만 수정해주면 된다.
    defer init을 쓴 상태라서 실제 forward를 한번 해줘야 한다.(anchornet.forward(mx.nd.ones(shape=(1, 3) + target_size, ctx=ctx))) 
    현재는 밖에서 보내면, 순간 내부의 auxiliary param으로 인식하지는 않아서, forward를 할 필요는 없다.
    어쨌든 두 방법 모두 사용하지 않는 변수가 생기기 때문에,  net.export(내부 코드)의 assert name in aux_names 부분을 주석 처리 해야한다.
    단 위와 같이 저장 한 경우, json, param을 불러 올 때, 아래와 같이 
    allow_missing=True, ignore_extra=True 인자를 gluon.SymbolBlock.imports(내부코드)를 수정해야 한다.
    ret.collect_params().load 함수에 allow_missing=True, ignore_extra=True 를 주면 된다 
    net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx, allow_missing=True, ignore_extra=True)
    --> 인자로 주게 만들어 놓지... 

    < 상세 설명 >
    target_size에 맞는 anchor를 얻기 위해서는 아래의 AnchorNet에서 VGG16 네트워크를 또 한번 호출해야 한다.
    ->  이렇게 되면 새롭게 호출하는 VGG16가 새로 저장하는 json에 추가적으로 써지고, 파라미터도 저장이 되기 때문에 비효율적이다.(해결책? 아직은...)
        이에 따라 또다른 문제가 생기는데(정확히 말해서 net.export에 내가 말하고자 하는 기능이 고려가 안되있다.), 

        현재 net.export는 할당한 파라미터들을 forward 에서 다 사용하지 않으면, AssertionError를 발생시킨다.

        실제 연산에 사용되는 파라미터만 저장하려고 하기 떄문에 이러한 오류가 발생하는데, 그냥 다 저장하게 net.export의
        내부 코드 한줄을 수정하면 된다. 
        이렇게 저장한 json, param을 불러 올때는 아래와 같이 불러와야 하는데, allow_missing=True, ignore_extra=True 는 
        본인이 직접 추가한 것이다.(gluon.SymbolBlock.imports 에는 allow_missing, ignore_extra 인자가 고려 되어 있지 않다.)
        gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx, allow_missing=True, ignore_extra=True)
        아래와 같이 gluon.SymbolBlock.imports을 수정하면 된다. 

    def imports(symbol_file, input_names, param_file=None, ctx=None, allow_missing=True, ignore_extra=True):
        sym = symbol.load(symbol_file)
        if isinstance(input_names, str):
            input_names = [input_names]
        if param_file is None:
            # Get a valid type inference by using fp32
            inputs = [symbol.var(i, dtype=mx_real_t) for i in input_names]
        else:
            # Do not specify type, rely on saved params type instead
            inputs = [symbol.var(i) for i in input_names]
        ret = SymbolBlock(sym, inputs)
        if param_file is not None:
            # allow_missing=True, ignore_extra=True 추가 함.
            ret.collect_params().load(param_file, ctx=ctx, cast_dtype=True, dtype_source='saved', 
            allow_missing=allow_missing, ignore_extra=ignore_extra) 
        return ret

        따라서 안쓰는 파라미터를 저장하지 않으면 net.export 내부를 수정해야 한다.(아래 설명) 
    '''

    anchornet = AnchorNet(net=net,
                          version=version,
                          box_sizes300=box_sizes300,
                          box_ratios300=box_ratios300,
                          box_sizes512=box_sizes512,
                          box_ratios512=box_ratios512,
                          anchor_box_clip=anchor_box_clip,
                          anchor_box_offset=anchor_box_offset,
                          target_size=target_size)

    new_weight_path = os.path.join(newpath, load_name)
    if not os.path.exists(new_weight_path):
        os.makedirs(new_weight_path)

    newname = str(target_size[0]) + "_" + str(
        target_size[1]) + "_" + temp[2] + "_" + temp[3] + "_" + temp[4]
    sym_pre = os.path.join(new_weight_path, f'{newname}_pre-symbol.json')
    params_pre = os.path.join(new_weight_path,
                              f'{newname}_pre-{load_period:04d}.params')
    onnx_pre_file_path = os.path.join(new_weight_path, f"{newname}_pre.onnx")

    try:
        '''
        def export(self, path, epoch=0, remove_amp_cast=True):
        """Export HybridBlock to json format that can be loaded by
        `SymbolBlock.imports`, `mxnet.mod.Module` or the C++ interface.

        .. note:: When there are only one input, it will have name `data`. When there
                  Are more than one inputs, they will be named as `data0`, `data1`, etc.

        Parameters
        ----------
        path : str
            Path to save model. Two files `path-symbol.json` and `path-xxxx.params`
            will be created, where xxxx is the 4 digits epoch number.
        epoch : int
            Epoch number of saved model.
        """
        if not self._cached_graph:
            raise RuntimeError(
                "Please first call block.hybridize() and then run forward with "
                "this block at least once before calling export.")
        sym = self._cached_graph[1]
        sym.save('%s-symbol.json'%path, remove_amp_cast=remove_amp_cast)

        arg_names = set(sym.list_arguments())
        aux_names = set(sym.list_auxiliary_states())
        arg_dict = {}
        for name, param in self.collect_params().items():
            if name in arg_names:
                arg_dict['arg:%s'%name] = param._reduce()
            else:
                #assert name in aux_names #  여기 주석 처리 해야함 
                arg_dict['aux:%s'%name] = param._reduce()
        ndarray.save('%s-%04d.params'%(path, epoch), arg_dict)
        '''
        export_block_for_cplusplus(
            path=os.path.join(new_weight_path, f"{newname}_pre"),
            block=anchornet,
            data_shape=tuple(target_size) + tuple((3, )),
            epoch=load_period,
            preprocess=True,  # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨
            layout='HWC',
            remove_amp_cast=True)
    except Exception as E:
        logging.error(f"json, param model export 예외 발생 : {E}")
    else:
        logging.info("json, param model export 성공")

    try:
        onnx_mxnet.export_model(
            sym=sym_pre,
            params=params_pre,
            input_shape=[tuple((1, )) + tuple(target_size) + tuple((3, ))],
            input_type=dtype,
            onnx_file_path=onnx_pre_file_path,
            verbose=False)
    except Exception as E:
        logging.error(f"ONNX model export 예외 발생 : {E}")
    else:
        logging.info(f"ONNX model export 성공")

    try:
        check_onnx(onnx_pre_file_path)
        logging.info(f"{os.path.basename(onnx_pre_file_path)} saved completed")
    except Exception as E:
        logging.error(f"ONNX model check 예외 발생 : {E}")
    else:
        logging.info("ONNX model check completed")
Ejemplo n.º 12
0
import mxnet as mx
import numpy as np
import onnx
from mxnet import gluon
from mxnet.contrib import onnx as onnx_mxnet

net = gluon.nn.Dense(1, in_units=2)
net.collect_params().initialize()

# collect_params returns gluon.parameter.ParameterDict object
# that contains all updatable parameters of a gluon.Block.
# Keys have type str and values have type mxnet.gluon.parameter.Parameter.
# data returns content of parameter as an ndarray.
params = {k: v.data(ctx=mx.cpu()) for k, v in net.collect_params().items()}
sym = net(mx.sym.var('data'))
file_path = onnx_mxnet.export_model(sym,
                                    params,
                                    input_shape=[(1, 2)],
                                    input_type=np.float32,
                                    onnx_file_path='simple_onnx_export_1.onnx')

print('Model saved to ' + file_path)

model = onnx.load('simple_onnx_export_1.onnx')
print('Textual representation of graph of ONNX model')
print(model.graph)
Ejemplo n.º 13
0
parser = argparse.ArgumentParser(description='convert arcface models to onnx')
# general
parser.add_argument('--prefix',
                    default='./model',
                    help='prefix to load model.')
parser.add_argument('--epoch',
                    default=0,
                    type=int,
                    help='epoch number to load model.')
parser.add_argument('--input_shape',
                    nargs='+',
                    default=[1, 3, 112, 112],
                    type=int,
                    help='input shape.')
parser.add_argument('--output_onnx',
                    default='./arcface_r100.onnx',
                    help='path to write onnx model.')
args = parser.parse_args()

input_shape = args.input_shape
print('input-shape:', input_shape)

sym_file = f'{args.prefix}-symbol.json'
params_file = f'{args.prefix}-{args.epoch:04d}.params'

converted_model_path = onnx_mxnet.export_model(sym_file,
                                               params_file, [input_shape],
                                               np.float32,
                                               args.output_onnx,
                                               verbose=True)
Ejemplo n.º 14
0
import onnx
from mxnet.gluon.model_zoo import vision as models
from mxnet import nd

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

net = models.alexnet(pretrained=True)
converted_onnx_filename = 'alexnet.onnx'

# Export MXNet model to ONNX format via MXNet's export_model API
x = nd.zeros((1, 3, 224, 224))
net.hybridize()
net(x)
net.export('alexnet')
converted_onnx_filename = onnx_mxnet.export_model('alexnet-symbol.json',
                                                  'alexnet-0000.params',
                                                  [(1, 3, 224, 224)],
                                                  np.float32,
                                                  converted_onnx_filename)

model_proto = onnx.load(converted_onnx_filename)
onnx.checker.check_model(model_proto)
Ejemplo n.º 15
0
# Definition of the graph that adds two numbers
import mxnet as mx
import onnx
from mxnet.contrib import onnx as onnx_mxnet

a = mx.sym.var('a')
b = mx.sym.var('b')
net = a + b

file_path = onnx_mxnet.export_model(net,
                                    params={},
                                    input_shape=[(1, ), (1, )],
                                    onnx_file_path='simple_onnx_export.onnx')

print('Model saved to ' + file_path)

model = onnx.load('simple_onnx_export.onnx')

# Type denotation defines semantic type for input or output
# In ONNX documentation it is proposed to have the following standard denotations:
# TENSOR
# IMAGE
# AUDIO
# TEXT
model.graph.input[0].type.denotation = 'TENSOR'
model.graph.input[1].type.denotation = 'TENSOR'
model.graph.output[0].type.denotation = 'TENSOR'

print('Textual representation of graph of ONNX model')
print(model.graph)
onnx.save_model(model, "simple_onnx_export.onnx")
Ejemplo n.º 16
0
import json
import mxnet as mx
from mxnet.contrib import onnx as onnx_mxnet
import logging
logging.basicConfig(level=logging.INFO)

# Downloaded input symbol and params files
sym = './mobilefacenet-res4-8-16-4-dim512/model-symbol.json'
params = './mobilefacenet-res4-8-16-4-dim512/model-0000.params'
# sym = './resnet-18-symbol.json'
# params = './resnet-18-0000.params'

# Standard Imagenet input - 3 channels, 224*224
input_shape = (1, 3, 112, 112)

# Path of the output file
onnx_file = './res512.onnx'

# Invoke export model API. It returns path of the converted onnx model
converted_model_path = onnx_mxnet.export_model(sym, params, [input_shape],
                                               np.uint8, onnx_file)

from onnx import checker
import onnx

# Load onnx model
model_proto = onnx.load_model(converted_model_path)

# Check if converted ONNX protobuf is valid
checker.check_graph(model_proto.graph)
Ejemplo n.º 17
0
import mxnet as mx
import numpy as np
from mxnet.contrib import onnx

name = 'PGGAN trained on CelebA'
input_shape = (1, 512)

model = mx.symbol.load(name + '.json')
array = mx.nd.load(name + '.params')
# array["Input"] = mx.nd.array(np.zeros(input_shape))
# net = model.bind(mx.cpu(), array)
onnx.export_model(model, array, [input_shape], np.float32, name + 'onnx', True)
Ejemplo n.º 18
0
mlp_model = mx.mod.Module(symbol=mlp, context=mx.cpu())

data_shapes = [('data', X_train.shape)]
label_shapes = [('softmax_label', y_train.shape)]

# Bind and initialize parameters
mlp_model.bind(data_shapes=data_shapes, label_shapes=label_shapes)
mlp_model.init_params(mx.init.Xavier())

# Save the parameters and symbol to files
mlp_model.save_params(MXNET_PARAMS_PATH_DEFAULT)
mlp.save(MXNET_SYMBOL_PATH_DEFAULT)

# Export the ONNX specification of the model, using the parameters and symbol files
onnx_mxnet.export_model(sym=MXNET_SYMBOL_PATH_DEFAULT,
                        params=MXNET_PARAMS_PATH_DEFAULT,
                        input_shape=[(64, input_length)],
                        onnx_file_path=ONNX_FILE_PATH_DEFAULT)
############################################################################

############################################################################
# Load ONNX file and remove files
model = onnx.load_model(ONNX_FILE_PATH_DEFAULT)
if os.path.exists(MXNET_PARAMS_PATH_DEFAULT):
    os.remove(MXNET_PARAMS_PATH_DEFAULT)
if os.path.exists(MXNET_SYMBOL_PATH_DEFAULT):
    os.remove(MXNET_SYMBOL_PATH_DEFAULT)
if os.path.exists(ONNX_FILE_PATH_DEFAULT):
    os.remove(ONNX_FILE_PATH_DEFAULT)
############################################################################
# Run the model on the task (requires an API key).
run = openml.runs.run_model_on_task(model, task, avoid_duplicate_runs=False)
Ejemplo n.º 19
0
def onnx_export(path="weights",
                newpath="exportweights",
                load_name="608_608_SGD_PDark_53",
                load_period=1,
                target_size=(768, 768),
                anchors={"shallow": [(10, 13), (16, 30), (33, 23)],
                         "middle": [(30, 61), (62, 45), (59, 119)],
                         "deep": [(116, 90), (156, 198), (373, 326)]},
                dtype=np.float32):
    try:
        _, test_dataset = testdataloader()
    except Exception:
        logging.info("The dataset does not exist")
        exit(0)

    weight_path = os.path.join(path, load_name)
    if not os.path.exists(weight_path):
        raise FileExistsError

    params = os.path.join(weight_path, f'{load_period}.params')

    temp = load_name.split("_")
    version = int(temp[-1])
    net = YoloV3output(Darknetlayer=version,
                               anchors=anchors,
                               num_classes=test_dataset.num_class)
    net.load_parameters(params, allow_missing=True,
                        ignore_extra=True)

    anchoroffstnet = AnchorOffstNet(net=net, version=version, anchors=anchors, target_size=target_size)

    new_weight_path = os.path.join(newpath, load_name)
    if not os.path.exists(new_weight_path):
        os.makedirs(new_weight_path)

    newname = str(target_size[0]) + "_" + str(target_size[1]) + "_" + temp[2] + "_" + temp[3] + "_" + temp[4]
    sym_pre = os.path.join(new_weight_path, f'{newname}_pre-symbol.json')
    params_pre = os.path.join(new_weight_path, f'{newname}_pre-{load_period:04d}.params')
    onnx_pre_file_path = os.path.join(new_weight_path, f"{newname}_pre.onnx")

    export_block_for_cplusplus(path=os.path.join(new_weight_path, f"{newname}_pre"),
                               block=anchoroffstnet,
                               data_shape=tuple(target_size) + tuple((3,)),
                               epoch=load_period,
                               preprocess=True,  # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨
                               layout='HWC',
                               remove_amp_cast=True)

    try:
        export_block_for_cplusplus(path=os.path.join(new_weight_path, f"{newname}_pre"),
                                   block=anchoroffstnet,
                                   data_shape=tuple(target_size) + tuple((3,)),
                                   epoch=load_period,
                                   preprocess=True,  # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨
                                   layout='HWC',
                                   remove_amp_cast=True)
    except Exception as E:
        logging.error(f"json, param model export 예외 발생 : {E}")
    else:
        logging.info("json, param model export 성공")

    try:
        onnx_mxnet.export_model(sym=sym_pre, params=params_pre,
                                input_shape=[tuple((1,)) + tuple(target_size) + tuple((3,))],
                                input_type=dtype,
                                onnx_file_path=onnx_pre_file_path, verbose=False)
    except Exception as E:
        logging.error(f"ONNX model export 예외 발생 : {E}")
    else:
        logging.info(f"ONNX model export 성공")

    try:
        check_onnx(onnx_pre_file_path)
        logging.info(f"{os.path.basename(onnx_pre_file_path)} saved completed")
    except Exception as E:
        logging.error(f"ONNX model check 예외 발생 : {E}")
    else:
        logging.info("ONNX model check completed")
Ejemplo n.º 20
0
def convert_sym_params_to_onnx(model_name, input_shape, path_sym_params, path_onnx='./'):
    model_path = path_onnx + model_name + '.onnx'
    sym = path_sym_params + model_name + '-symbol.json'
    params = path_sym_params + model_name + '-0000.params'
    onnx_mxnet.export_model(sym, params, [input_shape], np.float32, model_path, verbose=True)
Ejemplo n.º 21
0
# Convert a MXNet model to ONNX format

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

curr_dir = os.path.dirname(os.path.abspath(__file__))

path = 'http://data.mxnet.io/models/imagenet/'

# Download vgg16 pretrained model files
mx.test_utils.download(path + 'vgg/vgg16-0000.params',
                       curr_dir + '/vgg16-0000.params')
mx.test_utils.download(path + 'vgg/vgg16-symbol.json',
                       curr_dir + '/vgg16-symbol.json')

# Export the model to a .onnx file
out = onnx_mxnet.export_model(curr_dir + '/vgg16-symbol.json',
                              curr_dir + '/vgg16-0000.params',
                              [(1, 3, 224, 224)], np.float32,
                              curr_dir + '/vgg16.onnx')

# Check that the newly created model is valid and meets ONNX specification.
import onnx

model_proto = onnx.load(out)
onnx.checker.check_model(model_proto)
Ejemplo n.º 22
0
parser.add_argument('--symbol')
parser.add_argument('--params')
parser.add_argument('--input_shape')
parser.add_argument('--input_name')
parser.add_argument('--output_name')

args = parser.parse_args()

symbol_path = args.symbol
params_path = args.params
input_shape = list(map(int, args.input_shape.split(",")))


onnx_path = '__model.onnx'

converted_model_path = onnx_mxnet.export_model(symbol_path, params_path, [input_shape], np.float32, onnx_path)

tf_path = '__model.pb'

onnx_model = onnx.load(onnx_path)
# Maybe you have to do this workaround https://github.com/onnx/onnx-tensorflow/issues/377#issuecomment-464714597
tf_rep = onnx_tf.backend.prepare(onnx_model)
tf_rep.export_graph(tf_path)

converter = tf.lite.TFLiteConverter.from_frozen_graph(
    tf_path,
    [args.input_name],
    [args.output_name] 
)
tflite_model = converter.convert()
Ejemplo n.º 23
0
for k in aux_params:
    v = aux_params[k]
    nv = v.asnumpy().astype(np.float32)

    ac += nv.size
    invalid += np.count_nonzero(np.abs(nv) < eps)
    nv[np.abs(nv) < eps] = 0.0
    aux[k] = mx.nd.array(nv, dtype='float32')
aux_params = aux

all_args = {}
all_args.update(arg_params)
all_args.update(aux_params)
converted_model_path = onnx_mxnet.export_model(sym,
                                               all_args, [input_shape],
                                               np.float32,
                                               args.output,
                                               opset_version=11)

model = onnx.load(args.output)
graph = model.graph
input_map = create_map(graph.input)
node_map = create_map(graph.node)
init_map = create_map(graph.initializer)

#fix PRelu issue
for input_name in input_map.keys():
    if input_name.endswith('_gamma'):
        node_name = input_name[:-6]
        if not node_name in node_map:
            continue
Ejemplo n.º 24
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)
Ejemplo n.º 25
0
input_shape = args.input_shape
print('input-shape:', input_shape)

# BN bug fix?
sym, arg_params, aux_params = mx.model.load_checkpoint(args.prefix, args.epoch)
all_layers = sym.get_internals()
for layer in all_layers:
    if 'gamma' in layer.name and layer.attr('fix_gamma') == 'True':
        arg_params[layer.name] = mx.nd.array(np.ones(arg_params[layer.name].shape))
mx.model.save_checkpoint(args.prefix + "r", args.epoch, sym, arg_params, aux_params)

sym_file = f'{args.prefix + "r"}-symbol.json'
params_file = f'{args.prefix + "r"}-{args.epoch :04d}.params'
onnx_r = args.output_onnx.split('.onnx')[0]+'-tmp.onnx'
converted_model_path = onnx_mxnet.export_model(sym_file, params_file, [input_shape], np.float32, onnx_r)

# Check the model
onnx.checker.check_model(onnx_r)
print('The onnx_r is checked!')

def createGraphMemberMap(graph_member_list):
    member_map = dict()
    for n in graph_member_list:
        member_map[n.name] = n
    return member_map

model = onnx.load_model(onnx_r)
graph = model.graph
input_map = createGraphMemberMap(model.graph.input)
Ejemplo n.º 26
0
import mxnet as mx
import numpy as np
import argparse
import onnx
import os

print('mxnet version:', mx.__version__)
print('onnx version:', onnx.__version__)

if __name__ == '__main__':
    # First, the symbol and the param files.
    sym = "/home/ali/Projlab/Nist/Models/mxnet/model-y1-test2/model-symbol.json"
    params = "/home/ali/Projlab/Nist/Models/mxnet/model-y1-test2/model-0000.params"

    # Then, the standard Imagenet input - 3 channels, 122*122
    input_shape = (1, 3, 112, 112)
    print('input-shape:', input_shape)

    # Finally, the path of the ouput file.
    onnx_file = './mxnet_mobfacenet.onnx'

    # We are now ready to call the export function and actually convert the model.
    converted_model = onnx_mxnet.export_model(sym, params, [input_shape],
                                              np.float32, onnx_file)

    # load onnx model
    model_proto = onnx.load_model(converted_model)

    # check is converted onnx protobuf is valid
    checker.check_graph(model_proto.graph)
    # if you don't get any error message, it means that everything was executed correctly.
Ejemplo n.º 27
0
def get_onnx_model(model):
    if isinstance(model, keras.models.Model):
        # Create a session to avoid problems with names
        session = tf.Session()
        backend.set_session(session)

        with session.as_default():
            with session.graph.as_default():
                # If the model is sequential, it must be executed once and converted
                # to a function one prior to exporting the ONNX model
                if isinstance(model, keras.models.Sequential):
                    model.compile('Adam')

                    # Generate a random input just to execute the model once
                    dummy_input = numpy.random.rand(2, 2)
                    model.predict(dummy_input)

                    # Find the input and output layers to construct the functional model
                    input_layer = layers.Input(batch_shape=model.layers[0].input_shape)
                    prev_layer = input_layer
                    for layer in model.layers:
                        prev_layer = layer(prev_layer)

                    # Create a functional model equivalent to the sequential model
                    model = models.Model([input_layer], [prev_layer])

                # Export the functional keras model
                onnx_model = onnxmltools.convert_keras(model, target_opset=7)
    elif isinstance(model, torch.nn.Module):
        input_shape_found = False

        # Try to find the input shape and export the model
        for i in range(1, 5000):
            try:
                dummy_input = torch.randn(i, i, dtype=torch.float)
                torch.onnx.export(model, dummy_input, ONNX_MODEL_PATH)
                input_shape_found = True
            except RuntimeError:
                pass

            # There was no error, so the input shape has been correctly guessed
            # and the ONNX model was exported so we can stop iterating
            if input_shape_found:
                break

        # If the input shape could not be guessed, return None
        # and an error message will be displayed to the user
        if not input_shape_found:
            return None

        # Load the exported ONNX model file and remove the left-over file
        onnx_model = onnx.load_model(ONNX_MODEL_PATH)
        os.remove(ONNX_MODEL_PATH)
    elif isinstance(model, mx.gluon.nn.HybridBlock):
        # Initialize the MXNet model and create some dummy input
        model.collect_params().initialize(mx.init.Normal())
        dummy_input = numpy.random.rand(2, 2)

        # Propagate the input forward so the model can be fully initialized
        with mx.autograd.record():
            model(mx.nd.array(dummy_input))

        # Once initialized, export the ONNX equivalent of the model
        onnx_mxnet.export_model(
            sym=model(sym.var('data')),
            params={k: v._reduce() for k, v in model.collect_params().items()},
            input_shape=[(64, 2)],
            onnx_file_path=ONNX_MODEL_PATH)

        # Load the exported ONNX model file and remove the left-over file
        onnx_model = onnx.load_model(ONNX_MODEL_PATH)
        os.remove(ONNX_MODEL_PATH)
    elif isinstance(model, onnx.ModelProto):
        # The model is already an ONNX one
        onnx_model = model
    else:
        # The model was not produced by Keras, PyTorch, MXNet or ONNX and cannot be visualized
        # This point should not be reachable, as retrieval of the flow reinitializes the model
        # and that ensures if can be handled by MXNetExtension, OnnxExtension, PytorchExtension
        # or KerasExtension and therefore the model was produced by one of the libraries.
        return None

    return onnx_model
Ejemplo n.º 28
0
        try:
            # reads symbol.json file from given path and
            # retrieves model prefix and number of epochs
            model_name = sym_filepath.rsplit('.', 1)[0].rsplit('-', 1)[0]
            params_file_list = params_filepath.rsplit('.', 1)[0].rsplit('-', 1)
            # Setting num_epochs to 0 if not present in filename
            num_epochs = 0 if len(params_file_list) == 1 else int(
                params_file_list[1])
        except IndexError:
            logging.info("Model and params name should be in format: "
                         "prefix-symbol.json, prefix-epoch.params")
            raise

        sym, arg_params, aux_params = mx.model.load_checkpoint(
            model_name, num_epochs)

        # Merging arg and aux parameters
        params = {}
        params.update(arg_params)
        params.update(aux_params)

        return sym, params


sym = './model-symbol.json'
params = './model-0000.params'

sym, params = load_module(sym, params)
input_shape = [(1, 3, 112, 112)]
export_model(sym, params, input_shape)
    def train(self, batch_size=64,
              num_epoch=10,
              eval_metric='acc',
              eval_metric_params={},
              eval_train=False,
              loss ='softmax_cross_entropy',
              loss_params={},
              optimizer='adam',
              optimizer_params=(('learning_rate', 0.001),),
              load_checkpoint=True,
              checkpoint_period=5,
              load_pretrained=False,
              log_period=50,
              context='gpu',
              save_attention_image=False,
              use_teacher_forcing=False,
              normalize=True,
              shuffle_data=False,
              clip_global_grad_norm=None,
              preprocessing=False,
              onnx_export=False):
        num_pus = 1
        if context == 'gpu':
            num_pus = mx.context.num_gpus()
            if num_pus >= 1:
                if num_pus == 1:
                    mx_context = [mx.gpu(0)]
                else:
                    mx_context = [mx.gpu(i) for i in range(num_pus)]
            else:
                logging.error("Context argument is '" + context + "'. But no gpu is present in the system.")
        elif context == 'cpu':
            mx_context = [mx.cpu()]
        else:
            logging.error("Context argument is '" + context + "'. Only 'cpu' and 'gpu are valid arguments'.")
        single_pu_batch_size = int(batch_size/num_pus)

        if preprocessing:
            preproc_lib = "CNNPreprocessor_ResNeXt50_executor"
            train_iter, test_iter, data_mean, data_std, train_images, test_images = self._data_loader.load_preprocessed_data(batch_size, preproc_lib, shuffle_data)
        else:
            train_iter, test_iter, data_mean, data_std, train_images, test_images = self._data_loader.load_data(batch_size, shuffle_data)

        if 'weight_decay' in optimizer_params:
            optimizer_params['wd'] = optimizer_params['weight_decay']
            del optimizer_params['weight_decay']
        if 'learning_rate_decay' in optimizer_params:
            min_learning_rate = 1e-08
            if 'learning_rate_minimum' in optimizer_params:
                min_learning_rate = optimizer_params['learning_rate_minimum']
                del optimizer_params['learning_rate_minimum']
            optimizer_params['lr_scheduler'] = mx.lr_scheduler.FactorScheduler(
                                                   optimizer_params['step_size'],
                                                   factor=optimizer_params['learning_rate_decay'],
                                                   stop_factor_lr=min_learning_rate)
            del optimizer_params['step_size']
            del optimizer_params['learning_rate_decay']

        if normalize:
            self._net_creator.construct(context=mx_context, batch_size=batch_size, data_mean=data_mean, data_std=data_std)
        else:
            self._net_creator.construct(context=mx_context, batch_size=batch_size)

        begin_epoch = 0
        if load_checkpoint:
            begin_epoch = self._net_creator.load(mx_context)
        elif load_pretrained:
            self._net_creator.load_pretrained_weights(mx_context)
        else:
            if os.path.isdir(self._net_creator._model_dir_):
                shutil.rmtree(self._net_creator._model_dir_)

        self._networks = self._net_creator.networks

        try:
            os.makedirs(self._net_creator._model_dir_)
        except OSError:
            if not os.path.isdir(self._net_creator._model_dir_):
                raise

        if optimizer == "adamw":
            trainers = [mx.gluon.Trainer(network.collect_params(), AdamW.AdamW(**optimizer_params)) for network in self._networks.values() if len(network.collect_params().values()) != 0]
        else:
            trainers = [mx.gluon.Trainer(network.collect_params(), optimizer, optimizer_params) for network in self._networks.values() if len(network.collect_params().values()) != 0]

        margin = loss_params['margin'] if 'margin' in loss_params else 1.0
        sparseLabel = loss_params['sparse_label'] if 'sparse_label' in loss_params else True
        ignore_indices = [loss_params['ignore_indices']] if 'ignore_indices' in loss_params else []
        loss_axis = loss_params['loss_axis'] if 'loss_axis' in loss_params else -1
        batch_axis = loss_params['batch_axis'] if 'batch_axis' in loss_params else 0
        if loss == 'softmax_cross_entropy':
            fromLogits = loss_params['from_logits'] if 'from_logits' in loss_params else False
            loss_function = mx.gluon.loss.SoftmaxCrossEntropyLoss(axis=loss_axis, from_logits=fromLogits, sparse_label=sparseLabel, batch_axis=batch_axis)
        elif loss == 'softmax_cross_entropy_ignore_indices':
            fromLogits = loss_params['from_logits'] if 'from_logits' in loss_params else False
            loss_function = SoftmaxCrossEntropyLossIgnoreIndices(axis=loss_axis, ignore_indices=ignore_indices, from_logits=fromLogits, sparse_label=sparseLabel, batch_axis=batch_axis)
        elif loss == 'sigmoid_binary_cross_entropy':
            loss_function = mx.gluon.loss.SigmoidBinaryCrossEntropyLoss()
        elif loss == 'cross_entropy':
            loss_function = CrossEntropyLoss(axis=loss_axis, sparse_label=sparseLabel, batch_axis=batch_axis)
        elif loss == 'dice_loss':
            loss_weight = loss_params['loss_weight'] if 'loss_weight' in loss_params else None
            loss_function = DiceLoss(axis=loss_axis, weight=loss_weight, sparse_label=sparseLabel, batch_axis=batch_axis)
        elif loss == 'softmax_cross_entropy_ignore_label':
            loss_weight = loss_params['loss_weight'] if 'loss_weight' in loss_params else None
            loss_ignore_label = loss_params['loss_ignore_label'] if 'loss_ignore_label' in loss_params else None
            loss_function = SoftmaxCrossEntropyLossIgnoreLabel(axis=loss_axis, ignore_label=loss_ignore_label, weight=loss_weight, batch_axis=batch_axis)
        elif loss == 'l2':
            loss_function = mx.gluon.loss.L2Loss()
        elif loss == 'l1':
            loss_function = mx.gluon.loss.L1Loss()
        elif loss == 'huber':
            rho = loss_params['rho'] if 'rho' in loss_params else 1
            loss_function = mx.gluon.loss.HuberLoss(rho=rho)
        elif loss == 'hinge':
            loss_function = mx.gluon.loss.HingeLoss(margin=margin)
        elif loss == 'squared_hinge':
            loss_function = mx.gluon.loss.SquaredHingeLoss(margin=margin)
        elif loss == 'logistic':
            labelFormat = loss_params['label_format'] if 'label_format' in loss_params else 'signed'
            loss_function = mx.gluon.loss.LogisticLoss(label_format=labelFormat)
        elif loss == 'kullback_leibler':
            fromLogits = loss_params['from_logits'] if 'from_logits' in loss_params else True
            loss_function = mx.gluon.loss.KLDivLoss(from_logits=fromLogits)
        elif loss == 'log_cosh':
            loss_function = LogCoshLoss()
        else:
            logging.error("Invalid loss parameter.")

        loss_function.hybridize()


        tic = None

        avg_speed = 0
        n = 0
    
        for epoch in range(begin_epoch, begin_epoch + num_epoch):
            if shuffle_data:
                if preprocessing:
                    preproc_lib = "CNNPreprocessor_ResNeXt50_executor"
                    train_iter, test_iter, data_mean, data_std, train_images, test_images = self._data_loader.load_preprocessed_data(batch_size, preproc_lib, shuffle_data)
                else:
                    train_iter, test_iter, data_mean, data_std, train_images, test_images = self._data_loader.load_data(batch_size, shuffle_data)

            global_loss_train = 0.0
            train_batches = 0

            loss_total = 0
            train_iter.reset()
            for batch_i, batch in enumerate(train_iter):
                
                                 
                with autograd.record():
                    labels = [gluon.utils.split_and_load(batch.label[i], ctx_list=mx_context, even_split=False) for i in range(1)]
                    data_ = gluon.utils.split_and_load(batch.data[0], ctx_list=mx_context, even_split=False)

                    predictions_ = [mx.nd.zeros((single_pu_batch_size, 1000,), ctx=context) for context in mx_context]


                    nd.waitall()
                    lossList = []
                    for i in range(num_pus):
                        lossList.append([])

                    net_ret = [self._networks[0](data_[i]) for i in range(num_pus)]
                    predictions_ = [net_ret[i][0][0] for i in range(num_pus)]
                    [lossList[i].append(loss_function(predictions_[i], labels[0][i])) for i in range(num_pus)]


                    losses = [0]*num_pus
                    for i in range(num_pus):
                        for element in lossList[i]:
                            losses[i] = losses[i] + element

                for loss in losses: 
                    loss.backward()
                    loss_total += loss.sum().asscalar()
                    global_loss_train += loss.sum().asscalar()

                train_batches += 1

                if clip_global_grad_norm:
                    grads = []

                    for network in self._networks.values():
                        grads.extend([param.grad(mx_context) for param in network.collect_params().values()])

                    gluon.utils.clip_global_norm(grads, clip_global_grad_norm)

                for trainer in trainers:
                    trainer.step(batch_size)
    
                if tic is None:
                    tic = time.time()
                else:
                    if batch_i % log_period == 0:
                        try:
                            speed = log_period * batch_size / (time.time() - tic)
                        except ZeroDivisionError:
                            speed = float("inf")

                        loss_avg = loss_total / (batch_size * log_period)
                        loss_total = 0

                        logging.info("Epoch[%d] Batch[%d] Speed: %.2f samples/sec Loss: %.5f" % (epoch, batch_i, speed, loss_avg))
                        
                        avg_speed += speed
                        n += 1
    
                        tic = time.time()

            global_loss_train /= (train_batches * batch_size)

            tic = None
    
    
            if eval_train:
                train_iter.batch_size = single_pu_batch_size
                train_iter.reset()
                metric = mx.metric.create(eval_metric, **eval_metric_params)
                for batch_i, batch in enumerate(train_iter):

                    labels = [batch.label[i].as_in_context(mx_context[0]) for i in range(1)]
                    data_ = batch.data[0].as_in_context(mx_context[0])

                    predictions_ = mx.nd.zeros((single_pu_batch_size, 1000,), ctx=mx_context[0])


                    nd.waitall()

                    lossList = []
                    outputs = []
                    attentionList = []

                    net_ret = self._networks[0](data_)
                    predictions_ = net_ret[0][0]
                    outputs.append(predictions_)
                    lossList.append(loss_function(predictions_, labels[0]))
    
                    if save_attention_image == "True":
                        import matplotlib
                        matplotlib.use('Agg')
                        import matplotlib.pyplot as plt
                        logging.getLogger('matplotlib').setLevel(logging.ERROR)

                        if(os.path.isfile('src/test/resources/training_data/Show_attend_tell/dict.pkl')):
                            with open('src/test/resources/training_data/Show_attend_tell/dict.pkl', 'rb') as f:
                                dict = pickle.load(f)

                        plt.clf()
                        fig = plt.figure(figsize=(15,15))
                        max_length = len(labels)-1

                        ax = fig.add_subplot(max_length//3, max_length//4, 1)
                        ax.imshow(train_images[0+single_pu_batch_size*(batch_i)].transpose(1,2,0))

                        for l in range(max_length):
                            attention = attentionList[l]
                            attention = mx.nd.slice_axis(attention, axis=0, begin=0, end=1).squeeze()
                            attention_resized = np.resize(attention.asnumpy(), (8, 8))
                            ax = fig.add_subplot(max_length//3, max_length//4, l+2)
                            if int(labels[l+1][0].asscalar()) > len(dict):
                                ax.set_title("<unk>")
                            elif dict[int(labels[l+1][0].asscalar())] == "<end>":
                                ax.set_title(".")
                                img = ax.imshow(train_images[0+single_pu_batch_size*(batch_i)].transpose(1,2,0))
                                ax.imshow(attention_resized, cmap='gray', alpha=0.6, extent=img.get_extent())
                                break
                            else:
                                ax.set_title(dict[int(labels[l+1][0].asscalar())])
                            img = ax.imshow(train_images[0+single_pu_batch_size*(batch_i)].transpose(1,2,0))
                            ax.imshow(attention_resized, cmap='gray', alpha=0.6, extent=img.get_extent())

                        plt.tight_layout()
                        target_dir = 'target/attention_images'
                        if not os.path.exists(target_dir):
                            os.makedirs(target_dir)
                        plt.savefig(target_dir + '/attention_train.png')
                        plt.close()

                    predictions = []
                    for output_name in outputs:
                        if mx.nd.shape_array(mx.nd.squeeze(output_name)).size > 1:
                            predictions.append(mx.nd.argmax(output_name, axis=1))
                        else:
                            predictions.append(output_name)

                    metric.update(preds=predictions, labels=[labels[j] for j in range(len(labels))])

                train_metric_score = metric.get()[1]
            else:
                train_metric_score = 0

            global_loss_test = 0.0
            test_batches = 0
    
            test_iter.batch_size = single_pu_batch_size
            test_iter.reset()
            metric = mx.metric.create(eval_metric, **eval_metric_params)
            for batch_i, batch in enumerate(test_iter):
                if True: 
                                                   
                    labels = [batch.label[i].as_in_context(mx_context[0]) for i in range(1)]
                    data_ = batch.data[0].as_in_context(mx_context[0])

                    predictions_ = mx.nd.zeros((single_pu_batch_size, 1000,), ctx=mx_context[0])


                    nd.waitall()

                    lossList = []
                    outputs = []
                    attentionList = []

                    net_ret = self._networks[0](data_)
                    predictions_ = net_ret[0][0]
                    outputs.append(predictions_)
                    lossList.append(loss_function(predictions_, labels[0]))

                    if save_attention_image == "True":
                        if not eval_train:
                            import matplotlib
                            matplotlib.use('Agg')
                            import matplotlib.pyplot as plt
                            logging.getLogger('matplotlib').setLevel(logging.ERROR)

                            if(os.path.isfile('src/test/resources/training_data/Show_attend_tell/dict.pkl')):
                                with open('src/test/resources/training_data/Show_attend_tell/dict.pkl', 'rb') as f:
                                    dict = pickle.load(f)

                        plt.clf()
                        fig = plt.figure(figsize=(15,15))
                        max_length = len(labels)-1

                        ax = fig.add_subplot(max_length//3, max_length//4, 1)
                        ax.imshow(test_images[0+single_pu_batch_size*(batch_i)].transpose(1,2,0))

                        for l in range(max_length):
                            attention = attentionList[l]
                            attention = mx.nd.slice_axis(attention, axis=0, begin=0, end=1).squeeze()
                            attention_resized = np.resize(attention.asnumpy(), (8, 8))
                            ax = fig.add_subplot(max_length//3, max_length//4, l+2)
                            if int(mx.nd.slice_axis(outputs[l+1], axis=0, begin=0, end=1).squeeze().asscalar()) > len(dict):
                                ax.set_title("<unk>")
                            elif dict[int(mx.nd.slice_axis(outputs[l+1], axis=0, begin=0, end=1).squeeze().asscalar())] == "<end>":
                                ax.set_title(".")
                                img = ax.imshow(test_images[0+single_pu_batch_size*(batch_i)].transpose(1,2,0))
                                ax.imshow(attention_resized, cmap='gray', alpha=0.6, extent=img.get_extent())
                                break
                            else:
                                ax.set_title(dict[int(mx.nd.slice_axis(outputs[l+1], axis=0, begin=0, end=1).squeeze().asscalar())])
                            img = ax.imshow(test_images[0+single_pu_batch_size*(batch_i)].transpose(1,2,0))
                            ax.imshow(attention_resized, cmap='gray', alpha=0.6, extent=img.get_extent())

                        plt.tight_layout()
                        target_dir = 'target/attention_images'
                        if not os.path.exists(target_dir):
                            os.makedirs(target_dir)
                        plt.savefig(target_dir + '/attention_test.png')
                        plt.close()

                loss = 0
                for element in lossList:
                    loss = loss + element

                global_loss_test += loss.sum().asscalar()

                test_batches += 1

                predictions = []
                for output_name in outputs:
                    if mx.nd.shape_array(mx.nd.squeeze(output_name)).size > 1:
                        predictions.append(mx.nd.argmax(output_name, axis=1))
                    else:
                        predictions.append(output_name)

                metric.update(preds=predictions, labels=[labels[j] for j in range(len(labels))])

            global_loss_test /= (test_batches * single_pu_batch_size)
            test_metric_name = metric.get()[0]
            test_metric_score = metric.get()[1]

            metric_file = open(self._net_creator._model_dir_ + 'metric.txt', 'w')
            metric_file.write(test_metric_name + " " + str(test_metric_score))
            metric_file.close()

            logging.info("Epoch[%d] Train metric: %f, Test metric: %f, Train loss: %f, Test loss: %f" % (epoch, train_metric_score, test_metric_score, global_loss_train, global_loss_test))

            if (epoch+1) % checkpoint_period == 0:
                for i, network in self._networks.items():
                    network.save_parameters(self.parameter_path(i) + '-' + str(epoch).zfill(4) + '.params')

        for i, network in self._networks.items():
            network.save_parameters(self.parameter_path(i) + '-' + str((num_epoch-1) + begin_epoch).zfill(4) + '.params')
            network.export(self.parameter_path(i) + '_newest', epoch=0)

            if onnx_export:
                from mxnet.contrib import onnx as onnx_mxnet
                input_shapes = [(1,) + d.shape[1:] for _, d in test_iter.data]
                model_path = self.parameter_path(i) + '_newest'
                onnx_mxnet.export_model(model_path+'-symbol.json', model_path+'-0000.params', input_shapes, np.float32, model_path+'.onnx')

            loss_function.export(self.parameter_path(i) + '_newest_loss', epoch=0)
Ejemplo n.º 30
0
import os

import mxnet

from mxnet.contrib.onnx import export_model


import mxnet as mx

from configs import ROOT_DIR

print(mx.context.num_gpus())
from mxnet.runtime import feature_list
print(feature_list())

input_shape = '3,112,112'
input_shape = (1,) + tuple( [int(x) for x in input_shape.split(',')] )
print('input-shape:', input_shape)

import onnx

assert onnx.__version__=='1.2.1'

export_model(sym=os.path.join(ROOT_DIR, 'networks/insightface/model-r100-ii/model-symbol.json'),
             params=os.path.join(ROOT_DIR, 'networks/insightface/model-r100-ii/model-0000.params'),
             input_shape=[input_shape],
             onnx_file_path=os.path.join(ROOT_DIR, 'networks/onnx/model.onnx'),
             verbose=True)