lightvector / KataGo

GTP engine and self-play learning in Go
https://katagotraining.org/
Other
3.55k stars 565 forks source link

Is it worth using NNUE to replace FPU? #379

Closed CGLemon closed 1 year ago

CGLemon commented 3 years ago

An efficiently updatable neural network(NNUE) is pretty great ideal to improve the traditional chess engine. The result is the stockfish significant strong. It won TCEC season 18 and season 19.

Obviously, the NNUE adaption of the Go is not good ideal because there are more possible moves. But I think that it is an opportunity to use NNUE to replace FPU. Its computation time is very short. It can provide rough value for non-expansion nodes.

Is it worth doing that?

lightvector commented 3 years ago

Have you considered about how NNUE works and do you have a serious proposal for how to make it work here?

It has very little to do with the number of possible moves. It's more about the fundamental nature of the game. In Chess it works for the same reason that hand-crafted evaluation functions work: we know that even extremely simple and shallow features (e.g. material values and simple piece-square and piece-piece relationships) can already provide a decent evaluation of the game. So at least in retrospect, it's not too surprising that a shallow neural net can do well.

Think about it in Go. How is a shallow neural net supposed to correctly judge the life and death status of a large dragon in the late midgame using only shallow features? There are a large number of possible patterns for eyes and partial eyespace values too numerous to exactly enumerate all the possibilities, and you have to trace that information all the way across the board (the eyes may be far apart) through a whole bunch of shapes that you have to judge whether they are connected or not (bamboo joints, hanging connections, etc), which are also too numerous to enumerate. I don't currently see how it can be done in just a few layers of incrementally-updatable features. Connectivity is fairly sharp/discrete and behaves like a very long conjunctive formula in even the simplest case - A is connected to a distant J only if there exists B,C,D,... in between such that A connects to B, B connects to C, C to D, and so on, and if anything in the chain breaks, then the whole thing breaks. It feels like a thing where you really do need many steps, with a nonlinearity potentially every step, not easily reducible to something almost-linear over shallow features.

Even if all you need is to compute FPU rather than an accurate evaluation, it seems likely to be worthless if you can't judge large group status - a dragon being live or unsettled or dead is the difference between 1% winrate and 99% winrate, or the difference between a move there being the biggest move on the board, versus a waste of ko threats or even death in gote.

Do you have a proposal for what incremental architecture or feature set would be able to learn a set of topological connection shapes and trace them accurately across a large board, one that would work with the limited functional form that you would be able to obtain from 2-3 neural net layers plus a choice of nonlinearity? (Edit: or, a proposal in mind for how you would do incremental updates for a non-shallow net?)

CGLemon commented 3 years ago

This is my mistake to ignore that the shallow network is difficult to evaluate the accurate value. In my original ideal, the Network is same ideal as the NNUE but changing the fully-connect to convolution in order to adapt itself to different board size. Finally, it will evaluate the final score of current player. But the value-based evaluation is seldom on Go even before the AlphaGo. The most methods are policy-based that because value-based evaluation based either nn-like or handicraft is hard to evaluate accurate value. And knowing that the Leela's 12-Conv network did not evaluate the accurate value either. I thought it is stupid idea that NNUE applied to Go.

After all, Thank you for your proposal.

Smooshy30 commented 1 year ago

HalfKP for Shogi was something like 170k inputs For 2-stone relations, HalfPP on a 19x19 Go board is 361*360=129960 inputs, with the weights used for both sides (probably a lot less if we account for duplicate 2-stone relations; [triangular number of 360] = 64980) Inputs for 3-stone relations are out of the question, due to sheer increase in memory size of the network (~46 million inputs) Hard to say if it will be practical to implement with such limitations