Saturday, September 30, 2017

Evolving Neural Network Weights

Neural networks offer quiet a large repertoire of tasks that they can accomplish well. With the increasingly smart solutions people come up with to squeeze out performance with smaller networks(squeezeNet ,ReLu to name a few) it's likely that neural networks will dominate the Machine learning scenario for some time to come.

There is one limitation however. Current implementations of learning mechanisms ([1], [2]) are mostly gradient based. This limits the loss function to being at least differentiable, if not double differentiable in some cases. There are alternatives like reinforcement learning and genetic search but those have not been as heavily invested into by the community as the gradient based methods.

This post explores genetic search as a method for finding the appropriate weights for neural network architectures. We illustrate the basic principles and follow along with some basic code.

Let's look at the XOR problem. One of the classic problems that Minsky famously pointed to in the Perceptron book[3]. The problem is simply to compute the XOR function given two binary inputs. While a single perceptron is unable to do this, a multi layer perceptron is able to perform this computation.

We use a simple 3 layer neural network and sigmoid activation as done in the classic days of neural networks. Instead of using the wonderful powers of Theano, tensorflow or torch to perform automatic differentiation in order to use gradient based methods, we are able to drop those architectures from our program entirely.

We use numpy to make the matrix operations a little easier to read. The first part of the code imports the relevant libraries and defines the sigmoid function to be used later on.

We then define a roulette function which selects elements from a given array with a probability proportional to the magnitude of elements in the array. This is present in this part of the code.

The next bit defines the forward calculation of the network given it's weights and input data. Besides that it also defines a function which calculates the "score" of a given output from the network and the output expected. Here we ask the genetic search to maximize the ROC AUC score.

The get fitness function is another building block which makes use of the functions we have already defined. It takes in a network configuration and returns the "fitness" associated with this configuration. In genetic search terms this network configuration / network weight list is known as the "gene".

To employ genetic search in it's classic form we write two function which emulate gene crossover and mutation. This is the bread and butter of the genetic search algorithm which allows is to move around in the search space.

The last of our function definitions defines the "main" function which evolves network weights to fit on a certain data set that we provide. This data set is the XOR data set that we manufacture using numpy in the later sections of the code.

All that is left is to set the various configuration variables for the genetic search and to call the evolution function with these variables. We see that genetic search very quickly finds the "correct" weights for this neural network. It does get lost sometimes for very long periods of time but that is simply because we have implemented a vanilla version of genetic search.

The entire code is available at https://github.com/theSage21/evonet.

Friday, September 22, 2017

BookReview: Sialkot Saga


This book caught my attention on the railway station book stall as I almost boarded my train. That particular shade of red always draws my eye, as it had previously with Bhim. Particularly lucrative was the thickness of the book which promised to fill the dull hours of the train journey with more interesting scenery.

The work itself was an easy read, the language simple and natural although sometimes I wondered if the characters in the books would actually speak in those terms. Indians have their own set of slangs which could have been more faithfully rendered.

The story itself is engrossing, as all stories filled with crime are. Being illiterate in the current affairs of our country I struggled to put together some of the references of the crimes. Some were fresh in my memory and needed no dab of paint to spring forth, new again from the folds of my memory.

The book felt all too familiar to my world. I could have written it. I would have written it in the exact same way too, since I knew nothing of the streets of Mumbai or Calcutta for that matter. All I've known is what I've read and most of my reading has been in English and by foreign authors.

Towards the end the book took on a fantastic spin of science fiction and hand waved away a lot of the things as being 'quantum' in nature. I must say that good science fiction resides in pockets where science does not know the answer yet. If instead a book tries to claim fiction in a field science does know, it is merely fiction. No grudges held however, seeing as how the book was indeed called fiction.

Reading this book sparked off a strange thought. Books which reinterpret Indian mythology / history and leverage the idea of 'lost science' have become all too common since Amish wrote his Meluha. There's been a spate of these books, all reinterpreting classics with more 'lost knowledge' and better explanations. It reminds me of Hussain Haidry's poem this independence day. The authors too have picked up the saffron fever.