Self-Organizing Maps with fast.ai — Step 5: Interpretation on a trained Self-Organizing Map

Riccardo Sayn
Kirey Group
Published in
4 min readJan 19, 2021

This is the fifth and final part of the Self-Organizing Maps with fast.ai article series.

All the code (now updated to Fastai version 2) has been published in this repository and this PyPi library.

Previous parts

Step 1: Implementing a SOM with PyTorch

Step 2: Training the SOM Module with a Fast.ai Learner (with loss functions)

Step 3: Updating SOM hyperparameters with Fast.ai Callbacks

Step 4: Handling unsupervised data with Fast.ai DataBunch

SOM weights visualization (we’re going to build this)

In the previous articles, we’ve been laying the foundation for a stable implementation of a SOM training pipeline. By leveraging Fastai high-level APIs for data loading and processing, we were able to load mixed continuous/categorical datasets, customize training behavior and “hack” the SOM gradient-free back-propagation algorithm into the training loop.

For our last step, we’re going to build a set of visualization tools inspired to Fastai ClassificationInterpretation APIs (click here for Fastai V1, here for V2).

Self-Organizing Maps are all about displaying information, as they can be used to better understand data clusters and feature correlation with those groups. In this chapter, we will implement a SomInterpretation class with a set of handy visualization methods.

Let’s get started!

Anakin Skywalker (GIPHY)

1. Writing the base class

First of all, we need to define a SomInterpretation class. We’re going to receive the SomLearner as a constructor parameter, and we will also define a factory method to mimic the ClassificationInterpretation API.

SomInterpretation constructor + factory

We can then create a new instance by using:

As it stands now, our new class has no methods, so we’d better start writing some visualization functions!

Note that all the examples shown in this post are from the RGB color dataset found in this Jupyter Notebook in the code repo.

2. Visualizing the SOM as a heatmap

Being essentially 2D grids, SOMs are easily displayed as such. By displaying the number of elements that fall under each codebook node, we can quickly get a glimpse at the distribution and diversity in our dataset.

To do this, we will run model predictions over a given ds_idx; this way we can decide whether to visualize train, valid or test data.

Then we invoke our new method, obtaining the image below:

BMU hit counts

2. Visualizing SOM weights

While the information provided in the hitmap above is useful, we might want some kind of visualization that is even simpler and that could provide a high-level understanding of the uniformity of the dataset.

SOM codebook unit approximate real data points, as it happens in some clustering algorithms; we can exploit a three-dimensional PCA to visualize them as a picture consisting of RGB-colored squares.

RGB weights visualization

As before, we just implemented a neat one-liner that will produce the image below:

SOM codebook encoded as RGB

The result above is really smooth as it was obtained with a dataset of uniformely-distributed float triplets that resembles the RGB color space, but this will work with any data shape.

4. Visualizing SOM features

All the visualizations we’ve built so far are aggregating the codebook data in some way, but we can also see what’s happening to each feature.

By visualizing the feature values over the 2D grid and comparing with the other visualizations, we can understand how certain features are related with the class distribution on the map.

Yet again, one line of code to rule them all:

R / G / B single channel values in the codebook

Wrapping up

That’s it! With the model interpretation now complete, the set of SOM tools is ready to be used and experimented with.

The DataBunch “hacking” section in chapter 4 was especially hard and I had to simplify it a bit to keep things short in the blog post, but if you’re interested you can have a look at the code in the Github repo.

I’m really happy with how the project turned out, and I feel it helped me a lot in understanding how both PyTorch and Fastai work. If you want to learn these libraries, I’d recommend you to pick an idea (be it a neural network architecture, some kind of visualization or whatever you like), write a basic implementation and then think about other features and changes you could add to make your code better.

What I like the most about Fastai is the clear separation of concerns that they were able to obtain in a deep learning framework. By leveraging callbacks, we managed to keep the SOM implementation separated from things such as hyperparameter scaling, training loop, data preparation and output visualization.

I already have some ideas for upcoming features to explore:

  • More categorical encoding strategies (e.g. embeddings)
  • Different hyperparameter scaling strategies
  • Visualizations for target classes for SOMs trained on supervised tasks

In case you’re interested in the library and/or have some ideas about how it could be improved, be sure to open a feature request 😄

--

--