Clipper Tutorial: Part 2

In this part of the tutorial, you will put on your data scientist hat and train and deploy some models to Clipper to improve your application accuracy.

Connect to Clipper (again)

Because this is a separate Python instance, you must create a new Clipper object and connect to your running Clipper instance. Make sure you enter the same information here as you did in part one.


In [ ]:
import sys
import os
from clipper_admin import Clipper
# Change the username if necessary
user = ""
# Set the path to the SSH key
key = ""
# Set the SSH host
host = ""
clipper = Clipper(host, user, key)

Load Cifar

Because this is a new notebook, you must load the CIFAR dataset again. This time, you will be using it to train and evaluate machine learning models.

Set cifar_loc to the same location you did in the "Download the Images" section of part one of the tutorial. You will load into Python the number of training and test datapoints specified in "Extract the images" section of part one.


In [ ]:
cifar_loc = ""
import cifar_utils
train_x, train_y = cifar_utils.filter_data(
    *cifar_utils.load_cifar(cifar_loc, cifar_filename="cifar_train.data", norm=True))
test_x, test_y = cifar_utils.filter_data(
    *cifar_utils.load_cifar(cifar_loc, cifar_filename="cifar_test.data", norm=True))

Train Logistic Regression Model

When tackling a new problem with machine learning, it's always good to start with simple models and only add complexity when needed. Start by training a logistic regression binary classifier using Scikit-Learn. This model gets about 68% accuracy on the offline evaluation dataset if you use 10,000 training examples. It gets about 74% if you use all 50,000 examples.


In [ ]:
from sklearn import linear_model as lm 
def train_sklearn_model(m, train_x, train_y):
    m.fit(train_x, train_y)
    return m
lr_model = train_sklearn_model(lm.LogisticRegression(), train_x, train_y)
print("Logistic Regression test score: %f" % lr_model.score(test_x, test_y))

Deploy Logistic Regression Model

While 68-74% accuracy on a CIFAR binary classification task is significantly below state of the art, it's already much better than the 50% accuracy your application yields right now by guessing randomly.

You can deploy your logistic regression model directly to Clipper without having to worry about how to serialize the model or integrate it with application code.

To deploy a model to Clipper, you must assign it a name ("sklearn_cifar"), a version (1), and then provide some metadata about the model itself. In this case, you are specifying that you want to run the model using the sklearn_cifar_container Docker image in the Clipper repo on Docker Hub. You can assign the model descriptive labels, and specify the input type that this model expects. Finally, you can specify how many replicas of the model (how many Docker containers) to launch. Adding more replicas increases the throughput of this model.

After completing this step, Clipper will be managing a new container in Docker with your model in it:

Once again, because you are deploying a Docker image this command may take awhile to download the image. Thanks for being patient!


In [ ]:
model_name = "birds_vs_planes_classifier"

model_added = clipper.deploy_model(
    model_name,
    1,
    lr_model,
    "clipper/sklearn_cifar_container:latest",
    "doubles",
    num_containers=1
)
print("Model deploy successful? {success}".format(success=model_added))

Now that you've deployed your model, go ahead and check back on your running frontend application from part 1. You should see the accuracy rise from around 50% to the accuracy of your SKLearn model (68-74%), without having to stop or modify your application at all!

Load TensorFlow Model

To improve the accuracy of your application further, you will now deploy a TensorFlow convolutional neural network. This model takes a few hours to train, so you will download the trained model parameters rather than training it from scratch. This model gets about 88% accuracy on the test dataset.

There is a pre-trained TensorFlow model stored in the repo using git-lfs. Once you install git-lfs, you can download the model with the command git lfs pull. If you don't want to deploy a TensorFlow model, you can skip this step.


In [ ]:
import os
import tensorflow as tf
import numpy as np
tf_cifar_model_path = os.path.abspath("tf_cifar_model/cifar10_model_full")
tf_session = tf.Session('', tf.Graph())
with tf_session.graph.as_default():
    saver = tf.train.import_meta_graph("%s.meta" % tf_cifar_model_path)
    saver.restore(tf_session, tf_cifar_model_path)

def tensorflow_score(session, test_x, test_y):
    """
    NOTE: This predict method expects pre-whitened (normalized) images
    """
    logits = session.run('softmax_logits:0',
                           feed_dict={'x:0': test_x})
    relevant_activations = logits[:, [cifar_utils.negative_class, cifar_utils.positive_class]]
    preds = np.argmax(relevant_activations, axis=1)
    return float(np.sum(preds == test_y)) / float(len(test_y))
print("TensorFlow CNN test score: %f" % tensorflow_score(tf_session, test_x, test_y))

Deploy TensorFlow Model

Similar to deploying the logistic regression model, you can now deploy your TensorFlow neural network. Note that you will specify a different model container to use this time: the tf_cifar_container. In this case, you are providing Clipper a serialized version of the model. The container has been set up to reconstruct the original model from the serialized representation.

After completing this step, Clipper will send queries to the newly-deployed TensorFlow model instead of the logistic regression Scikit-Learn model, improving the application's accuracy.

Once again, please patient while the Docker image is downloaded.


In [ ]:
model_added = clipper.deploy_model(
    model_name,
    2,
    os.path.abspath("tf_cifar_model"),
    "clipper/tf_cifar_container:latest",
    "doubles",
    num_containers=1
)
print("Model deploy successful? {success}".format(success=model_added))

Inspect Clipper Metrics

Clipper also records various system performance metrics. You can inspect the current state of these metrics with the inspect_instance() command.


In [ ]:
clipper.inspect_instance()

Congratulations! You've now successfully completed the tutorial. You started Clipper, created an application and queried it from a frontend client, and deployed two models trained in two different machine learning frameworks (Scikit-Learn and TensorFlow) to the running system.

Head back to the notebook from part 1. When you're done watching the accuracy of your application, stop the cell (hit the little "stop" square in the notebook toolbar).

This step will stop and remove all Clipper Docker containers running on the host. This command will not affect other Docker containers running on the host machine.

Cleanup

When you're completely done with the tutorial and want to shut down your Clipper instance, you can run the stop_all() command to stop all the Clipper Docker containers.

If you check the accuracy of your frontend application a final time, you should see accuracy around 88%. If the accuracy is below that, you can try sending more feedback to increase the weight on the TensorFlow model even more.


In [ ]:
clipper.stop_all()