A Lazy Girl's Guide to Setting Up Jupyter on EC2 for Deep Learning

TL;DR: I describe how I set up a Jupyter server on EC2 with a Marketplace AMI (so we don’t have to install too much stuff ourselves) so we can speed up the training of our NN without leaving the convenient workflow of a Jupyter notebook.

Jupyter logo

Getting started with deep learning is quite easy these days given all the available material out there. I got inspired to build my first convolutional neural network for sentiment analysis after reading this paper by Kim (2014) and attending a PyData meetup with a keras demo (more about this maybe in another post).

Given the experimental nature of my enterprise I started out directly in a Jupyter notebook running locally on my Mac. However, after building more and more layers with more and more filters and starting to tune the hyperparameters for my networks, I noticed that the training time is starting to slow me down. Hence, it was time to move to an AWS EC2 machine with a dedicated GPU to speed up my experiments. In the following I will describe the steps I took to get to the point of training a NN with keras in a Jupyter notebook running on an EC2 instance.

Prerequisites: I assume in this post you already know how to set up an EC2 instance with your credentials so that you can access the instance once it has booted up. I also assume you know how to work with virtual environments for Python and you know the general workflow of installing Python packages. If not you can easily find some articles explaining the purpose of virtual environments.

1. Launch an EC2 Instance With a Suitable AMI

Choosing the right AMI (Amazon Machine Image) will save us a lot of installation effort and time. Since our goal is to do some deep learning, I suggest looking for an AMI that comes with the deep learning library of your desire. In my case I wanted to use either tensorflow or keras with a tensorflow backend. Some searching in the AWS Marketplace reveals that Amazon’s Deep Learning AMI and Bitfusion Ubuntu 14 TensorFlow AMI are nice options. In the end I opted for the Amazon AMI and installed keras myself (see next step). Jupyter is also already preinstalled on both.

AWS Marketplace Screenshot

(If you are not sure yet which libraries you will need, you can also use a vanilla Linux AMI and install everything you need later on the command line. But since this is the lazy girl’s guide we want to spend as little time as possible on installation of tools.)

After choosing the AMI we also need to choose the right instance type. Reasonable choices are the g2 and p2 instances, both of which have dedicated GPUs. I opted for a p2 machine, since they are newer and basically designed for the best deep learning performance.

We need to create a new security group with some specific rules as we want to be able to access the Jupyter server from our browser via HTTPS later on. The following rules will be added to the security group.

Type Protocol Port Range Source
Custom TCP Rule TCP 8888

All of the steps described above can be summarised in the following CLI commands if you don’t want to go through the launch wizard in the web console:

# create security group 
aws ec2 create-security-group --group-name JupyterSecurityGroup --description "My Jupyter security group"

# add security group rules 
aws ec2 authorize-security-group-ingress --group-name JupyterSecurityGroup --protocol tcp --port 8888 --cidr
aws ec2 authorize-security-group-ingress --group-name JupyterSecurityGroup --protocol tcp --port 22 --cidr
aws ec2 authorize-security-group-ingress --group-name JupyterSecurityGroup --protocol tcp --port 443 --cidr

# launch instance 
aws ec2 run-instances --image-id ami-41570b32 --count 1 --instance-type p2.xlarge --key-name <YOUR_KEY_NAME> --security-groups JupyterSecurityGroup

ami-41570b32 is the identifier for the Deep Learning AMI in the eu-west-1 region. The launch command will return a bunch of information about the new instance. Find the InstanceId in the output (somewhere in the bottom). Using this instance id we can find out the public IP address and DNS name of our machine with the following command. We will use this later to access the machine. (Or browse through the EC2 overview in the web console to find the same information.)

aws ec2 describe-instances --instance-ids <INSTANCE_ID> 

2. Set up the Environment on the Remote Machine

Let’s ssh to the instance using its DNS name.

ssh -i <PATH_TO_PEM>

As is common practice with Python we will do everything from within a virtual environment (even though it’s probably not necessary here since this machine only has one purpose, namely to run our notebook). I will use Anaconda as my environment management tool but you can choose any tool of your choice as long as you know how to use it. With the preinstalled Anaconda distribution I will activate the default environment named root:

source src/anaconda3/bin/activate root

Note that I activated the Anaconda 3 default environment, which by default uses Python 3.5. If you prefer to use Python 2.7 (but why?), you can do the same thing with the preinstalled Anaconda 2 distribution in src/anaconda2.

Let’s make sure that we are indeed using the correct binaries by checking the following:

> which python
> which pip
> which jupyter

Here we can see that we are actually not using the jupyter in our environment. This can be fixed by prepending to the PATH variable. Open ~/.bash_profile and change the PATH definition to the following:

export PATH

Now let’s source the updated .bash_profile:

source ~/.bash_profile

Verify that you are now using the correct jupyter.

> which jupyter

Now it’s time to install keras, which is very straightforward with to do with pip. You can skip this step if you don’t require any additional libraries, or you can install some custom libraries of your own.

pip install keras

3. Configure the Jupyter Server

We will now generate the configuration file for our Jupyter server. Since we are using HTTPS we have to create a certificate first. We will use Python to generate a key based on a password you can choose for yourself. We will tell the server that this password will be required to access the notebooks.

Or: just execute the commands given below, follow the instructions on the command line (for the very lazy ones: you can also leave all the prompts empty) and things will just magically work.

jupyter notebook --generate-config
key=$(python -c "from notebook.auth import passwd; print(passwd())")
cd ~
mkdir certs
cd certs
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.key -out mycert.pem
cd ~
sed -i "1 a\
c = get_config()\\
c.NotebookApp.certfile = u'$certdir/mycert.pem'\\
c.NotebookApp.keyfile = u'$certdir/mycert.key'\\
c.NotebookApp.ip = '*'\\
c.NotebookApp.open_browser = False\\
c.NotebookApp.password = u'$key'\\
c.NotebookApp.port = 8888" .jupyter/

4. Run the Jupyter Server

Before starting the server, it is advisable to use some kind of session management tool to keep the server running after a user logout. I usually use screen but here also you can choose whichever tool you like.

screen -S jupyter
mkdir notebook
cd notebook
jupyter notebook

If you want to test the server with a notebook of yours immediately, now would be a good time to copy a notebook over to the server with scp. If you don’t have one at hand, you could copy an example notebook that I prepared. This notebook builds a very standard CNN for the MNIST dataset and reaches 99% accuracy on a test set after 12 training epochs.

git clone 
scp -i <PATH_TO_PEM> keras-example-notebook/Vanilla+CNN+on+MNIST+dataset.ipynb

Your Jupyter server should now be accessible in your browser with this URL: https://<your-instances-public-ip>:8888. And if you’ve copied the notebook over to the EC2 instance, you should be able to run your notebook now in the browser.

Jupyter notebook overview screenshot

5. Have Fun Experimenting with NNs

The only thing I still had to do is to make keras use tensorflow as the backend library by modifying the config file ~/.keras/keras.json (you have to create it if it isn’t already there). Or just stick with the theano backend, which is also already installed.

    "image_dim_ordering": "tf",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "tensorflow"

The first time you import keras, the console should tell you which backend you are currently using as well as some output indicating that you are using the GPU via CUDA (if not, try importing keras in the Python interpreter).

We’re done! Have fun experimenting with your NNs!

Share this: