Skip to content

Commit e2372a9

Browse files
committed
Introduce Optimism
Current master implements a scaling of the raw NNUE output value with a formula equivalent to 'eval = alpha * NNUE_output', where the scale factor alpha varies between 1.8 (for early middle game) and 0.9 (for pure endgames). This feature allows Stockfish to keep material on the board when she thinks she has the advantage, and to seek exchanges and simplifications when she thinks she has to defend. This patch slightly offsets the turning point between these two strategies, by adding to Stockfish's evaluation a small "optimism" value before actually doing the scaling. The effect is that SF will play a little bit more risky, trying to keep the tension a little bit longer when she is defending, and keeping even more material on the board when she has an advantage. We note that this patch is similar in spirit to the old "Contempt" idea we used to have in classical Stockfish, but this implementation differs in two key points: a) it has been tested as an Elo-gainer against master; b) the values output by the search are not changed on average by the implementation (in other words, the optimism value changes the tension/exchange strategy, but a displayed value of 1.0 pawn has the same signification before and after the patch). See the old comment official-stockfish/Stockfish#1361 (comment) for some images illustrating the ideas. ------- finished yellow at STC: LLR: -2.94 (-2.94,2.94) <0.00,2.50> Total: 165048 W: 41705 L: 41611 D: 81732 Ptnml(0-2): 565, 18959, 43245, 19327, 428 https://tests.stockfishchess.org/tests/view/61942a3dcd645dc8291c876b passed LTC: LLR: 2.95 (-2.94,2.94) <0.50,3.00> Total: 121656 W: 30762 L: 30287 D: 60607 Ptnml(0-2): 87, 12558, 35032, 13095, 56 https://tests.stockfishchess.org/tests/view/61962c58cd645dc8291c8877 ------- How to continue from there? a) the shape (slope and amplitude) of the sigmoid used to compute the optimism value could be tweaked to try to gain more Elo, so the parameters of the sigmoid function in line 391 of search.cpp could be tuned with SPSA. Manual tweaking is also possible using this Desmos page: https://www.desmos.com/calculator/jhh83sqq92 b) in a similar vein, with two recents patches affecting the scaling of the NNUE evaluation in evaluate.cpp, now could be a good time to try a round of SPSA tuning of the NNUE network; c) this patch will tend to keep tension in middlegame a little bit longer, so any patch improving the defensive aspect of play via search extensions in risky, tactical positions would be welcome. ------- closes official-stockfish/Stockfish#3797 Bench: 6184852
1 parent f5df517 commit e2372a9

File tree

4 files changed

+46
-9
lines changed

4 files changed

+46
-9
lines changed

src/evaluate.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,11 +1091,15 @@ Value Eval::evaluate(const Position& pos) {
10911091
v = Evaluation<NO_TRACE>(pos).value(); // classical
10921092
else
10931093
{
1094-
int scale = 898
1095-
+ 24 * pos.count<PAWN>()
1096-
+ 33 * pos.non_pawn_material() / 1024;
1094+
int scale = 898
1095+
+ 24 * pos.count<PAWN>()
1096+
+ 33 * pos.non_pawn_material() / 1024;
10971097

1098-
v = NNUE::evaluate(pos, true) * scale / 1024; // NNUE
1098+
Value nnue = NNUE::evaluate(pos, true); // NNUE
1099+
Color stm = pos.side_to_move();
1100+
Value optimism = pos.this_thread()->optimism[stm];
1101+
1102+
v = (nnue + optimism) * scale / 1024 - optimism;
10991103

11001104
if (pos.is_chess960())
11011105
v += fix_FRC(pos);

src/misc.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,33 @@ class ValueList {
138138
std::size_t size_ = 0;
139139
};
140140

141+
142+
/// sigmoid(t, x0, y0, C, P, Q) implements a sigmoid-like function using only integers,
143+
/// with the following properties:
144+
///
145+
/// - sigmoid is centered in (x0, y0)
146+
/// - sigmoid has amplitude [-P/Q , P/Q] instead of [-1 , +1]
147+
/// - limit is (y0 - P/Q) when t tends to -infinity
148+
/// - limit is (y0 + P/Q) when t tends to +infinity
149+
/// - the slope can be adjusted using C > 0, smaller C giving a steeper sigmoid
150+
/// - the slope of the sigmoid when t = x0 is P/(Q*C)
151+
/// - sigmoid is increasing with t when P > 0 and Q > 0
152+
/// - to get a decreasing sigmoid, call with -t, or change sign of P
153+
/// - mean value of the sigmoid is y0
154+
///
155+
/// Use <https://www.desmos.com/calculator/jhh83sqq92> to draw the sigmoid
156+
157+
inline int64_t sigmoid(int64_t t, int64_t x0,
158+
int64_t y0,
159+
int64_t C,
160+
int64_t P,
161+
int64_t Q)
162+
{
163+
assert(C > 0);
164+
return y0 + P * (t-x0) / (Q * (std::abs(t-x0) + C)) ;
165+
}
166+
167+
141168
/// xorshift64star Pseudo-Random Number Generator
142169
/// This class is based on original code written and dedicated
143170
/// to the public domain by Sebastiano Vigna (2014).

src/search.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,10 @@ void Thread::search() {
334334

335335
nodesLastExplosive = nodes;
336336
nodesLastNormal = nodes;
337-
state = EXPLOSION_NONE;
338-
trend = SCORE_ZERO;
337+
state = EXPLOSION_NONE;
338+
trend = SCORE_ZERO;
339+
optimism[ us] = Value(25);
340+
optimism[~us] = -optimism[us];
339341

340342
int searchAgainCounter = 0;
341343

@@ -381,11 +383,14 @@ void Thread::search() {
381383
alpha = std::max(prev - delta,-VALUE_INFINITE);
382384
beta = std::min(prev + delta, VALUE_INFINITE);
383385

384-
// Adjust trend based on root move's previousScore (dynamic contempt)
385-
int tr = 113 * prev / (abs(prev) + 147);
386-
386+
// Adjust trend and optimism based on root move's previousScore
387+
int tr = sigmoid(prev, 0, 0, 147, 113, 1);
387388
trend = (us == WHITE ? make_score(tr, tr / 2)
388389
: -make_score(tr, tr / 2));
390+
391+
int opt = sigmoid(prev, 0, 25, 147, 113, 2);
392+
optimism[ us] = Value(opt);
393+
optimism[~us] = -optimism[us];
389394
}
390395

391396
// Start with a small aspiration window and, in the case of a fail

src/thread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class Thread {
6868
int selDepth, nmpMinPly;
6969
Color nmpColor;
7070
ExplosionState state;
71+
Value optimism[COLOR_NB];
7172

7273
Position rootPos;
7374
StateInfo rootState;

0 commit comments

Comments
 (0)