wagenaartje / neataptic

:rocket: Blazing fast neuro-evolution & backpropagation for the browser and Node.js
https://wagenaartje.github.io/neataptic/
Other
1.19k stars 279 forks source link

Support for Minimal Fitness Function #52

Open codyseibert opened 7 years ago

codyseibert commented 7 years ago

I'm trying to implement sum of absolute differences as my fitness function; therefore, the minimal value returned is the "best" fit. It seems like this library doesn't support these typical well known distance formulas inside the fitness function by default; I'm having to do something like this in order for it to perform as expected:

return 10 - sum;

which seems hacky. Additionally, if I change the 10 to Number.MAX_VALUE, it doesn't seem like I get good results any more (which I assume is to some internal error threshold or something)

Is there a good reason as to why the neat fitness function doesn't default to the minimal value to support all the well known distance formulas by default?

I noticed that once upon a time this sort method used to be reversed in a way that I would think is expected: https://github.com/wagenaartje/neataptic/commit/69b44b8f475e3dcfce8eb1e4c544ff83668d8c92#diff-447d2789045ed8b6b82edba48b3301b6L65

@wagenaartje

wagenaartje commented 7 years ago

You are a right, the goal of all distance/error functions is to minimize their value. The built-in Network.prototype.evolve function tries to minimize the error on a certain dataset. A simple workaround is used:

return -sum;

As negative fitnesses are supported by Neataptic. From my perspective, I think it is quite logical that a 'fitness function' should return a higher value if a genome performs better (thus is 'fitter').

I think this is just a matter of personal preference. If more people bring this up then I will reverse the sort function, but still, this would create some problems with selection.FITNESS_PROPORTIONATE.

I could also create a seperate option when constructing the Neat instance where you can specify if you want to minimize or maximize the value of the fitness function.

codyseibert commented 7 years ago

Thanks for the work around suggestion! I didn't even think about negating the absolute sum result. Thank you for dedicating your time towards working on this project.

I think your argument makes sense. For example, let's say you want to write a fitness function which maximizes the amount made in a stock market trade. You want the network which has the greatest value. But, in another example, let's say you want a network to predict a position on an image; it would make sense to have your fitness function sum to zero be the maximum.

At the very least, I'd say document that the current implementation of the fitness function expects a maximum value to be the "most fit". (maybe I just skipped over that part in the docs, but I didn't read anything like that)

wagenaartje commented 7 years ago

Exactly. It depends on the problem. For some problems it is easy to define a maximum score (e.g. distance = 0) but not a minimum score and for some problems it is easy to define a minimum score (e.g. goals scored = 0) but not a maximum score.

I have added this extra info in the develop branch (https://github.com/wagenaartje/neataptic/commit/7fc2cb4d1cf5d73d898aa0e9932c3ac13781ad23) and it will be build soon. I hope that makes a little clearer. I still might implement an option that allows the choice for minimize/maximize score. Thanks for the appreciation :smile: