This is a tutorial based on the fast.ai Practical Deep Learning course and their Cats and Dogs Redux

This Jupyter Notebook uses the lein-jupyter plugin to be able to execute Clojure code in
project setting. The first time that you run it you will need to install the kernal with lein jupyter install-kernel.
After that you can open the notebook in the project directory with lein jupyter notebook

The Deep Learning library in Clojure that we are using is called Cortex. This example
borrows heavily from the Resnet-retrain example in the repo.

The goal of this is to take the dataset from the Kaggle Cats and Dogs Redux Competiton
and train a model. We will then run the model on the Kaggle testing data and submit the results to see how we compare.

You will need to do a bit of setup first. Download the train.zip and test.zip from the Kaggle Data page.

Make a /data directory in the project directory and put the train.zip file there and unzip it.

You should now have a directory structure that looks like data/train with inside the directory lots of pictures like cat.156.jpg and dog.1.jpg

The next thing that we need to do is to run the .get-resnet50.sh in the root of the project. What this is going to do is download a pretrained model that is meant to classify 1000 images types from the ImageNet competition. This model and its weights have been translated into a Cortex network format nippy

One of the main things we want to do is take all the images in the data/train directory, shuffle them, and then split them into 85% of the pictures for training and 15% of the pictures for validation testing. We also want to have a directory structure so that only the cat pictures are in the cat directory and dog pictures in the dog directory. Also all of the pictures should be resized to 224x224 to match up with the RESNET model's input, (it's expecting a 224x224 image).

There is a build-image-data function in the cats-dogs namespace that will do this for us.

In [21]:

(cats-dogs/build-image-data)

Building the image data with a test-training split of 0.85
training files 21250 testing files 3750

What it is doing is taking in that resnet50 trained models and chopping off the last layer and setting all the layers to non-trainable so that the training won't spend any time retraining those layers and leave them frozen. Then it tacks on the layers that we want to add which are the linear layer of size 2 for our 2 classes (cat and dog of classifcation) and a softmax activation layer that will return the probalities that the image is a cat or dog with the values summing to 1.

Now we're at a point where we can actually do the training. There is a function called train that takes a batch size. If you are running on your computer, and you have memory problems you can try decreasing the batch size or running the core code as an uber jar to do the training. The default is set to a batch size of 32. Another option is running on a AWS P2 compute instance.

For me to be able to run on my old mac, I need to run the uberjar.

If you want to do the uber jar:

lein uberjar

java -jar target/cats-dogs-cortex-redux.jar

Using the GPU on my mac it takes approximately 6 minutes to train 1 epoch Note: 1 epoch of fine tuning is all we need

Now we can test out things a bit. There is a label-one function that grabs a random image and classifies it

Note a window will popup with a the dog or cat picture in it

In [2]:

(cats-dogs/label-one)

Out[2]:

{:answer "dog", :guess {:prob 0.9978577494621277, :class "dog"}}

Step 3 - Run the Kaggle test predictions and get it into csv submission format¶

You will need to do a bit more setup for this. First, you need to get the Kaggle test images for classification. There are 12500
of these in the test.zip file from the site. Under the data directory, create a new directory called kaggle-test. Now unzip
the contents of test.zip inside that folder. The full directory with all the test images should now be:

data/kaggle-test/test

This step takes a long time and you might have to tweak the batch size again depending on your memory. There are 12500 predications to be made. The main logic for this is in function called (kaggle-results batch-size). It will take a long time to run.
It will print the results as it goes along to the kaggle-results.csv file. If you want to check progress you can do wc -l kaggle-results.csv