First success with neural nets
Posted: Thu Sep 24, 2020 12:16 am
I've been playing around with neural nets recently, which I was totally new to, and managed the first result that I'd consider a success.
I trained a rook and pawns endgame neural net to be used by the dev version that is +3 elo versus the the non-neural net evaluation in rook endgames. However it should be much stronger once I do some of the possible speed optimizations as it could probably be around 3 times faster than it is now.
Initially I was surprised at how simple the concept of using a neural net to compute a value was once I understood how they are usually structured. First actual implementation of this was pretty quick too. It really is just some weights and biases, and multiplications and sums (and usually densely connected with a weight from each input to output.)
Training a neural net proved a far tougher task. I started with my own training code and after finding some issues (one example : don't initialize with all weights with the same value) it worked to some extent. I could match piece square table values in a test. But training was slow, and with more layers and more complicated values didn't reduce error in the way it should have. So at this point I downloaded tensorflow and exported the training data in an inputs and target file, then imported the weights back. It did turn out easier to have already debugged and optimized training, out of curiosity I may go back and try to make my own work and use it, but it does seem likely that tensorflow would just be better in every way except the import/export workflow step.
Once I made a generalized neural network class, I setup a neural net structure that used the pieces on the board directly as input features, and has 4 layers for rook endgames. As inputs I started with 64 rook squares, 64 king squares, 48 pawn squares, all 0 or 1 depending on if occupied.
I filtered some games to get an epd of about 10000 rook endgame starting positions, and ran some matches of Slow 2.3 versus itself, exported the training data scored based on game result, and trained a net with 176 inputs x 256 x 64 x 32 x 1.
I was surprised at how much error was reduced.
First try was -458 elo versus the base. Obviously massively overfit and too little data. Imported with data from the games played and retrained, got -425 elo, then -401, then -358. As expected error was going up as amount of training data increased.
It was at this point where I realized I had a very bad bug... I was actually setting the total inputs to 176 instead of 352, so it was only seeing the white side of the board this whole time.
I corrected this and was at -170 elo. Then I optimized the first layer to only do the calculation if the inputs were non-zero which for rook endgames was a 2.5x speed increase, and was at -111 elo. More training and horizontal symmetry (32 squares for white king, rest of board flipped depending on side) -88 elo.
more training and side-to-move input -70 elo. Reduced the net size, and faster memory layout for inputs -55 elo. After this it was basically just more training, and increasing positions per game seemed to help too, was better to have more data and worry less it would be too similar.
-43, -38, -28, -20, -14, -7, and finally +3. I'm up to 1.5 million training positions at this point.
Why rook endgame : I wanted to experiment in a smaller setting, since I'm new to neural nets, starting from scratch in all aspects (except use of tensorflow.)
Rook endgames are also the most common endgames, and I figured starting from the endgame and working back might be a reasonable method.
Right now I'm using floating points with some SIMD. I estimate it could be about 3 times faster if I change to 16-bit fixed point with SIMD and add incremental updates for changing inputs on the first layer. After optimization I might play with net size and inputs to see if what works best.
This is just rook and pawns endgames and not enough testing and a workflow that needs improvement, so don't expect any new version of Slow Chess any time soon. Also it might still be overfit and not do as well in with other positions and opponents. But it seems likely that the method could yield significant gains eventually.
I trained a rook and pawns endgame neural net to be used by the dev version that is +3 elo versus the the non-neural net evaluation in rook endgames. However it should be much stronger once I do some of the possible speed optimizations as it could probably be around 3 times faster than it is now.
Initially I was surprised at how simple the concept of using a neural net to compute a value was once I understood how they are usually structured. First actual implementation of this was pretty quick too. It really is just some weights and biases, and multiplications and sums (and usually densely connected with a weight from each input to output.)
Training a neural net proved a far tougher task. I started with my own training code and after finding some issues (one example : don't initialize with all weights with the same value) it worked to some extent. I could match piece square table values in a test. But training was slow, and with more layers and more complicated values didn't reduce error in the way it should have. So at this point I downloaded tensorflow and exported the training data in an inputs and target file, then imported the weights back. It did turn out easier to have already debugged and optimized training, out of curiosity I may go back and try to make my own work and use it, but it does seem likely that tensorflow would just be better in every way except the import/export workflow step.
Once I made a generalized neural network class, I setup a neural net structure that used the pieces on the board directly as input features, and has 4 layers for rook endgames. As inputs I started with 64 rook squares, 64 king squares, 48 pawn squares, all 0 or 1 depending on if occupied.
I filtered some games to get an epd of about 10000 rook endgame starting positions, and ran some matches of Slow 2.3 versus itself, exported the training data scored based on game result, and trained a net with 176 inputs x 256 x 64 x 32 x 1.
I was surprised at how much error was reduced.
First try was -458 elo versus the base. Obviously massively overfit and too little data. Imported with data from the games played and retrained, got -425 elo, then -401, then -358. As expected error was going up as amount of training data increased.
It was at this point where I realized I had a very bad bug... I was actually setting the total inputs to 176 instead of 352, so it was only seeing the white side of the board this whole time.
I corrected this and was at -170 elo. Then I optimized the first layer to only do the calculation if the inputs were non-zero which for rook endgames was a 2.5x speed increase, and was at -111 elo. More training and horizontal symmetry (32 squares for white king, rest of board flipped depending on side) -88 elo.
more training and side-to-move input -70 elo. Reduced the net size, and faster memory layout for inputs -55 elo. After this it was basically just more training, and increasing positions per game seemed to help too, was better to have more data and worry less it would be too similar.
-43, -38, -28, -20, -14, -7, and finally +3. I'm up to 1.5 million training positions at this point.
Why rook endgame : I wanted to experiment in a smaller setting, since I'm new to neural nets, starting from scratch in all aspects (except use of tensorflow.)
Rook endgames are also the most common endgames, and I figured starting from the endgame and working back might be a reasonable method.
Right now I'm using floating points with some SIMD. I estimate it could be about 3 times faster if I change to 16-bit fixed point with SIMD and add incremental updates for changing inputs on the first layer. After optimization I might play with net size and inputs to see if what works best.
This is just rook and pawns endgames and not enough testing and a workflow that needs improvement, so don't expect any new version of Slow Chess any time soon. Also it might still be overfit and not do as well in with other positions and opponents. But it seems likely that the method could yield significant gains eventually.