SPSA under review: no proven better method

Listen to this post11 min

Created by AI from the text of this post and read by the synthetic voice “Sulafat”; not a word-for-word version, and it may contain errors.

Coherent sets numerical values of its search, such as pruning margins, reductions and extensions, with SPSA. At the operator's request, three model families checked independently on 2026-10-26 whether there is a better tuning method. In addition there is a model calculation on which values should be kept after a tuning. All Elo Strength difference to the opponent, estimated from the games, with a 95-percent half-width where the oracle reported one. Never an absolute rating. numbers in this post are model Elo from a simulation, not a measurement of playing strength.

How SPSA works

Schematic; the numbers in the footer are those of the model calculation in this post. Perturb: Each parameter gets a random sign. θ+ shifts it by the perturbation radius in that direction, θ− equally far in the opposite direction.; Duel: θ+ plays θ−: pairs of games with colours swapped. Counted: wins minus losses.; Step: Each duel contributes towards the version that scored better there, more for a clearer result. The sum is applied after the batch.; repeat; perturbation radius and learning factor decrease, the radius down to c. In the model every tuning runs twice, independently, from the same start. An end rule then decides per parameter: Filter: Both runs shift it in the same direction, each by at least 0.5·c: then the mean, else the start value.; Seed mean: Always the mean of both runs.; Seed mean with |T| ≥ 1: The mean if the test statistic T over both runs reaches |T| ≥ 1, else the start value.. Our implementation computes in the form of Fishtest, the testing platform of Stockfish. Model calculation: 30 parameters, 500 duels of 30 game pairs per run, updates after batches of 15 duels (the last batch has 5); c = final perturbation radius.
One SPSA step and three end rules (schematic)

Is there a better method?

The search was for a method that yields more playing strength with the same number of games, or the same strength with clearly fewer games. The operator's condition: a replacement must be provably at least as reliable as SPSA. Two families worked with web search, one without network access.

MethodGames needed compared with our SPSA formBasis
CMA-ES1.25 to 5 timesestimate in one review
Bayesian optimisationat least 15 times; more than 200,000 gamesrule of thumb from the documentation of a chess tuning tool, in one review; estimate in a second
CLOPclearly more; its quadratic model has 496 coefficients for 30 parametersestimate in one review
2SPSAat least 2 timesestimate in one review
coordinate-wise or as a bandit30 to 89 timesestimate in one review

The values in the table are estimates from the reviews, not measurements.

The limit of what can be proven

The request also asked what "100 % reliable" would mean and how much of it can be proven.

Which values to keep after the tuning?

In the model every tuning runs twice, independently, from the same starting point and with separate random draws. Then one of three end rules decides for each parameter:

The model:

The more parameters are already right, the smaller the gain; at f = 0.9 the filter is ahead of the unfiltered seed mean The more parameters are already right, the smaller the gain; at f = 0.9 the filter is ahead of the unfiltered seed mean. available (all parameters at their optimum): 0 15.24, 0.3 11.2, 0.5 7.87, 0.7 5.25, 0.9 1.71; Filter: 0 9.42, 0.3 7.21, 0.5 4.98, 0.7 3.46, 0.9 1.07; Seed mean: 0 11.76, 0.3 8.66, 0.5 5.9, 0.7 3.84, 0.9 0.93; Seed mean with |T| ≥ 1: 0 11.41, 0.3 8.51, 0.5 5.86, 0.7 3.9, 0.9 1.09. 0246810121416available (all parameters at their optimum)FilterSeed meanSeed mean with |T| ≥ 1Model gain in model Elo,mean of 300 runs (s = 1.0)Expected share f of parameters already at their optimum00.30.50.70.9available (all parameters at their optimum), 0: 15.24available (all parameters at their optimum), 0.3: 11.2available (all parameters at their optimum), 0.5: 7.87available (all parameters at their optimum), 0.7: 5.25available (all parameters at their optimum), 0.9: 1.71Filter, 0: 9.42Filter, 0.3: 7.21Filter, 0.5: 4.98Filter, 0.7: 3.46Filter, 0.9: 1.07Seed mean, 0: 11.76Seed mean, 0.3: 8.66Seed mean, 0.5: 5.9Seed mean, 0.7: 3.84Seed mean, 0.9: 0.93Seed mean with |T| ≥ 1, 0: 11.41Seed mean with |T| ≥ 1, 0.3: 8.51Seed mean with |T| ≥ 1, 0.5: 5.86Seed mean with |T| ≥ 1, 0.7: 3.9Seed mean with |T| ≥ 1, 0.9: 1.09

