A Neural Network To Learn Aesthetics
In Richard Dawkins' The Blind Watchmaker, the author introduces the concept of biomorphs, which are simple tree-like things, the particular design of which is controlled by a small set of genes that specify various general parameters about the biomorphs, and the user selects the one they prefer, which is used as the parent of the next generation. There are demonstrations of this online.
Note that this simple example of evolution is entirely mutation-driven, there is no crossover involved.
The plan here is for a version of this that has a more complex genotype for the biomorph themselves, allowing them to evolve into a more complex form, and also to have a neural network that trains itself based on the users selections, and then takes over the selection process.
The point of this is to see how well a neural network can end up learning the 'aesthetics' of a persons selections.
The genotype described by Richard Dawkins is a very simple one. It has something like nine genes which still allows for a fairly varied collection of biomorphs. However, I'd like to go for something more complex, that allows all kinds of tree-based structures to be drawn that do things like allow asymmetry, and having each fork being described in the genotype, rather than a high-level specification of the whole structure. To do this, there will be three genotype strings per biomorph. An index string, an angle string, and a length string. The index string consists of a series of pointers into the appropriate parts of the angle and length strings. When the genotype is being converted into a phenotype, the first step is to dereference the index string by scanning through it, and pulling in the value that is pointed to in the appropriate string. An example series of strings may look something like:
The index is processed in a pattern of angle, length, angle, length,.... The decoded version is:
A length of 0 indicates that this branch doesn't exist, and so has no children.
This then converts into the actual biomorph using the following algorithm:
- Create an initial point to start the tree from, add this to a queue
- Pull a point from the queue
- Read the next two values from the decoded genotype
- If length <> 0
- Create a child branch of the angle and length specified
- Add the endpoint of this branch to the queue
- If the queue is not empty, and there are still values in the decoded genotype, goto step 2
The reason for the 3-part genotype is to encourage, but not enforce, symmetry. If the L and R pairs are pointing to the same place in the index and/or angle strings, then alteration of them will not result in breaking the symmetry of the biomorph.
More technical details to come