3

I trained my model in Amazon-SageMaker and downloaded it to my local computer. Unfortunately, I don't have any idea how to run the model locally.

The Model is in a directory with files like:

image-classification-0001.params
image-classification-0002.params
image-classification-0003.params
image-classification-0004.params
image-classification-0005.params
image-classification-symbol.json
model-shapes.json

Would anyone know how to run this locally with Python, or be able to point me to a resource that could help? I am trying to avoid calling the model using the Amazon API.

Edit: The model I used was created with code very similar to this example.

Any help is appreciated, I will award the bounty to whoever is most helpful, even if they don't completely solve the question.

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
walker_4
  • 433
  • 1
  • 7
  • 21
  • Did you use MXNet to train the models? – SRC Mar 08 '18 at 16:43
  • I don't believe so unless it was used somewhere in Amazon's backend. The model I used was created with a script very similar to this example: https://github.com/awslabs/amazon-sagemaker-examples/blob/master/introduction_to_amazon_algorithms/imageclassification_caltech/Image-classification-fulltraining.ipynb – walker_4 Mar 08 '18 at 22:12
  • I'm not set up with sagemaker to test, but I think the answer you're looking for might be in the [sdk README](https://github.com/aws/sagemaker-python-sdk). It looks like there is a [models.get_model](https://github.com/aws/sagemaker-python-sdk#model-serving) command listed immediately above the linked section and then the python calls to use the loaded model below that. – Seth Rothschild Mar 09 '18 at 06:06

3 Answers3

4

This is not a complete answer as I do not have SageMaker setup (And I do not know MXNet) and so I can not practically test this approach (yes, as already mentioned, I do not want to call this a complete answer rather a probable pointer/approach to solve this issue).

The Assumption -

You mentioned a that your model is very similar to the notebook link you provided. If you read the text in the notebook carefully, you will see at some point there is something like this -

"In this demo, we are using Caltech-256 dataset, which contains 30608 images of 256 objects. For the training and validation data, we follow the splitting scheme in this MXNet example."

See the mention of MXNet there? Let us assume that you did not change a lot and hence your model is built using MXNet as well.

The Approach -

Assuming what I just mentioned, if you go and search in the documentation of AWS SageMaker Python SDK you will see a section about serialization of the modules. Which again, by itself, starts with another assumption -

"If you train function returns a Module object, it will be serialized by the default Module serialization system, unless you've specified a custom save function."

Assuming that this is True for your case, further reading in the same document tells us that "model-shapes.json" is a JSON serialised representation of your models, "model-symbol.json" is the serialization of the module symbols created by calling the 'save' function on the 'symbol' property of module, and finally "module.params" is the serialized (I am not sure if it is text or binary format) form of the module parameters.

Equipped with this knowledge we go and look into the documentation of MXNet. And Voila! We see here how we can save and load models with MXNet. So as you already have those saved files, you just need to load them in a local installation of MXNet and then run them to predict the unknown.

I hope this will help you to find a direction to solve your problem.

Bonus -

I am not sure if this also can do the same job, (it is also mentioned by @Seth Rothschild in the comments) but it should, you can see that AWS SageMaker Python SDK has a way to load models from saved ones as well.

SRC
  • 2,123
  • 3
  • 31
  • 44
  • Thanks for the advice, I will try to work it out through the docs. Would you have any insight into what iteration would mean in this example in the mxnet docs? `# save a model to mymodel-symbol.json and mymodel-0100.params prefix = 'mymodel' iteration = 100 model.save(prefix, iteration) # load model back model_loaded = mx.model.FeedForward.load(prefix, iteration)`? Is is specific to the FeedForward model? – walker_4 Mar 09 '18 at 23:44
  • As I mentioned, I do not know MXNet but looking into docs and poking around thereafter, I come to the belief that it may be checkpoint iteration number. Your model possibly ran on a 400 iteration and after each 100 you saved the params. So you have 4 params files. Also you can check [this SO](https://stackoverflow.com/questions/47190614/how-to-load-a-trained-mxnet-model) answer for a little bit more context about the module level save and load. – SRC Mar 10 '18 at 08:37
  • Thanks! Was able to get it to work, thanks to your help. I will type up an answer on what I did. – walker_4 Mar 10 '18 at 21:30
  • Great to know that :) Pleased that I could help. Happy modeling! – SRC Mar 11 '18 at 14:49
3

Following SRC's advice, I was able to get it to work by following the instructions in this question and this doc which describe how to load a MXnet model.

I loaded the model like so:

lenet_model = mx.mod.Module.load('model_directory/image-classification',5)
image_l = 64
image_w = 64
lenet_model.bind(for_training=False, data_shapes=[('data',(1,3,image_l,image_w))],label_shapes=lenet_model._label_shapes)

Then predicted using the slightly modified helper functions in the previously linked documentation:

import mxnet as mx
import matplotlib.pyplot as plot
import cv2
import numpy as np
from mxnet.io import DataBatch

def get_image(url, show=False):
    # download and show the image
    fname = mx.test_utils.download(url)
    img = cv2.cvtColor(cv2.imread(fname), cv2.COLOR_BGR2RGB)
    if img is None:
         return None
    if show:
         plt.imshow(img)
         plt.axis('off')
    # convert into format (batch, RGB, width, height)
    img = cv2.resize(img, (64, 64))
    img = np.swapaxes(img, 0, 2)
    img = np.swapaxes(img, 1, 2)
    img = img[np.newaxis, :]
    return img

def predict(url, labels):
    img = get_image(url, show=True)
    # compute the predict probabilities
    lenet_model.forward(DataBatch([mx.nd.array(img)]))
    prob = lenet_model.get_outputs()[0].asnumpy()

    # print the top-5
    prob = np.squeeze(prob)
    a = np.argsort(prob)[::-1]

    for i in a[0:5]:
       print('probability=%f, class=%s' %(prob[i], labels[i]))

Finally I called the prediction with this code:

labels = ['a','b','c', 'd','e', 'f']
predict('https://eximagesite/img_tst_a.jpg', labels )
Vineeth Chitteti
  • 1,454
  • 2
  • 14
  • 30
walker_4
  • 433
  • 1
  • 7
  • 21
0

If you want to host your trained model locally, and you are using Apache MXNet as your model framework (as you have in the above example), the simplest way is to use MXNet Model Server: https://github.com/awslabs/mxnet-model-server

Once you installed it locally, you can start serving using:

mxnet-model-server \ --models squeezenet=https://s3.amazonaws.com/model-server/models/squeezenet_v1.1/squeezenet_v1.1.model

and then call the local endpoint with the image

curl -O https://s3.amazonaws.com/model-server/inputs/kitten.jpg curl -X POST http://127.0.0.1:8080/squeezenet/predict -F "data=@kitten.jpg"

Guy
  • 12,388
  • 3
  • 45
  • 67