Snes
Separable Natural Evolution Strategy in JavaScript
Install / Use
/learn @mattdesl/SnesREADME
snes
Separable Natural Evolution Strategy algorithm in JavaScript.
<img src="examples/rects-output.png" width="50%" />Mona Lisa in 200 rectangles, see demo
Quick Example
import SNES from "snes";
// creates an optimizer with settings
const optimizer = SNES({
solutionLength, // number of parameters
populationCount,
});
// an array to store your fitnesses for each population
const fitnesses = new Float32Array(populationCount);
// for each epoch...
const epochs = 100;
for (let i = 0; i < epochs; i++) {
// ask for a set of solutions (flat array)
const solutions = optimizer.ask();
// compute the fitness for each
for (let j = 0; j < populationCount; j++) {
// note this returns a subarray (i.e. no copy)
const params = optimizer.getSolutionAt(solutions, j);
// compute the fitness, which is often -err
fitnesses[j] = fitness(params);
}
// update the optimizer with all fitnesses
optimizer.tell(fitnesses);
}
// The optimized 'mean' solution
console.log(optimizer.center);
See the examples directory for more.
Install
Use npm to install.
npm install snes --save
Usage
optimizer = SNES({ opts })
With options:
solutionLengthnumber of parameters to optimizepopulationCountnumber of candidate solutions to usealpha(default=0.05) learning ratestatea 4-element Uint32Array random seed staterandom(default=Math.random) randomizer for computing an initialopts.stateif not specified; ignored if state is givensigmathe initial standard deviation, defaults to:new Float32Array(solutionLength).fill(1)
centerthe initial mean, defaults to:new Float32Array(solutionLength).fill(0)
solutions = optimizer.ask()
Returns a flat array of solutions, strided by solutionLength. The total size of this array will be solutionLength * populationCount.
subarray = optimizer.getSolutionAt(solutions, index)
From a flat array of solutions, gets a subarray at slot index. Since this is a view of the flat array, it is not a copy, and so any changes to the flat array will also be present in this view. You should use subarray.slice() if you want a copy.
optimizer.tell(fitnesses)
Updates the parameters based on the list of fitnesses, which is expected to be parallel to the solutions array given by the ask() function. The size of this array should be populationCount.
optimizer.center
The current mean of the optimizer, i.e. the optimization result. This may not always be the best performing candidate, for example compared to candidates from prior epochs.
other getters
optimizer.sigma(lengthsolutionLength)optimizer.gaussian(lengthpopulationCount * solutionLength)optimizer.prng(you can useprng.next()andprng.nextGaussian()for random values)
From Source
Clone the repo, cd into it and npm install dependencies, then you can run:
npm run rects
And open the localhost URL in your browser to see Mona Lisa painted in 200 rectangles.
You can also test with node examples/ascii.js for a simple textual learning example.
References
- Exponential Natural Evolution Strategies (2010) - T Glasmachers
- Benchmarking Separable Natural Evolution Strategies on the Noiseless and Noisy Black-box Optimization Testbeds (2012) - T Schaul
- pints
License
MIT, see LICENSE.md for details.
Related Skills
node-connect
338.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
338.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.4kCommit, push, and open a PR