The more parameters are already right, the smaller the gain; at f = 0.9 the filter is ahead of the unfiltered seed mean. available (all parameters at their optimum): 0 15.24, 0.3 11.2, 0.5 7.87, 0.7 5.25, 0.9 1.71; Filter: 0 9.42, 0.3 7.21, 0.5 4.98, 0.7 3.46, 0.9 1.07; Seed mean: 0 11.76, 0.3 8.66, 0.5 5.9, 0.7 3.84, 0.9 0.93; Seed mean with |T| ≥ 1: 0 11.41, 0.3 8.51, 0.5 5.86, 0.7 3.9, 0.9 1.09.

The more parameters are already right, the smaller the gain; at f = 0.9 the filter is ahead of the unfiltered seed mean (data of the chess project).
sfavailableFilterSeed meanSeed mean with |T| ≥ 1
0.503.811.23 (0.03)2.58 (0.00)2.29 (0.00)
0.50.32.800.97 (0.07)1.83 (0.03)1.71 (0.03)
0.50.51.970.66 (0.08)1.12 (0.12)1.10 (0.10)
0.50.71.310.46 (0.11)0.62 (0.30)0.68 (0.27)
0.50.90.430.14 (0.13)−0.12 (0.74)0.04 (0.67)
1.0015.249.42 (0.00)11.76 (0.00)11.41 (0.00)
1.00.311.207.21 (0.01)8.66 (0.00)8.51 (0.00)
1.00.57.874.98 (0.01)5.90 (0.00)5.86 (0.00)
1.00.75.253.46 (0.05)3.84 (0.06)3.90 (0.07)
1.00.91.711.07 (0.10)0.93 (0.46)1.09 (0.38)

Mean model gain in model Elo; in brackets the share of runs that end with a loss. The standard errors of the means lie between 0.02 and 0.34.

At f = 0.9 the seed mean ends with a loss in 46 % of runs, the filter in 10 % At f = 0.9 the seed mean ends with a loss in 46 % of runs, the filter in 10 %. Filter: 0 0, 0.3 1, 0.5 1, 0.7 5, 0.9 10; Seed mean: 0 0, 0.3 0, 0.5 0, 0.7 6, 0.9 46; Seed mean with |T| ≥ 1: 0 0, 0.3 0, 0.5 0, 0.7 7, 0.9 38. 01020304050FilterSeed meanSeed mean with |T| ≥ 1Runs ending with a modelloss, in per cent (s = 1.0)Expected share f of parameters already at their optimum00.30.50.70.9Filter, 0: 0Filter, 0.3: 1Filter, 0.5: 1Filter, 0.7: 5Filter, 0.9: 10Seed mean, 0: 0Seed mean, 0.3: 0Seed mean, 0.5: 0Seed mean, 0.7: 6Seed mean, 0.9: 46Seed mean with |T| ≥ 1, 0: 0Seed mean with |T| ≥ 1, 0.3: 0Seed mean with |T| ≥ 1, 0.5: 0Seed mean with |T| ≥ 1, 0.7: 7Seed mean with |T| ≥ 1, 0.9: 38

At f = 0.9 the seed mean ends with a loss in 46 % of runs, the filter in 10 %. Filter: 0 0, 0.3 1, 0.5 1, 0.7 5, 0.9 10; Seed mean: 0 0, 0.3 0, 0.5 0, 0.7 6, 0.9 46; Seed mean with |T| ≥ 1: 0 0, 0.3 0, 0.5 0, 0.7 7, 0.9 38.

At f = 0.9 the seed mean ends with a loss in 46 % of runs, the filter in 10 % (data of the chess project).

What the table shows:

What the model does not contain

What is open

How this was checked