I got private explanations from Ronald Friederich, author of engines rofChade and PeSTO via PM here on talkchess.mvanthoor wrote: ↑Thu Jan 07, 2021 12:41 pm Congratulations
Where did you find the explanation with regard to Texel tuning, and the millions of games to test against? Or, did you get all the explanation needed by PM and created the test data yourself by (for example) scraping lichess games?
I'd be _very_ much interested in a video about this topic, because I feel that evaluation function tuning is something I just can't get my head around properly. Maybe I'm just missing some details. Writing a Texel tuner (for me) seems infinitely more complex than understanding and writing a magic bitboard engine.
I'd love to implement Texel tuning as one of the first features after the transposition table, so I can use it right from the beginning, even when only using PST's. I'm wondering how much Texel tuning could improve the PST's. (It'll probably compensate for a huge lack of knowledge, at least in the beginning. For example, having the rook on the 7th line is now in the PST, instead of being a discrete parameter.)
Initially I've asked him to share his PeSTO (3098) material weights and PST serving the ONLY evaluation.
PeSTO tables worked worse compare to rofChade's tables for me which is surprising because rofChade's eval also includes
some additional params apart from material and PST.
Then I asked about Texel's tuning and Ronald provided me pseudo code, see first page of this thread.
Then he explained some core details.
First I tried FEN positions with results from Ethereal data dump thread.
Then I've generated my own from pgn2600.pgn, see this thread: http://talkchess.com/forum3/viewtopic.php?f=7&t=76251
The most difficult for me was to get the understanding of pipeline flow:
1. generate dataset (from self play or external source like in my case) - fen string followed by result of the game
2. loop over all positions (people loop over millions, I tried no more than 10000 for my code is slow as hell)
3. evaluate() or quiescence() position depending if it's tactical (I removed tactical positions on dataset generation to use eval() for it's faster)
4. convert scalar eval value, say 25 to probabilistic using sigmoid, say it would be 0.75
5. get error for every position, e.g. win is 1.0 draw is 0.5 loss is 0.0, so for 0.75 error would be 1.0 - 0.75 = 0.25
6. Sum all the errors (for all positions) and divide by the number of positions - mean square error
And then justt loop over all the eval parameters.
Adjust first by one.
Recalculate mean square error (this is so damn long if many positions, hence optimizations like using gradient decent are involved).
If mean square error didn't get minimized - decrement parameter by one and recalculate mean square error.
So if we drop the particular implementation - Texel's using is all about calculating mean square error and changing eval parameters.
(material weights, opening/endgame phase margins, PST for opening/endgame - around 794 params in total for me)
I'm definitely going to make an extended video explanation on this very soon.
Understanding of method's essence open opportunities for customizations depending on your goals.
For now now you can have a look and even run my implementation: https://github.com/maksimKorzh/wukongJS ... eval_tuner
it takes initial_weights.json as input
then while script is running eval params are changing
as the output it generates javascript code that I later copypaste into my engine, see /temp_weights folder
I'm going to alter the original method for Wukong JS to obtain material weights/PST from scratch (from 0 values)
and then document it within a project repo and also make a video.
It still needs lots of testing.
