Our new nets output two values for the side to move in the last layer.
We can interpret the first value as a material evaluation of the
position, and the second one as the dynamic, positional value of the
location of pieces.
This patch changes the balance for the (materialist, positional) parts
of the score from (128, 128) to (121, 135) when the piece material is
equal between the two players, but keeps the standard (128, 128) balance
when one player is at least an exchange up.
Passed STC:
LLR: 2.93 (-2.94,2.94) <-0.50,2.50>
Total: 15936 W: 1421 L: 1266 D: 13249
Ptnml(0-2): 37, 1037, 5694, 1134, 66
https://tests.stockfishchess.org/tests/view/
60a82df9ce8ea25a3ef0408f
Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,3.50>
Total: 13904 W: 516 L: 410 D: 12978
Ptnml(0-2): 4, 374, 6088, 484, 2
https://tests.stockfishchess.org/tests/view/
60a8bbf9ce8ea25a3ef04101
closes https://github.com/official-stockfish/Stockfish/pull/3492
Bench:
3856635
int scale = 903 + 28 * pos.count<PAWN>() + 28 * pos.non_pawn_material() / 1024;
- Value nnue = NNUE::evaluate(pos) * scale / 1024;
+ Value nnue = NNUE::evaluate(pos, true) * scale / 1024;
if (pos.is_chess960())
nnue += fix_FRC(pos);
namespace NNUE {
- Value evaluate(const Position& pos);
+ Value evaluate(const Position& pos, bool adjusted = false);
bool load_eval(std::string name, std::istream& stream);
bool save_eval(std::ostream& stream);
void init();
}
// Evaluation function. Perform differential calculation.
- Value evaluate(const Position& pos) {
+ Value evaluate(const Position& pos, bool adjusted) {
// We manually align the arrays on the stack because with gcc < 9.3
// overaligning stack variables with alignas() doesn't work correctly.
ASSERT_ALIGNED(buffer, alignment);
const std::size_t bucket = (pos.count<ALL_PIECES>() - 1) / 4;
-
const auto [psqt, lazy] = featureTransformer->transform(pos, transformedFeatures, bucket);
- if (lazy) {
+
+ if (lazy)
return static_cast<Value>(psqt / OutputScale);
- } else {
+ else
+ {
const auto output = network[bucket]->propagate(transformedFeatures, buffer);
- return static_cast<Value>((output[0] + psqt) / OutputScale);
+
+ int materialist = psqt;
+ int positional = output[0];
+
+ int delta_npm = abs(pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK));
+ int entertainment = (adjusted && delta_npm <= BishopValueMg - KnightValueMg ? 7 : 0);
+
+ int A = 128 - entertainment;
+ int B = 128 + entertainment;
+
+ int sum = (A * materialist + B * positional) / 128;
+
+ return static_cast<Value>( sum / OutputScale );
}
}