maksimKorzh wrote: ↑Thu Oct 15, 2020 6:59 pmCan you please clarify the code:
Well, with comments (and expanded to do all layers) it would roughly look like this
Code: Select all
// in MakeMove():
piece = board[from];
victim = board[to];
board[from] = EMPTY;
board[to] = piece;
for(i=0; i<256; i++) { // for all cells in layer 1
if(IsKing(piece)) {
int sum=0;
king[stm] = to; // New king location; stm = 0 (white) or 1 (black)
for(s=0; s<64; s++) { // for all board squares
int p = board[s]; // get the piece on it
sum += KPST[i][to][p][s]; // add its KPST score to the total
}
layer1[i + 256*stm] = sum; // this is the board's PST eval for the new King location
} else { // other than King, update incrementally
for(j=0; j<2; j++) { // for both players
int k = king[j]; // get their King's location
layer1[i+256*j] -= KPST[i][k][piece][from]; // update the PST eval incrementally
layer1[i+256*j] += KPST[i][k][piece][to];
layer1[i+256*j] -= KPST[i][k][victim][to];
}
}
}
for(i=0; i<32; i++) { // for all cells in layer 2
int sum = 0; // prepare calculating their input for cell i
for(j=0; j<512; j++) { // for each of the cells in layer 1
sum += weights1[i][j] * layer1[j]; // add its weighted output to the input
} // we now have the total input of cell i in layer 2
layer2[i] = max(0, sum); // calculate its output
}
for(i=0; i<32; i++) { // for all cells in layer 3
int sum = 0; // prepare calculating their input for cell i
for(j=0; j<32; j++) { // for each of the cells in layer 2
sum += weights2[i][j] * layer2[j]; // add its weighted output to the input
} // we now have the total input of cell i in layer 3
layer3[i] = max(0, sum); // calculate its output
}
int eval = 0; // prepare calculating the evaluation score
for(j=0; j<32; j++) { // for each of the cells in layer 3
sum += weights3[j] * layer3[j]; // add its weighted output to the input
} // we now have the total input the final cell
// which just outputs it unmodified
This glosses over some hairy details in the first (KPST) layer, such as that the KPST for white and black really need to be each other's mirror images, but should give you roughly an idea of what is going on. BTW, KPST stands for King-Piece-Square Table, because it is indexed by king location, piece type and square location. They are similar to PST, but you use a different one for each King location. So that you can award larger bonus for pieces close to a King. In Shogi this is very important, as Shogi games are usually a race to mate in an all-out King attack. Defense is a losing strategy there, instead you counter-attack and hope to be faster at it.
questions:
1. How can I initialize weights1?
By loading it with the net you want to run. Presumably reading that from a file, and writing the numbers you read in the corresponding elements. Of course if you want to create (train) your own network, this is an entirely different matter. The code I gave is just for running an engine that uses a given network.
2. weights1 is 2 dimensional array here, what values I need in 1st and 2nd indices when I define array? // e.g. weights1[?][?]
The weights represent the 'strength' with which the output of a cell in layer 1 contributes to the input of a cell in layer 2. The indices are the cell numbers.
3. same question for layer1 amd and layer2 (I only understand that NNUE has 4 layers but that's rocket science to me)
The layer arrays hold the output of all the cells in that layer. (To be used as input for the next layer.)
Could you please provide the code the would be doing following(or give a link on implementation):
1. Init everything needed from "*.nnue" file with weights
I have no idea. For that you would have to know in what order Stockfish stores the weights of the net in the file. This is no doubt documented somewhere, but I am not interested in looking it up.
2. then I guess the code you've already provided
Indeed; that code was for calculating layer 2 from layer 1.
3. And then somehow magically obtain a score
The new code shows this for all the layers. The magical score is obtained by the last loop in that code, just the weighted sum of all the outputs of the cells in layer3.