
Amy de Buitléir
I'm implementing a cyclic neural network. At time t, each neuron will update its output based on the outputs (at time t-1) of the neurons that it's connected to. It will also update the weights for its connections according to some learning rule, and it may destroy a connection or create a new one.
So far, the best way I can think of to do this is to have a master list of neurons, and each neuron would know the indices for the other neurons it connects to. I'd write a function to update the neuron (actually returning a "new" neuron), and then do a "map" over the list with that function.
That seems OK, but I wonder if there's a better way. I suspect the State monad could be used for this, but I can't figure out how to put the pieces of the puzzle together. Here's what I was thinking: - A connection could be a State monad, where the state is the source neuron and the current weight, and the result would be the weighted input. - A neuron could also be a State Monad, where the state is a list of connections, and the result is the neuron's output.
When using a State monad, the state is going to be your entire network together with all neurons and connection weights. At least this is how I have done it some time ago. Just use something like an IntMap and give the neurons unique names. Then you can use something like this: type NeunetT = StateT NeuralNetwork learn :: Monad m => [(Vector Double, Vector Double)] -> NeunetT m Double or: run :: Monad m => Vector Double -> NeunetT m (Vector Double) A very different, probably more elegant approach to implement ANNs is to use functional reactive programming. The 'elerea' library seems to be suitable for this.
I've read dozens of monad tutorials, but I can't figure out how to trigger all the neurons to update themselves. Is the State Monad appropriate for this problem?
A State monad just encodes functions of the following type: s -> (a, s) Unlike a regular function, it passes the state around implicitly. Instead of accessing function arguments, you 'get' the state. You change the state not by returning a new state, but by using the 'set'/'put' functions. You get a mutable variable-like interface to the state, but under the hood you really just encode a function of the above type. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/