Interactive Neural Network Fun in Excel | by Tony Roberts | Towards Data Science

After reading Making deep neural networks paint to understand how they work by Paras Chopra I was inspired to delve into some experiments of my own. The images produced were intriguing, and I wanted to play around and get a feel for how they changed in response to changing the structure of the neural network.
I encourage you to go back and read the original article, but as a brief summary it involves using Compositional Pattern Producing Networks (CPPN) with random weights to produce abstract images. The basic idea is that we construct a function c = f(x,y) that takes the input coordinates of a pixel x,y and returns the colour for that pixel, c using a CPPN.
As in the original article, we’ll use PyTorch to create a CPPN. The following code is the result of lots of work by Paras Chopra and will be our starting point.
Running the above neural network on a 512x512 input array results in an output image as shown below. The neural network is initialised with random weights, and the input array is scaled such that each input is between +0.5 and -0.5.
There are a lot of variables to play with that will affect the resulting image. From the scaling of the inputs, the number of neurons at each stage, and the structure of the neural network itself. We could put this code in a Jupyter notebook and use change the inputs there, but each change we make is a change to the code itself and somehow doesn’t quite feel like a real interactive experience.
Microsoft Excel might seem like an odd choice for an interactive playground for this type of task initially. Bear with me though... What we want to do is enter some information like the number of weights and how many layers, and have a new image presented to us. In essence, Excel simply runs functions when inputs change — and those functions can do anything, even show us an image in Excel! If we could have a worksheet in Excel with the parameters we want to change, and as soon as we make a change have the image update that would be make a great playground for getting a feel for how the inputs affect the output.
Neural networks in Excel might sound like a hard task, but we’re not talking about implementing it in VBA! In fact, we won’t need to go anywhere near VBA as we can continue to use Python instead.
PyXLL is an Excel add-in that embeds the Python runtime into Microsoft Excel. It allows us to write Excel functions entirely in Python, and so we can still use PyTorch for our neural network but all within Excel. Having access to all the Python tools really opens up what is possible with Excel. Rather than having complex logic encoded in VBA, software written in Python is simply exposed to Excel. Excel becomes our front end user interface tool, with Python taking care of the complex computation.
PyXLL is the highest performing and easiest way to write Excel functions entirely in Python, which is perfect for complex workloads. You can download a free 30 day trial from https://www.pyxll.com/download.html.
Our goal is to be able to construct our neural network in Excel and have complete control over the inputs. We’ll start by writing some Python functions and exposing them to Excel. Roughly, the functions we’ll need are:
Create the layers (nn.Linear, nn.Tanh and nn.Sigmoid)Create a neural network from a set of layers (nn.Sequential)Run the neural network on a set of inputs and show the output
Create the layers (nn.Linear, nn.Tanh and nn.Sigmoid)
Create a neural network from a set of layers (nn.Sequential)
Run the neural network on a set of inputs and show the output
At this stage you might be wondering how we are going to represent some of these items in Excel. PyXLL lets us pass Python objects between Excel functions in a workbook, so having a function that returns a Python instance of nn.Linear or another Python function that takes a list of transformation layers is actually very simple. When a Python object is returned to Excel, what we see in Excel is just a handle to the Python object, and when that handle is passed to another Python function PyXLL fetches the object for that handle automatically. PyXLL also manages the life-cycle of these objects so when they are no longer needed they will be cleaned up automatically.
To expose a Python function to Excel we use the @xl_func decorator from the pyxll module. Here are the first functions we need for creating the layers:
The @xl_func decorator is all that’s needed to expose those functions to Excel! The nn_Linear function has type annotations which PyXLL uses to ensure the correct types are passed from Excel to the function, otherwise the numbers passed from Excel might come through as floats.
All that’s needed is to add this module to the PyXLL config file, pyxll.cfg. For example, if your code was written to a Python module named “pytorch_abstract_art.py” in the folder “C:\MyCode\PyTorch-Abstract-Art\Modules”, you would update your pyxll.cfg file with the following settings:
[PYTHON]pythonpath =    C:\MyCode\PyTorch-Abstract-Art\Modules[PYXLL]modules =    pytorch_abstract_art
We can now call these functions from Excel to construct all the layers required required for the neural network. All of the inputs are entered in Excel, and we can even change the number and order of the layers interactively.
To construct the neural network we just need another function that takes these layers and returns the neural network using nn.Sequential. PyXLL can accept arrays of arguments as well as just single values, so we can pass the whole set of layers as a single argument. The @xl_func decorator takes an optional function signature to tell PyXLL more about the argument and return types to expect.
To tell PyXLL to convert the range of cells passed to it into a 1d list of objects we use the object[] type. If we wanted to pass a range as a 2d list of lists of objects instead we could use the object[][] type. When flattening from a 2d range of cells to a 1d list of values PyXLL takes cells from left to right and so the ordering of our layers in the above image will result in the correct arrangement.
We can now add that new function nn_Sequential to our Excel worksheet and pass in the layers created earlier.
The only things remaining now are to create an input set, initialise the weights, and show the resulting image.
To do that we’ll use Excel’s Object Model to manipulate an image in Excel. Excel’s Object Model is exactly what you may have used if you’ve ever written any VBA, but you may not have realised that it can be called from Python just as easily as from VBA! The guide Python as a VBA Replacement explains how to call Excel from Python, and also covers some of the differences between VBA’s syntax and Python.
The final function takes:
The neural network objectThe name of the image object in ExcelScale and offset parameters for the inputsA random seed
The neural network object
The name of the image object in Excel
Scale and offset parameters for the inputs
A random seed
To add the image that will show our result, in Excel click Developer → Insert →Image (Active X Control). To the left of the formula bar you will see the name of the image object. This will default to Image1, but you can edit this to any name you like.
The following code gets the image from Excel, constructs the inputs, computes the outputs and updates the image.
With this final function complete we can now pull it all together. All of the inputs to constructing the neural network are exposed on the sheet, as are the parameters controlling how the input data is created.
We can add or remove layers, edit the number of features at each stage and even switch the activation functions. What’s really fun about this is that everything is in real-time. As soon as we make a change, the image updates.
A couple of functions were left out of the above code to make it easier to read. You can find them below, or you can also get all of the code from the GitHub repo https://github.com/pyxll/pyxll-examples in the pytorch folder.
Playing around with neural networks in Excel in this way has been really interesting and fun. More importantly than that though, it shows how even complex Python tasks can be integrated into Excel seamlessly.
Excel’s strength is as a user-interface tool and, in my opinion, should not be used to store data, algorithms or business logic that can be better managed elsewhere. Anyone who’s used Excel for a while or has worked with a team that depends on Excel know the pain of VBA macros that can’t be tested, version controlled or even be consistent between different users’ workbooks. By moving the code outside of Excel you not only get the huge benefits of a modern language like Python, but you can also apply modern development practices to the code behind your spreadsheets.
While not many people will want to actually construct and train neural networks in Excel, there is still value in being able to access neural networks from Excel. A large part of what makes machine learning useful is the ability to use it to assist decision making. If the decision makers are already using Excel, we can make it easy for them by exposing trained and tested machine learning solutions to them in Excel. This can be a much improved workflow over them using Excel to do some basic calculations, then breaking out to a custom tool or web app (or even worse, emailing someone in the data science group a spreadsheet!), and then putting those results back into Excel — which they will want to do, no matter how good you think your custom tool is ;)
You can download the code and the example workbook from the GitHub repo https://github.com/pyxll/pyxll-examples in the pytorch folder. You will also need PyXLL, which you can download with a 30 day free trial from https://www.pyxll.com/download.html.