Roids, simple fun in a simple world

This is my take on neural networks moving around in a simple world that gives feedback. When I started this project I had no idea that "neuroid" was already established and really popular within the neural network field, so I named my creatures "neuroids", or "roids" for short, and created a place for them to exist in.

The neural network in itself is a simple framework that I have written to explore both neural networks and genetic algorithms. I have gone for simplicity to be able to have as much control as possible and this seems to be enough to get networks that can be trained to perform simple tasks. Everything is written in C and I use GTK-1.2 to do the graphics.

The neural network framework

A neural network is constructed with nodes and connections between these nodes. The connections allow propagation of signals and training information and the nodes themselves act as input-, output- and intranodes.

The node has a threshold that dictates when the node is active or inactive. The state of the node changes from inactive to active when the sum of the weighted inputs from the connected nodes is greater than the threshold. The threshold ranges from 0.0 to 1.0 and the sum of the weights for the connected nodes is 1.0 if there is more than one connection. Adding connections to an initialy unconnected node follows a certain pattern regarding wieghts that I think is interesting.
  • If there are no connections, add a connection with a randomized weight in the range 0.0 to 1.0.
  • If there is one connection, with the weight n0, add a connection with the weight 1.0 - n0.
  • For every new connection after the second one, multiply the existing wights with 1.0 - 1.0 / number_of_connections and give the new connection the weight 1.0 - sum_of_existing_weights.
The result is a node with two connections that, on average, are equally influential on the state of the node and the rest are there to add fractions. As far as I know, this is not the conventional way to distribute weights on connections which makes it even more interesting to investigate what will happen.

The nodes are inserted into a structure that, mainly, consists of three sets: in_nodes, out_nodes and nodes. All nodes in in_nodes and out_nodes are also members of nodes. There is also information about which node is connected to which node to facilitate for the genetic algorithms to modify the networks.

Training of a network is done in an as straightforward way as possible by adjusting the weights and/or the threshold of a node to make it more likely to give the desired output in the future with regard to the current distribution of weights in the node and the state of the connected nodes.
  • Determine in what direction the weights and/or the threshold should be changed.
  • Loop through all connections and change the weights in the desired direction on the connections that are connected to an active node.
  • If the weight to be changed is too small or too big (smaller than WEIGHT_CHANGE or bigger than 1.0 - WEIGHT_CHANGE), change the threshold instead.
With this training, a network that, for example, manipulates single characters is easily created using the bits of the character as input.

The roids and the world that they inhabit

With the framework ready it is easy to construct networks that can handle a simple world and react on the stimuli that they are provided with. In this case a fully connected network with 20 inputnodes and 4 outputnodes is present in every roid. The roid will get information about the following:
  • Visual info (food, tree, water, other roid and wall)
  • The distance to the object measured with five intervals and five corresponding inputnodes
  • The health of the roid supplied with ten inputnodes, one for each available hitpoint
The roid can react with the following:
  • Accelerate
  • Decelerate
  • Turn anti-clockwise 0.1 radians
  • Turn clockwise 0.1 radians
Put all this together and you will get something that looks like this:



The 15 red roids move around and they can see eachother, yellow food, green trees and blue water. The border of the inner drawingarea is reported as a wall. To make things a bit more interesting the roids are punished for their existance with regular intervals making it a good thing to find food to be the last living roid and get a shot at propagating your neural network to the next generation. A roid "eats" by passing through food and getting one more hitpoint each time it happens.

When the dust has settled one roid is still alive due to eating more than his fellow roids and thus being able to sustain more beating:


This page was created using emacs and my own two eyes. Some fingers were also involved. Last updated 20040614.