Integrating Deep Learning With clojure.spec
clojure.spec allows you to write specifications for data and use them for validation. It also provides a generative aspect that allows for robust testing as well as an additional way to understand your data through manual inspection. The dual nature of validation and generation is a natural fit for deep learning models that consist of paired discriminator/generator models.
TLDR: In this post we show that you can leverage the dual nature of clojure.spec’s validator/generator to incorporate a deep learning model’s classifier/generator.
A common use of clojure.spec is at the boundaries to validate that incoming data is indeed in the expected form. Again, this is boundary is a fitting place to integrate models for the deep learning paradigm and our traditional software code.
Before we get into the deep learning side of things, let’s take a quick refresher on how to use clojure.spec.
quick view of clojure.spec
To create a simple spec for keywords that are cat sounds, we can use s/def
.
1
|
|
To do the validation, you can use the s/valid?
function.
1 2 |
|
For the generation side of things, we can turn the spec into generator and sample it.
1 2 |
|
There is the ability to compose specs by adding them together with s/and
.
1 2 3 |
|
We can also control the generation by creating a custom generator using s/with-gen
.
In the following the spec is only that the data be a general string, but using the custom generator, we can restrict the output to only be a certain set of example cat names.
1 2 3 4 5 6 7 8 9 |
|
For further information on clojure.spec, I whole-heartedly recommend the spec Guide. But, now with a basic overview of spec, we can move on to creating specs for our Deep Learning models.
Creating specs for Deep Learning Models
In previous posts, we covered making simple autoencoders for handwritten digits.
Then, we made models that would:
- Take an image of a digit and give you back the string value (ex: “2”) - post
- Take a string number value and give you back a digit image. - post
We will use both of the models to make a spec with a custom generator.
Note: For the sake of simplicity, some of the supporting code is left out. But if you want to see the whole code, it is on github)
With the help of the trained discriminator model, we can make a function that takes in an image and returns the number string value.
1 2 3 4 5 6 7 8 |
|
Let’s test it out with a test-image:
1
|
|
Likewise, with the trained generator model, we can make a function that takes a string number and returns the corresponding image.
1 2 3 4 |
|
Giving it a test drive as well:
1 2 3 4 |
|
Great! Let’s go ahead and start writing specs. First let’s make a quick spec to describe a MNIST number - which is a single digit between 0 and 9.
1 2 3 4 5 |
|
We now have both parts to validate and generate and can create a spec for it.
1 2 3 4 5 6 |
|
The ::mnist-number
spec is used for the validation after the discriminate
model is used. On the generator side, we use the generator for the ::mnist-number
spec and feed that into the deep learning generator model to get sample images.
We have a test function that will help us test out this new spec, called test-model-spec
. It will return a map with the following form:
1 2 3 4 |
|
It will also write an image of all the sample images to a file named sample-spec-name
Let’s try it on our test image:
1 2 3 4 5 6 7 |
|
Pretty cool!
Let’s do some more specs. But first, our spec is going to be a bit repetitive, so we’ll make a quick macro to make things easier.
1 2 3 4 5 6 7 |
|
More Specs - More Fun
This time let’s define an even mnist image spec
1 2 3 4 5 6 7 8 9 10 |
|
And Odds
1 2 3 4 5 6 7 8 9 10 |
|
Finally, let’s do Odds that are over 2!
1 2 3 4 5 6 7 8 9 10 |
|
Conclusion
We have shown some of the potential of integrating deep learning models with Clojure. clojure.spec is a powerful tool and it can be leveraged in new and interesting ways for both deep learning and AI more generally.
I hope that more people are intrigued to experiment and take a further look into what we can do in this area.