=> mutationRate := ft / (ft + float64(len(vals)))
for has := false; !has; { // loop until at least one value was modified
for i, o := range opts {
=> if i == 0 || rand.Float64() < mutationRate {
mutationRate is the probability to select each value to mutate. For large N (the number of parameters) it tends to t/N. The extra +t term from t/(N+t) is just so that if N is smaller that T the mutation probability is not >1. mutationRate is somewhere in interval (0, 1).
Second line is basically: do the following with probability mutationRate. rand.Float64() returns a uniformly distributed number between 0 and 1.
I'm still experimenting with it, so I cannot yet report any success. Nevertheless, feel free to experiment with txt and if you find it useful, please consider contributing.
Regards,
After almost a month of testing and tuning I glad to say that zurichess is 40ELO stronger now. I have a few more ideas from Joerg that I'll include in txt.
I'm still experimenting with it, so I cannot yet report any success. Nevertheless, feel free to experiment with txt and if you find it useful, please consider contributing.
Regards,
After almost a month of testing and tuning I glad to say that zurichess is 40ELO stronger now. I have a few more ideas from Joerg that I'll include in txt.
SPSA, which randomly mutates all variables, has some pretty strong theoretical guarantees of convergence even in the presence of noise. It can be slow in the final phases of convergence though.
=> mutationRate := ft / (ft + float64(len(vals)))
for has := false; !has; { // loop until at least one value was modified
for i, o := range opts {
=> if i == 0 || rand.Float64() < mutationRate {
mutationRate is the probability to select each value to mutate. For large N (the number of parameters) it tends to t/N. The extra +t term from t/(N+t) is just so that if N is smaller that T the mutation probability is not >1. mutationRate is somewhere in interval (0, 1).
Second line is basically: do the following with probability mutationRate. rand.Float64() returns a uniformly distributed number between 0 and 1.
Recently you changed a lot of code in your framework, so I wanted to give it another try with Stockfish.
Unfortunately, I get an error message after
I pushed new code. The new version has a simplified mutating algorithm and its simpler to use overall. There is support for saving/loading but there is one small bug that the wrong values are written. I'll try to fix it today.
I cannot give a set of pgn because my file with 200.000 games takes 220MB compressed. However you can generate one with the following script:
Use 2moves_v1.pgn as opening book.
Use a very fast time control to make search less relevant.
Use high timemargin to prevent timeouts at short time control.
Use high concurrency >= number of logical processors.
On my 2 core cpu it took about 1.5 days to generate 200.000 games. I actually used -concurrecy=6 for some of the games.
Big thanks again!
Games at ultrasfast tc have already been played.
I'm still undecided whether to use 'go depth 1' as recommended by original Texel tuning method, or SF's internal 'eval' command (with slightly modified output).
The first will take longer, but i'm not bound to only use quiet positions ...
Joerg Oster wrote:Big thanks again!
Games at ultrasfast tc have already been played.
I'm still undecided whether to use 'go depth 1' as recommended by original Texel tuning method, or SF's internal 'eval' command (with slightly modified output).
The first will take longer, but i'm not bound to only use quiet positions ...
Yesterday I pushed the fix and some slight improvements. Saving/loading is more important than flexibility of setting parameters (e.g. multiple names) so the config file has changed again. I hope it won't change in the near future.
After giving some though I realized why it doesn't work for stockfish. Remember the constant k? It's a scaling factor. The returned values depend highly on the scaling factor. So changing k will give you different values which is why it makes sense to tune all parameters at once.
Joerg Oster wrote:Big thanks again!
Games at ultrasfast tc have already been played.
I'm still undecided whether to use 'go depth 1' as recommended by original Texel tuning method, or SF's internal 'eval' command (with slightly modified output).
The first will take longer, but i'm not bound to only use quiet positions ...
Yesterday I pushed the fix and some slight improvements. Saving/loading is more important than flexibility of setting parameters (e.g. multiple names) so the config file has changed again. I hope it won't change in the near future.
Great stuff!
This plot
is from a still ongoing tuning session with Stockfish, 40 parameters at once.
No sign of convergence so far. And it seems this will take some more hours until there's no further improvement.
And one estimation takes only 6 seconds, and the evaluation of the large set about 70 seconds! (I'm using SFs internal eval command)
Now I wonder how you can get tuned values in 3 - 5 hours ...
Do you have a link to the hill-climbing algorithm you are using?
How do you pick the values from the pool?
brtzsnr wrote:After giving some though I realized why it doesn't work for stockfish. Remember the constant k? It's a scaling factor. The returned values depend highly on the scaling factor. So changing k will give you different values which is why it makes sense to tune all parameters at once.