Advertisement

Genetic Algorithm

Started by September 12, 2006 07:42 AM
25 comments, last by sharpnova 18 years, 2 months ago
Hey! Quit skulking around, fup!! 8^)

BTW, PacMan lives. I have it running currently with the animation working and only need to link up the controls. Once I have that done, I'll start putting NEAT to work. I PROMISE!! My goal is the end of the year (preferably the next month or two - we'll see how much time I have). You still have exclusive license.

Sorry for the aside...

-Kirk
Actually, it doesn't even have to be a very complex mapping. Here's a simple method.

Instead of thinking binary coded GAs, if you think real coded GA, then it would be more feasible. There are a few ways to approach this once it's real coded. The most straight forward way would be to encode probability values for the 4 directions it can move in. So, you might have N:35%, S:15%, E:45%, and W:5%. That's the simplistic way. Then you expand on that. Since you have a 5x5 grid of visibility, you can then create 4 slightly overlapping sectors that represent each direction. Based on the number of food and other animals in the sector, you multiple those two values by weights. To determine the probability of going in a direction, you simply add the weights and divide the weight of a sector by the total. So, for example, if there's nothing in any given sector, you start out with a base weight of 100. Now if we see that there's 1 food in the N, and the weight for food in the north is 2, then the weight for going north become 102. If there's a food in the south and another animal, and the weight for food and animal are 3 and -5, then the weight for the south becomes 98. So, there will be a total of 8 weights to evolve for the GA, a set of 2 for each direction. Then its just how you want to cap these values to create interesting behavior.

Just a quick idea.
Advertisement
I would do a NN with the input neurons as the visibility grid (5x5 or even more). but you should have 1 input for 1 characteristic meaning 1 input for (food there/not there) and 1 for (other creature there/not there). perhaps adding predaters is simply adding another input neuron (per grid field). you could add some static obstacles too...
so you'll have 5x5x2 input neurons (in case of predators added 5x5x3). then you can choose a number of hidden layer neurons which are connected to the every input neuron. and then you have the 4 output neurons which are connected to every hidden layer neuron.
that's your basic NN setup. with the GA you would use the weights on every neuron2neuron connection as the genetic information. you could encode to binary or even let the GA operate on floats (yeah thats possible ;) ).

when you're calculating which instances of creatures(/genetic information) you should use for the next generations, you let the creatures handle with their individual genetic information filled in the NN that's driving their behaviour. simply counting how much food was eaten by each creature after N cycles and then sort by that amount and you get the X first creatures (and their information) for mutation etc...

and if you like somewhat more realistic behaviour, I would add a sort of timestamps to your NN. meaning you could add some input neurons that show the last N states, the creature was in or what the creature did the last time (moved in x direction/didn't move)


let's assume you have a visibility field of 5x5, on the grid tiles there can be (nothing, another creature, food, predator, wall) you would need 4 neurons per field (for example 0100 -> creature; 0000 -> nothing; i think you get the idea), making 5x5x4 input neurons. adding 4 neurons for the last action (nothing(0000), moved north(1000), south(0100),..) you'll have 5x5x4+4=104 neurons in the input layer. then choosing a number for your hidden layer neurons, say 10 (I don't have an idea what number is good, you have to try ;) ). making 104*10 connections from input to hidden layer, plus 10*4 connections from hidden layer to output. you have 1080 connections (floats!) to store in your genetic information per each creature. thats an incredible amount but I think these creatures will behave very good after enough epochs of GA.

ok perhaps this is all overkill *g* but you get the idea... simply choose the characteristics you need and play a little bit, till you get "intelligent" results
quick question.

why isn't it just 5x5 inputs? if i'm using floats couldn't the input just be 0 for nothing, 1 for creature 2 for food, 3 for wall, etc.?

actually i already realized the answer to that while typing this... i was going ot have one input per square and use 0 for nothing 1 for creature etc. then in the connection, the weight was going to depend on whether it was 0,1,2,3... in other words.. same amount of overhead as just using 4 input neurons..

and yes i was planning on having predators, walls, (i am going to have the predators evolving as well) and the previous states, i think i mentioned alrady in this thread. i'm going to have all the input neurons necessary to input all the information for the past states (but not past actions.. i'm going to disregard those.. as i think forward planning is behavior.. but basing it on past actions is pointless since a new situation may have a new optimal behavioral response)


i'll be working on this for awhile :p








IMPORTANT QUESTION:

i've read evolution is far slower than back propogation.. but since i have no idea what my target output or target behavior is here.. there is no way for error calculations.. or back propogation.. am i correct in this or not understanding back propogation?
Everyone hates #1.That's why a lot of idiots complain about WoW, the current president, and why they all loved google so much when it was new.Forget the fact that WoW is the greatest game ever created, our president rocks and the brainless buffons of America care more about how articulate you are than your decision making skills, and that google supports adware, spyware, and communism.
The main reason not to have a single input neuron with 0,1,2,3 for empty, food, wall, creature is that in this situation the various states of a cell have a relative weight with respect to each other. I originally suggested -1,0,1 for creature, empty, and food based on the idea that a creature being present is a bad thing, empty is arbitrary, and food is a good thing. This relative weighting makes sense in this context, but when you add in walls, it doesn't work very well. The neural net will have an extremely hard time trying to decide how to assign weights and may never converge.

The idea propsed by haemonculus sounds like a good one, however, you will end up with a huge number of weights that need to be adjusted and this will take a very long time. The best idea is to simplify the inputs as much as possible without losing information.

You're right about backpropagation. You have to know what your target output is to be able to use it. In this case, all you know is good or bad results. This is an example of reinforcement learning.

-Kirk
Quote: Original post by sharpnova
i've read evolution is far slower than back propogation.. but since i have no idea what my target output or target behavior is here.. there is no way for error calculations.. or back propogation.. am i correct in this or not understanding back propogation?


That's right -- this is the exact situation where you should be evolving. If there's no way of creating stimulus-response pairs, you can't really use backprop.

Of course, that's not quite true, as people have tried to find some ways of doing this. You can take a look at a thread I started, http://www.gamedev.net/community/forums/topic.asp?topic_id=411372 which, while it doesn't contain any concrete answers, at least has some good ideas for search terms to do some research on this.

However, that's for a slightly different situation. This is classic A-Life, and thus using a GA is apropriate.
Advertisement
Quote: Original post by kirkd
The main reason not to have a single input neuron with 0,1,2,3 for empty, food, wall, creature is that in this situation the various states of a cell have a relative weight with respect to each other.


which is solved by having a different weight for each possible state.. or 4 neurons.

main reason i like 4 neurons is so i can stick to bit operations.. which are probably way faster than floats.
Everyone hates #1.That's why a lot of idiots complain about WoW, the current president, and why they all loved google so much when it was new.Forget the fact that WoW is the greatest game ever created, our president rocks and the brainless buffons of America care more about how articulate you are than your decision making skills, and that google supports adware, spyware, and communism.
Quote: Original post by sharpnova
Quote: Original post by kirkd
The main reason not to have a single input neuron with 0,1,2,3 for empty, food, wall, creature is that in this situation the various states of a cell have a relative weight with respect to each other.


which is solved by having a different weight for each possible state.. or 4 neurons.


Yes, that was my point. The only down side is the very large number of weights that this method leads to.

Quote:
main reason i like 4 neurons is so i can stick to bit operations.. which are probably way faster than floats.


I'm not sure I'm clear on this one. Even if you have bits as your inputs, you're weights are FP adjustable parameters.

-kirk

well i just meant for the very bottom level, the inputs. or should i just use floats for everything?
Everyone hates #1.That's why a lot of idiots complain about WoW, the current president, and why they all loved google so much when it was new.Forget the fact that WoW is the greatest game ever created, our president rocks and the brainless buffons of America care more about how articulate you are than your decision making skills, and that google supports adware, spyware, and communism.
Bits will save memory if that's an issue, but if they are being multiplied by floats than they will probably be changed to floats and then multiplied and that isn't any faster. If you were to do something like: if(input[a].out())node+=weight[a] ;
it might be a little faster than:
node+=input[a].out()*wieght[a] ;
However, I'd still suggest using all floats so the code is more portable. I have a set of neural net and other AI classes I use for lots of things. So if I were doing this I would use all floats just because I already have the code written. My point is: if you plan on doing much with neural nets it's a good idea to make code that is general purpose.

This topic is closed to new replies.

Advertisement