diff --git a/README.md b/README.md
index 9e455b4db2..05746b7de5 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,7 @@ These examples that showcase unique functionality available in Amazon SageMaker.
- [Bring Your Own R Algorithm](advanced_functionality/r_bring_your_own) shows how to bring your own algorithm container to Amazon SageMaker using the R language.
- [Installing the R Kernel](advanced_functionality/install_r_kernel) shows how to install the R kernel into an Amazon SageMaker Notebook Instance.
- [Bring Your Own scikit Algorithm](advanced_functionality/scikit_bring_your_own) provides a detailed walkthrough on how to package a scikit learn algorithm for training and production-ready hosting.
+- [Bring Your Own MXNet Model](advanced_functionality/mxnet_mnist_byom) shows how to bring a model trained anywhere using MXNet into Amazon SageMaker
- [Bring Your Own TensorFlow Model](advanced_functionality/tensorflow_iris_byom) shows how to bring a model trained anywhere using TensorFlow into Amazon SageMaker
### Amazon SageMaker TensorFlow and MXNet Pre-Built Containers and the Python SDK
@@ -69,8 +70,6 @@ These examples focus on the Amazon SageMaker Python SDK which allows you to writ
These Amazon SageMaker examples fully illustrate a concept, but may require some additional configuration on the users part to complete.
-- [Bring Your Own MXNet Model](under_development/mxnet_mnist_byom) shows how to bring a model trained anywhere using MXNet into Amazon SageMaker
-
## FAQ
*What do I need in order to get started?*
diff --git a/advanced_functionality/README.md b/advanced_functionality/README.md
index 38eb7ae9c6..3dfdc3be2c 100644
--- a/advanced_functionality/README.md
+++ b/advanced_functionality/README.md
@@ -13,4 +13,5 @@ These examples that showcase unique functionality available in Amazon SageMaker.
- [Installing the R Kernel](install_r_kernel) shows how to install the R kernel into an Amazon SageMaker Notebook Instance.
- [Bring Your Own R Algorithm](r_bring_your_own) shows how to bring your own algorithm container to Amazon SageMaker using the R language.
- [Bring Your Own scikit Algorithm](scikit_bring_your_own) provides a detailed walkthrough on how to package a scikit learn algorithm for training and production-ready hosting.
-- [Bring Your Own TensorFlow Model](tensorflow_iris_byom) shows how to bring a model trained anywhere using TensorFlow into Amazon SageMaker
+- [Bring Your Own MXNet Model](mxnet_mnist_byom) shows how to bring a model trained anywhere using MXNet into Amazon SageMaker
+- [Bring Your Own TensorFlow Model](tensorflow_iris_byom) shows how to bring a model trained anywhere using TensorFlow into Amazon SageMaker
\ No newline at end of file
diff --git a/advanced_functionality/mxnet_mnist_byom/input.html b/advanced_functionality/mxnet_mnist_byom/input.html
new file mode 100644
index 0000000000..78d91aee88
--- /dev/null
+++ b/advanced_functionality/mxnet_mnist_byom/input.html
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/under_development/mxnet_mnist_byom/mnist.py b/advanced_functionality/mxnet_mnist_byom/mnist.py
similarity index 98%
rename from under_development/mxnet_mnist_byom/mnist.py
rename to advanced_functionality/mxnet_mnist_byom/mnist.py
index eafc50209e..d56371d437 100644
--- a/under_development/mxnet_mnist_byom/mnist.py
+++ b/advanced_functionality/mxnet_mnist_byom/mnist.py
@@ -12,7 +12,6 @@ def find_file(root_path, file_name):
if file_name in files:
return os.path.join(root, file_name)
-
def build_graph():
data = mx.sym.var('data')
data = mx.sym.flatten(data=data)
@@ -49,4 +48,4 @@ def train(data, hyperparameters= {'learning_rate': 0.11}, num_cpus=0, num_gpus =
def get_train_context(num_cpus, num_gpus):
if num_gpus > 0:
return mx.gpu()
- return mx.cpu()
+ return mx.cpu()
\ No newline at end of file
diff --git a/under_development/mxnet_mnist_byom/mxnet_mnist.ipynb b/advanced_functionality/mxnet_mnist_byom/mxnet_mnist.ipynb
similarity index 81%
rename from under_development/mxnet_mnist_byom/mxnet_mnist.ipynb
rename to advanced_functionality/mxnet_mnist_byom/mxnet_mnist.ipynb
index 3ac107599f..dd49bf57fa 100644
--- a/under_development/mxnet_mnist_byom/mxnet_mnist.ipynb
+++ b/advanced_functionality/mxnet_mnist_byom/mxnet_mnist.ipynb
@@ -58,7 +58,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": null,
"metadata": {
"collapsed": true,
"isConfigCell": true
@@ -83,9 +83,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"import mxnet as mx\n",
@@ -100,7 +98,7 @@
"source": [
"### Training\n",
"\n",
- "It is time to train the network. Since we are training the network locally, we can make use of mxnet training tools. The training method is also in the accompanying [mnist.py](mnist.py) file. The method is shown below. \n",
+ "It is time to train the network. Since we are training the network locally, we can make use of mxnet training tools. The training method is also in the accompanying [mnist.py](mnist.py) file. The notebook assumes that this instance is a `p2.xlarge`. If running this in a non-GPU notebook instance, please adjust num_gpus=0 and num_cpu=1 The method is shown below. \n",
"\n",
"```python \n",
"def train(data, hyperparameters= {'learning_rate': 0.11}, num_cpus=0, num_gpus =1 , **kwargs):\n",
@@ -131,19 +129,19 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"from mnist import train\n",
- "model = train(data = data)"
+ "model = train(data = data, num_cpus=0, num_gpus=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
+ "If you want to run the training on a cpu or if you are on an instance with cpus only, pass appropriate arguments. \n",
+ "\n",
"## Set up hosting for the model\n",
"\n",
"### Export the model from mxnet\n",
@@ -154,23 +152,33 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"import os\n",
+ "import json\n",
"os.mkdir('model')\n",
+ "\n",
"model.save_checkpoint('model/model', 0000)\n",
+ "with open ( 'model/model-shapes.json', \"w\") as shapes:\n",
+ " json.dump([{\"shape\": model.data_shapes[0][1], \"name\": \"data\"}], shapes)\n",
+ "\n",
"import tarfile\n",
- "with tarfile.open('model.tar.gz', mode='w:gz') as archive:\n",
- " archive.add('model', recursive=True)"
+ "def flatten(tarinfo):\n",
+ " tarinfo.name = os.path.basename(tarinfo.name)\n",
+ " return tarinfo\n",
+ "\n",
+ "tar = tarfile.open(\"model.tar.gz\", \"w:gz\")\n",
+ "tar.add(\"model\", filter=flatten)\n",
+ "tar.close() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
+ "The above piece of code essentially hacks the MXNet model export into a sagemaker-readable model export. Study the exported model files if you want to organize your exports in the same fashion as well. Alternatively, you can load the model on MXNet itself and load the sagemaker model as you normally would. Refer [here](https://github.com/aws/sagemaker-python-sdk#model-loading) for details on how to load MXNet models.\n",
+ "\n",
"### Import model into SageMaker\n",
"\n",
"Open a new sagemaker session and upload the model on to the default S3 bucket. We can use the ``sagemaker.Session.upload_data`` method to do this. We need the location of where we exported the model from MXNet and where in our default bucket we want to store the model(``/model``). The default S3 bucket can be found using the ``sagemaker.Session.default_bucket`` method."
@@ -179,9 +187,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"import sagemaker\n",
@@ -200,9 +206,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"from sagemaker.mxnet.model import MXNetModel\n",
@@ -223,13 +227,14 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
+ "import logging\n",
+ "logging.getLogger().setLevel(logging.WARNING)\n",
+ "\n",
"predictor = sagemaker_model.deploy(initial_instance_count=1,\n",
- " instance_type='ml.c4.xlarge')"
+ " instance_type='ml.m4.xlarge')"
]
},
{
@@ -238,21 +243,37 @@
"source": [
"### Validate the endpoint for use\n",
"\n",
- "We can now use this endpoint to classify hand-written digits."
+ "We can now use this endpoint to classify hand-written digits. To see inference in action, draw a digit in the image box below. The pixel data from your drawing will be loaded into a ``data`` variable in this notebook. \n",
+ "\n",
+ "*Note: after drawing the image, you'll need to move to the next notebook cell.*"
]
},
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from IPython.display import HTML\n",
+ "HTML(open(\"input.html\").read())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
"outputs": [],
"source": [
- "predict_sample = data['test_data'][0][0]\n",
"response = predictor.predict(data)\n",
"print('Raw prediction result:')\n",
- "print(response)"
+ "print(response)\n",
+ "\n",
+ "labeled_predictions = list(zip(range(10), response[0]))\n",
+ "print('Labeled predictions: ')\n",
+ "print(labeled_predictions)\n",
+ "\n",
+ "labeled_predictions.sort(key=lambda label_and_prob: 1.0 - label_and_prob[1])\n",
+ "print('Most likely answer: {}'.format(labeled_predictions[0]))"
]
},
{
@@ -267,9 +288,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"print(predictor.endpoint)"
@@ -279,7 +298,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "If you do not want continued use of the endpoint, you can remove it. Remember, open endpoints are charged. If this is a simple test or practice, it is recommended to delete them."
+ "If you do not want continied use of the endpoint, you can remove it. Remember, open endpoints are charged. If this is a simple test or practice, it is recommended to delete them."
]
},
{
@@ -303,21 +322,27 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
"source": [
"os.remove('model.tar.gz')\n",
"import shutil\n",
- "shutil.rmtree('export')"
+ "shutil.rmtree('model')"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
}
],
"metadata": {
- "notice": "Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the \"License\"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/apache2.0/ or in the \"license\" file accompanying this file. This file 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.",
"kernelspec": {
- "display_name": "Environment (conda_mxnet_p36)",
+ "display_name": "conda_mxnet_p36",
"language": "python",
"name": "conda_mxnet_p36"
},
@@ -332,7 +357,8 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
- }
+ },
+ "notice": "Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the \"License\"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/apache2.0/ or in the \"license\" file accompanying this file. This file 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."
},
"nbformat": 4,
"nbformat_minor": 2
diff --git a/advanced_functionality/tensorflow_iris_byom/tensorflow_BYOM_iris.ipynb b/advanced_functionality/tensorflow_iris_byom/tensorflow_BYOM_iris.ipynb
index 7a90d95799..7674de6235 100644
--- a/advanced_functionality/tensorflow_iris_byom/tensorflow_BYOM_iris.ipynb
+++ b/advanced_functionality/tensorflow_iris_byom/tensorflow_BYOM_iris.ipynb
@@ -171,7 +171,7 @@
"\n",
"### Export the model from tensorflow\n",
"\n",
- "In order to set up hosting, we have to import the model from training to hosting. We will begin by exporting the model from TensorFlow and saving it down. Analogous to the [MXNet example](../mxnet_mnist_byom/mxnet_mnist.ipynb), some structure needs to be followed. The exported model has to be converted into a form that is readable by ``sagemaker.mxnet.model.MXNetModel``. The following code describes exporting the model in a form that does the same:\n",
+ "In order to set up hosting, we have to import the model from training to hosting. We will begin by exporting the model from TensorFlow and saving it down. Analogous to the [MXNet example](../mxnet_mnist_byom/mxnet_mnist.ipynb), some structure needs to be followed. The exported model has to be converted into a form that is readable by ``sagemaker.tensorflow.model.TensorFlowModel``. The following code describes exporting the model in a form that does the same:\n",
"\n",
"There is a small difference between a SageMaker model and a TensorFlow model. The conversion is easy and fairly trivial. Simply move the tensorflow exported model into a directory ``export\\Servo\\`` and tar the entire directory. SageMaker will recognize this as a loadable TensorFlow model."
]
@@ -199,7 +199,7 @@
"source": [
"### Import model into SageMaker\n",
"\n",
- "Open a new sagemaker session and upload the model on to the default S3 bucket. We can use the ``sagemaker.Session.upload_data`` method to do this. We need the location of where we exported the model from MXNet and where in our default bucket we want to store the model(``/model``). The default S3 bucket can be found using the ``sagemaker.Session.default_bucket`` method."
+ "Open a new sagemaker session and upload the model on to the default S3 bucket. We can use the ``sagemaker.Session.upload_data`` method to do this. We need the location of where we exported the model from TensorFlow and where in our default bucket we want to store the model(``/model``). The default S3 bucket can be found using the ``sagemaker.Session.default_bucket`` method."
]
},
{
@@ -220,7 +220,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Use the ``sagemaker.mxnet.model.TensorFlowModel`` to import the model into SageMaker that can be deployed. We need the location of the S3 bucket where we have the model, the role for authentication and the entry_point where the model defintion is stored (``iris_dnn_classifier.py``). The import call is the following:"
+ "Use the ``sagemaker.tensorflow.model.TensorFlowModel`` to import the model into SageMaker that can be deployed. We need the location of the S3 bucket where we have the model, the role for authentication and the entry_point where the model defintion is stored (``iris_dnn_classifier.py``). The import call is the following:"
]
},
{
@@ -243,7 +243,7 @@
"source": [
"### Create endpoint\n",
"\n",
- "Now the model is ready to be deployed at a SageMaker endpoint. We can use the ``sagemaker.mxnet.model.TensorFlowModel.deploy`` method to do this. Unless you have created or prefer other instances, we recommend using 1 ``'ml.m4.xlarge'`` instance for this example. These are supplied as arguments. "
+ "Now the model is ready to be deployed at a SageMaker endpoint. We can use the ``sagemaker.tensorflow.model.TensorFlowModel.deploy`` method to do this. Unless you have created or prefer other instances, we recommend using 1 ``'ml.m4.xlarge'`` instance for this example. These are supplied as arguments. "
]
},
{