| { |
| "cells": [ |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "<!--- Licensed to the Apache Software Foundation (ASF) under one -->\n", |
| "<!--- or more contributor license agreements. See the NOTICE file -->\n", |
| "<!--- distributed with this work for additional information -->\n", |
| "<!--- regarding copyright ownership. The ASF licenses this file -->\n", |
| "<!--- to you under the Apache License, Version 2.0 (the -->\n", |
| "<!--- \"License\"); you may not use this file except in compliance -->\n", |
| "<!--- with the License. You may obtain a copy of the License at -->\n", |
| "\n", |
| "<!--- http://www.apache.org/licenses/LICENSE-2.0 -->\n", |
| "\n", |
| "<!--- Unless required by applicable law or agreed to in writing, -->\n", |
| "<!--- software distributed under the License is distributed on an -->\n", |
| "<!--- \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->\n", |
| "<!--- KIND, either express or implied. See the License for the -->\n", |
| "<!--- specific language governing permissions and limitations -->\n", |
| "<!--- under the License. -->\n", |
| "\n", |
| "# Exporting to ONNX format\n", |
| "\n", |
| "[Open Neural Network Exchange (ONNX)](https://github.com/onnx/onnx) provides an open source format for AI models. It defines an extensible computation graph model, as well as definitions of built-in operators and standard data types.\n", |
| "\n", |
| "In this tutorial, we will show how you can save MXNet models to the ONNX format.\n", |
| "\n", |
| "MXNet-ONNX operators coverage and features are updated regularly. Visit the [ONNX operator coverage](https://cwiki.apache.org/confluence/display/MXNET/ONNX+Operator+Coverage) page for the latest information.\n", |
| "\n", |
| "In this tutorial, we will learn how to use MXNet to ONNX exporter on pre-trained models.\n", |
| "\n", |
| "## Prerequisites\n", |
| "\n", |
| "To run the tutorial you will need to have installed the following python modules:\n", |
| "- [MXNet >= 1.3.0](/get_started)\n", |
| "- [onnx]( https://github.com/onnx/onnx#installation) v1.2.1 (follow the install guide)\n", |
| "\n", |
| "*Note:* MXNet-ONNX importer and exporter follows version 7 of ONNX operator set which comes with ONNX v1.2.1." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "import mxnet as mx\n", |
| "import numpy as np\n", |
| "from mxnet.contrib import onnx as onnx_mxnet\n", |
| "import logging\n", |
| "logging.basicConfig(level=logging.INFO)" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "## Downloading a model from the MXNet model zoo\n", |
| "\n", |
| "We download the pre-trained ResNet-18 [ImageNet](http://www.image-net.org/) model from the [MXNet Model Zoo](/api/python/docs/api/gluon/model_zoo/index.html).\n", |
| "We will also download synset file to match labels." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "# Download pre-trained resnet model - json and params by running following code.\n", |
| "path='http://data.mxnet.io/models/imagenet/'\n", |
| "[mx.test_utils.download(path+'resnet/18-layers/resnet-18-0000.params'),\n", |
| " mx.test_utils.download(path+'resnet/18-layers/resnet-18-symbol.json'),\n", |
| " mx.test_utils.download(path+'synset.txt')]" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "Now, we have downloaded ResNet-18 symbol, params and synset file on the disk.\n", |
| "\n", |
| "## MXNet to ONNX exporter API\n", |
| "\n", |
| "Let us describe the MXNet's `export_model` API." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "help(onnx_mxnet.export_model)" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "Output:" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "```text\n", |
| "Help on function export_model in module mxnet.contrib.onnx.mx2onnx.export_model:\n", |
| "\n", |
| "export_model(sym, params, input_shape, input_type=<type 'numpy.float32'>, onnx_file_path=u'model.onnx', verbose=False)\n", |
| " Exports the MXNet model file, passed as a parameter, into ONNX model.\n", |
| " Accepts both symbol,parameter objects as well as json and params filepaths as input.\n", |
| " Operator support and coverage - https://cwiki.apache.org/confluence/display/MXNET/MXNet-ONNX+Integration\n", |
| " \n", |
| " Parameters\n", |
| " ----------\n", |
| " sym : str or symbol object\n", |
| " Path to the json file or Symbol object\n", |
| " params : str or symbol object\n", |
| " Path to the params file or params dictionary. (Including both arg_params and aux_params)\n", |
| " input_shape : List of tuple\n", |
| " Input shape of the model e.g [(1,3,224,224)]\n", |
| " input_type : data type\n", |
| " Input data type e.g. np.float32\n", |
| " onnx_file_path : str\n", |
| " Path where to save the generated onnx file\n", |
| " verbose : Boolean\n", |
| " If true will print logs of the model conversion\n", |
| " \n", |
| " Returns\n", |
| " -------\n", |
| " onnx_file_path : str\n", |
| " Onnx file path\n", |
| "```\n" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "`export_model` API can accept the MXNet model in one of the following two ways.\n", |
| "\n", |
| "1. MXNet sym, params objects:\n", |
| " * This is useful if we are training a model. At the end of training, we just need to invoke the `export_model` function and provide sym and params objects as inputs with other attributes to save the model in ONNX format.\n", |
| "2. MXNet's exported json and params files:\n", |
| " * This is useful if we have pre-trained models and we want to convert them to ONNX format.\n", |
| "\n", |
| "Since we have downloaded pre-trained model files, we will use the `export_model` API by passing the path for symbol and params files.\n", |
| "\n", |
| "## How to use MXNet to ONNX exporter API\n", |
| "\n", |
| "We will use the downloaded pre-trained model files (sym, params) and define input variables." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "# Downloaded input symbol and params files\n", |
| "sym = './resnet-18-symbol.json'\n", |
| "params = './resnet-18-0000.params'\n", |
| "\n", |
| "# Standard Imagenet input - 3 channels, 224*224\n", |
| "input_shape = (1,3,224,224)\n", |
| "\n", |
| "# Path of the output file\n", |
| "onnx_file = './mxnet_exported_resnet50.onnx'" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "We have defined the input parameters required for the `export_model` API. Now, we are ready to covert the MXNet model into ONNX format." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "# Invoke export model API. It returns path of the converted onnx model\n", |
| "converted_model_path = onnx_mxnet.export_model(sym, params, [input_shape], np.float32, onnx_file)" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "This API returns path of the converted model which you can later use to import the model into other frameworks.\n", |
| "\n", |
| "## Check validity of ONNX model\n", |
| "\n", |
| "Now we can check validity of the converted ONNX model by using ONNX checker tool. The tool will validate the model by checking if the content contains valid protobuf:" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": null, |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "from onnx import checker\n", |
| "import onnx\n", |
| "\n", |
| "# Load onnx model\n", |
| "model_proto = onnx.load_model(converted_model_path)\n", |
| "\n", |
| "# Check if converted ONNX protobuf is valid\n", |
| "checker.check_graph(model_proto.graph)" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "metadata": {}, |
| "source": [ |
| "If the converted protobuf format doesn't qualify to ONNX proto specifications, the checker will throw errors, but in this case it successfully passes. \n", |
| "\n", |
| "This method confirms exported model protobuf is valid. Now, the model is ready to be imported in other frameworks for inference!" |
| ] |
| } |
| ], |
| "metadata": { |
| "language_info": { |
| "name": "python" |
| } |
| }, |
| "nbformat": 4, |
| "nbformat_minor": 4 |
| } |