You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by jx...@apache.org on 2017/08/29 00:22:34 UTC

[incubator-mxnet] branch master updated: Pip installer for CoreML Converter: mxnet-to-coreml (#7624)

This is an automated email from the ASF dual-hosted git repository.

jxie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/master by this push:
     new 4e11674  Pip installer for CoreML Converter: mxnet-to-coreml (#7624)
4e11674 is described below

commit 4e116740d1adf78e9e0c4ed6202965db08c2087b
Author: Pracheer Gupta <pr...@hotmail.com>
AuthorDate: Mon Aug 28 17:22:31 2017 -0700

    Pip installer for CoreML Converter: mxnet-to-coreml (#7624)
    
    * Fixing CoreML converter's README: typos/grammar/etc.
    
    * CoreML converter README update: Talk about layers first and then about models.
    
    * Providing examples on converting various standard models; calling out issues with InceptionV3.
    
    * Fixing CoreML converter's README: typos/grammar/etc.
    
    * CoreML converter README update: Talk about layers first and then about models.
    
    * Providing examples on converting various standard models; calling out issues with InceptionV3.
    
    * Pip installer for converter: mxnet-coreml-converter.
    
    Runs only on MacOS and python 2.7. Once inside the directory pip_package, user needs
    to run:
    python setup.py bdist_wheel
    twine upload dist/*
    
    Once uploaded it'll look like this:
    https://testpypi.python.org/pypi/mxnet-coreml-converter
    
    Also updated the README for converter to reflect this.
    
    Note that we are going with a package per tool for the time being. Please leave feedback if you think it is better to adopt the policy of all the tools in one single package.
    
    Unit tests continue to pass.
    
    * More informative pypi package documentation.
    
    * Updating MacOS in release notes to 10.11 after testing on it.
    
    * Changing the name to mxnet-to-coreml and version to 0.1.0.
    
    * Added license to setup.py
    
    * Updating readme files with the correct pip package name.
---
 tools/coreml/README.md                 | 39 +++++++++----------
 tools/coreml/{ => converter}/utils.py  |  0
 tools/coreml/mxnet_coreml_converter.py |  3 +-
 tools/coreml/pip_package/.gitignore    | 10 +++++
 tools/coreml/pip_package/MANIFEST.in   |  5 +++
 tools/coreml/pip_package/README.rst    | 44 ++++++++++++++++++++++
 tools/coreml/pip_package/setup.py      | 69 ++++++++++++++++++++++++++++++++++
 tools/coreml/test/test_mxnet_image.py  |  2 +-
 8 files changed, 149 insertions(+), 23 deletions(-)

diff --git a/tools/coreml/README.md b/tools/coreml/README.md
index e29eebe..45f19b6 100644
--- a/tools/coreml/README.md
+++ b/tools/coreml/README.md
@@ -3,22 +3,23 @@
 This tool helps convert MXNet models into [Apple CoreML](https://developer.apple.com/documentation/coreml) format which can then be run on Apple devices.
 
 ## Installation
-In order to use this tool you need to have these installed:
-* MacOS - High Sierra 10.13
-* Xcode 9
-* coremltools 0.5.0 or greater (pip install coremltools)
-* mxnet 0.10.0 or greater. [Installation instructions](http://mxnet.io/get_started/install.html).
-* yaml (pip install pyyaml)
+In order to use this tool you need to have these:
+* MacOS - 10.11 (El Capitan) or higher (for running inferences on the converted model MacOS 10.13 or higher (for phones: iOS 11 or above) is needed)
 * python 2.7
+* mxnet-to-coreml tool: 
+
+```bash
+pip install mxnet-to-coreml
+```
 
 ## How to use
-Let's say you want to use your MXNet model in an iPhone App. For the purpose of this example, let's say you want to use squeezenet-v1.1.
+Let's say you want to use your MXNet model in an iPhone App. For the purpose of this example, let's assume it is a squeezenet-v1.1 model.
 
-1. Download the model into the directory where this converter resides. Squeezenet can be downloaded from [here](http://data.mxnet.io/models/imagenet/squeezenet/).
+1. Download the model into the directory where this converter resides. Squeezenet can be downloaded from [here](http://data.mxnet.io/models/imagenet/squeezenet/). The synset.txt file which contains all the class-labels and can be downloaded from [here](http://data.mxnet.io/models/imagenet/synset.txt).
 2. Run this command:
 
   ```bash
-python mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,227,227"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels classLabels.txt --output-file="squeezenetv11.mlmodel"
+mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,227,227"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels synset.txt --output-file="squeezenetv11.mlmodel"
 ```
 
   The above command will save the converted model in CoreML format to file squeezenet-v11.mlmodel. Internally, the model is first loaded by MXNet recreating the entire symbolic graph in memory. The converter walks through this symbolic graph converting each operator into its CoreML equivalent. Some of the supplied arguments to the converter are used by MXNet to generate the graph while others are used by CoreML either to pre-process the input (before passing it to the neural network) or  [...]
@@ -40,20 +41,20 @@ python mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --in
 You could provide a file containing class labels (as above) so that CoreML will return the category a given image belongs to. The file should have a label per line and labels can have any special characters. The line number of the label in the file should correspond with the index of softmax output. E.g.
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,227,227"}' --mode=classifier --class-labels classLabels.txt --output-file="squeezenetv11.mlmodel"
+mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,227,227"}' --mode=classifier --class-labels synset.txt --output-file="squeezenetv11.mlmodel"
 ```
 
 ### Adding a pre-processing layer to CoreML model.
 You could ask CoreML to pre-process the images before passing them through the model. The following command provides image re-centering parameters for red, blue and green channel.
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,224,224"}' --pre-processing-arguments='{"red_bias":127,"blue_bias":117,"green_bias":103}' --output-file="squeezenet_v11.mlmodel"
+mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,224,224"}' --pre-processing-arguments='{"red_bias":127,"blue_bias":117,"green_bias":103}' --output-file="squeezenet_v11.mlmodel"
 ```
 
 If you are building an app for a model that takes "Image" as an input, you will have to provide image_input_names as pre-processing arguments. This tells CoreML that a particular input variable is of type Image. E.g.:
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,224,224"}' --pre-processing-arguments='{"red_bias":127,"blue_bias":117,"green_bias":103,"image_input_names":"data"}' --output-file="squeezenet_v11.mlmodel"
+mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,224,224"}' --pre-processing-arguments='{"red_bias":127,"blue_bias":117,"green_bias":103,"image_input_names":"data"}' --output-file="squeezenet_v11.mlmodel"
 ```
 
 ## Currently supported
@@ -79,36 +80,32 @@ Any MXNet model that uses the above operators can be converted easily. For insta
 1. [Inception-BN](http://data.mxnet.io/models/imagenet/inception-bn/)
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='Inception-BN' --epoch=126 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels classLabels.txt --output-file="InceptionBN.mlmodel"
+mxnet_coreml_converter.py --model-prefix='Inception-BN' --epoch=126 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels synset.txt --output-file="InceptionBN.mlmodel"
 ```
 
 2. [NiN](http://data.dmlc.ml/models/imagenet/nin/)
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='nin' --epoch=0 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels classLabels.txt --output-file="nin.mlmodel"
+mxnet_coreml_converter.py --model-prefix='nin' --epoch=0 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels synset.txt --output-file="nin.mlmodel"
 ```
 
 3. [Resnet](http://data.mxnet.io/models/imagenet/resnet/)
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='resnet-50' --epoch=0 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels classLabels.txt --output-file="resnet50.mlmodel"
+mxnet_coreml_converter.py --model-prefix='resnet-50' --epoch=0 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels synset.txt --output-file="resnet50.mlmodel"
 ```
 
 4. [Squeezenet](http://data.mxnet.io/models/imagenet/squeezenet/)
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,227,227"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels classLabels.txt --output-file="squeezenetv11.mlmodel"
+mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' --epoch=0 --input-shape='{"data":"3,227,227"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels synset.txt --output-file="squeezenetv11.mlmodel"
 ```
 
 5. [Vgg](http://data.mxnet.io/models/imagenet/vgg/)
 
 ```bash
-python mxnet_coreml_converter.py --model-prefix='vgg16' --epoch=0 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels classLabels.txt --output-file="vgg16.mlmodel"
+mxnet_coreml_converter.py --model-prefix='vgg16' --epoch=0 --input-shape='{"data":"3,224,224"}' --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' --class-labels synset.txt --output-file="vgg16.mlmodel"
 ```
 
 ## Known issues
 * [Inception-V3](http://data.mxnet.io/models/imagenet/inception-v3.tar.gz) model can be converted into CoreML format but is unable to run on Xcode.
-
-## This tool has been tested with:
-* MacOS - High Sierra 10.13 Beta.
-* Xcode 9 beta 5.
diff --git a/tools/coreml/utils.py b/tools/coreml/converter/utils.py
similarity index 100%
rename from tools/coreml/utils.py
rename to tools/coreml/converter/utils.py
diff --git a/tools/coreml/mxnet_coreml_converter.py b/tools/coreml/mxnet_coreml_converter.py
index 502377e..ffa5008 100644
--- a/tools/coreml/mxnet_coreml_converter.py
+++ b/tools/coreml/mxnet_coreml_converter.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -18,7 +19,7 @@
 from __future__ import print_function
 import argparse
 from converter._mxnet_converter import convert
-from utils import load_model
+from converter.utils import load_model
 import yaml
 from ast import literal_eval
 
diff --git a/tools/coreml/pip_package/.gitignore b/tools/coreml/pip_package/.gitignore
new file mode 100644
index 0000000..7c67bf4
--- /dev/null
+++ b/tools/coreml/pip_package/.gitignore
@@ -0,0 +1,10 @@
+# Compiled python modules.
+*.pyc
+
+# Setuptools distribution folder.
+/dist/
+
+# Python egg metadata, regenerated from source files by setuptools.
+/*.egg-info
+/*.egg
+
diff --git a/tools/coreml/pip_package/MANIFEST.in b/tools/coreml/pip_package/MANIFEST.in
new file mode 100644
index 0000000..6ecd97d
--- /dev/null
+++ b/tools/coreml/pip_package/MANIFEST.in
@@ -0,0 +1,5 @@
+# Include the license file
+include LICENSE.txt
+
+# Documentation for pypi webpage
+include README.rst
diff --git a/tools/coreml/pip_package/README.rst b/tools/coreml/pip_package/README.rst
new file mode 100644
index 0000000..875d89f
--- /dev/null
+++ b/tools/coreml/pip_package/README.rst
@@ -0,0 +1,44 @@
+MXNET -> CoreML Converter
+=========================
+
+`Apache MXNet <https://github.com/apache/incubator-mxnet>`_ (incubating) is a deep learning framework designed for both efficiency and flexibility. It allows you to mix `symbolic and imperative programming <http://mxnet.io/architecture/index.html#deep-learning-system-design-concepts>`_ to maximize efficiency and productivity. At its core, MXNet contains a dynamic dependency scheduler that automatically parallelizes both symbolic and imperative operations on the fly. A graph optimization  [...]
+
+`Core ML <http://developer.apple.com/documentation/coreml>`_ is an Apple framework which allows developers to simply and easily integrate machine learning (ML) models into apps running on Apple devices (including iOS, watchOS, macOS, and tvOS). Core ML introduces a public file format (.mlmodel) for a broad set of ML methods including deep neural networks (both convolutional and recurrent), tree ensembles with boosting, and generalized linear models. Models in this format can be directly  [...]
+
+This tool helps convert `MXNet models <https://github.com/apache/incubator-mxnet>`_ into `Apple CoreML <https://developer.apple.com/documentation/coreml>`_ format which can then be run on Apple devices. You can find more information about this tool on our `github <https://github.com/apache/incubator-mxnet/tree/master/tools/coreml>`_ page.
+
+Prerequisites
+-------------
+This package can only be installed on MacOS X since it relies on Apple's CoreML SDK. It can be run on MacOS 10.11 or higher though for running inferences on the converted model MacOS 10.13 or higher is needed (or for phones, iOS 11 or above).
+
+Installation
+------------
+The method for installing this tool follows the `standard python package installation steps <https://packaging.python.org/installing/>`_. Once you have set up a python environment, run::
+
+  pip install mxnet-to-coreml
+
+The package `documentation <https://github.com/apache/incubator-mxnet/tree/master/tools/coreml>`_ contains more details on how to use coremltools.
+
+Dependencies
+------------
+This tool has the following dependencies:
+
+* mxnet (0.10.0+)
+* coremltools (0.5.1+)
+* pyyaml (3.12+)
+
+Sample Usage
+------------
+
+In order to convert, say a `Squeezenet model <http://data.mxnet.io/models/imagenet/squeezenet/>`_, with labels from `synset.txt <http://data.mxnet.io/models/imagenet/synset.txt>`_, execute this ::
+
+  mxnet_coreml_converter.py --model-prefix='squeezenet_v1.1' \
+  --epoch=0 --input-shape='{"data":"3,227,227"}' \
+  --mode=classifier --pre-processing-arguments='{"image_input_names":"data"}' \
+  --class-labels synset.txt --output-file="squeezenetv11.mlmodel"
+
+More Information
+----------------
+* `On Github <https://github.com/apache/incubator-mxnet/tree/master/tools/coreml>`_
+* `MXNet framework <https://github.com/apache/incubator-mxnet>`_
+* `Apple CoreML <https://developer.apple.com/documentation/coreml>`_
diff --git a/tools/coreml/pip_package/setup.py b/tools/coreml/pip_package/setup.py
new file mode 100644
index 0000000..18c601d
--- /dev/null
+++ b/tools/coreml/pip_package/setup.py
@@ -0,0 +1,69 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from setuptools import setup
+from setuptools import find_packages
+
+# We are overriding the default behavior of bdist_wheel which is generating
+# pure python wheels while we need platform specific wheel since this tool
+# can only work on MacOS.
+try:
+    from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
+    class bdist_wheel(_bdist_wheel):
+        def finalize_options(self):
+            _bdist_wheel.finalize_options(self)
+            self.root_is_pure = False
+except ImportError:
+    bdist_wheel = None
+
+
+def readme():
+    """
+    Reads README.rst file and allows us to provide
+    a better experience for pypi webpage.
+    """
+    with open('README.rst') as f:
+        return f.read()
+
+setup(name='mxnet-to-coreml',
+      version='0.1.0',
+      description='Tool to convert MXNet models into Apple CoreML model format.',
+      long_description=readme(),
+      classifiers=[
+        'Development Status :: 4 - Beta',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Apache Software License',
+        'Operating System :: MacOS :: MacOS X',
+        'Programming Language :: Python :: 2.7',
+        'Topic :: Software Development :: Libraries :: Python Modules'
+      ],
+      keywords='Apache MXNet Apple CoreML Converter Deep Learning',
+      url='https://github.com/apache/incubator-mxnet/tree/master/tools/coreml',
+      author='pracheer',
+      author_email='pracheer_gupta@hotmail.com',
+      license='Apache 2.0',
+      package_dir = {'': '..'},
+      packages=['converter'],
+      install_requires=[
+          'mxnet',
+          'coremltools',
+          'pyyaml',
+      ],
+      scripts=['../mxnet_coreml_converter.py'],
+      python_requires='~=2.7',
+      zip_safe=False,
+      cmdclass={'bdist_wheel': bdist_wheel},)
diff --git a/tools/coreml/test/test_mxnet_image.py b/tools/coreml/test/test_mxnet_image.py
index ac30ac7..2bbf7b1 100644
--- a/tools/coreml/test/test_mxnet_image.py
+++ b/tools/coreml/test/test_mxnet_image.py
@@ -24,7 +24,7 @@ current_working_directory = os.getcwd()
 sys.path.append(current_working_directory + "/..")
 sys.path.append(current_working_directory + "/../converter/")
 import _mxnet_converter as mxnet_converter
-from utils import load_model
+from converter.utils import load_model
 
 
 VAL_DATA = 'data/val-5k-256.rec'

-- 
To stop receiving notification emails like this one, please contact
['"commits@mxnet.apache.org" <co...@mxnet.apache.org>'].