Deploying a Medical Time Series Model using Zeppelin Notebooks and SKIL

Over the last five years, we have witnessed a sharp increase in the volume, detail, and availability of digital health data. Driven in large part by the adoption of electronic health records (EHRs) at hospitals and clinics, these data promise a wellspring of insights about health and illness. Researchers have made substantial progress in modeling complex clinical data with advanced techniques, including deep learning, but this is not the only barrier to improving patient care at the bedside: once a model is trained and validated, it must then be deployed and integrated with clinical software, a challenge that can prove more formidable than training a deep neural network!

The Skymind Intelligence Layer (SKIL) helps software engineers overcome deployment barriers by easing the transition from model training to model deployment. In How To Predict ICU Mortality with Digital Health Data, DL4J, Apache Spark and Cloudera, we showed how to train a long short-term memory recurrent neural network (LSTM RNN) to model risk of mortality among intensive care unit (ICU) patients, using the publicly available Physionet Challenge 2012 data set. Here we will teach you how to use Zeppelin notebooks and SKIL to build, train, evaluate, and deploy a similar model. Finally, you will learn how to set up a client application to query mortality risk scores for new patients via a REST API.

We will assume that SKIL has already been installed and that the reader has some knowledge about using SKIL. For material that goes into more in depth about these topics, check out our quick start on SKIL and a previous blog post on building an experiment by importing a notebook.

Setting up a SKIL Workspace

To start, we need to set up a new workspace using the SKIL user interface (UI) by clicking on the workspaces tab. The UI will show a list of previous workspaces. To create a new workspace click on the “Create Workspace” button on the top left.

Screen-Shot-2018-02-07-at-2.55.50-AM

Setting up a SKIL Experiment

Once the new workspace is set up, we'll create a new experiment for our medical time series task. For this example, we will use the workspace named “test.” We can then select this new workspace and then click on the “New Experiment Button” at the top right. The interface should then show something similar to the screenshot below:

Screen-Shot-2018-02-07-at-2.56.57-AM

Creating a New Experiment

You can then name the experiment “Medical Time Series Experiment," input the appropriate Model History Server Id and Zeppelin Server Id, and import the Zeppelin notebook from your local device. The Zeppelin notebook used is available on Github and can be found here. The interface should now show something like this.

Screen-Shot-2018-02-07-at-2.58.38-AM

Running Code

Next, click on the “Open Notebook” button. The UI should now show the Zeppelin notebook. Click on the "run" button next to the name of the notebook to run all the paragraphs of the notebook. Note that the code for downloading and preparing the data is already included as part of the notebook. For more information on the basic architecture of the model we train in this notebook, look at our guide on RNNs and LSTMs.

After each paragraph runs the code it contains, the output of the code will appear similar to what is shown below.

Screen-Shot-2018-02-07-at-3.01.48-AM

Once the deep learning model is created, we need to deploy the model to the SKIL server. First, add the newly created model to the SKIL experiment. To do this, we can first create a SkilContext within the Scala notebook.

Screen-Shot-2018-02-07-at-3.03.52-AM

To save the model, we can use the method addModelToExperiment of the SkilContext class.

Screen-Shot-2018-02-07-at-3.03.23-AM

SKIL Model

Once these lines of code are run, we can look at the model in SKIL. Simply scroll up to the top of the page containing the Zeppelin notebook and click on the Models tab. We should then see a list of models similar to what is shown below.

Screen-Shot-2018-02-07-at-3.05.31-AM

Click on the newly created model to see the evaluation results again. Using this UI, it's easy to compare different models using SKIL and choose the best model to deploy.

Creating a SKIL Deployment

To deploy the model, click on the deploy button on the top right, which will prompt a deployment wizard. Go through the wizard to create a deployment, which is defined to be a group of models, transforms, and KNN endpoints.

Screen-Shot-2018-02-07-at-3.06.27-AM

We can now see the deployment after clicking on the Deployments tab on the left menu.

Screen-Shot-2018-02-07-at-3.07.04-AM

Querying the Model Server for Mortality Risk via REST

The example for querying the model server is contained in this Java client, and the code is available here. To run the client application, first use Maven to build and package the JAR file. This JAR file will be used to send an example to the model server for classification.

More specifically, run the mvn package command in the directory SKIL_Examples/skil_clinical_lstm_app/client_app. This command will create a JAR file called skil-example-clinical-lstm-1.0.0.jar in the target directory of the project.

Client Code

The code for sending an example data file to the model server via the REST API is contained here. It is similar to the client code in a previous blog post.

The Authorization class should be used to send a username and password to the model server and obtain an authorization token to use in the classification REST request. This involves sending the token and the base64-encoded bytes via a REST POST request.

Screen-Shot-2018-02-07-at-11.57.13-AM

The next bit of code loads a CSV file by its local URI, converts the features into an INDArray and finally base64-encodes the bytes for REST transport.

Screen-Shot-2018-02-07-at-11.58.15-AM

For more information on using the SKIL client API check out this post.

Running the Client Code

Now we will go through how to send an example data file to the SKIL model server via REST. We will assume that SKIL is running locally and the model we created earlier has been deployed. Additionally, we will assume that the model endpoint address is http://localhost:9008/endpoints/test/model/lstm/default/

The command needed for sending a data file to the SKIL model server is shown below.

java -jar ./target/skil-example-clinical-lstm-1.0.0.jar --feature [feature file location] --label [label file location] --endpoint [skil endpoint URI]

Once this is finished running, the console should return an output similar to what is shown below.

Screen-Shot-2018-02-12-at-4.36.16-PM

We see that for this example, the model predicts that this particular patient has a 72 percent chance of survival.

Conclusion

One of the largest barriers to deriving value from machine learning (ML) in clinical and other enterprise settings is the handoff from data science to production deployment.

We have shown how SKIL provides a single environment in which to create, analyze, and deploy models for production quickly and easily, easing this handoff. We used a Zeppelin notebook to build, train, and evaluate an LSTM that models risk of mortality among hospitalized patients. We then deployed the trained neural net to the SKIL model server with only a handful of clicks and queried mortality risk predictions for new patients via a REST API.

For more details on the setting and model architecture, we recommend reading the previous article on training an LSTM to predict mortality using DL4J, Spark, and Cloudera Hadoop.

You can visit the Deeplearning4j documentation page to read more about RNNs and LSTMs. Finally, you can get started right away by visiting the SKIL Community Edition download page.