BitBrain SBC: counted mode + global decay (forgetting, probabilities)

Adds an smCounted storage mode alongside the default smBitset. Each
(i,j,class) cell becomes a saturating uint8 counter; learn increments it and
a global fractional decay (c -= c shr decayShift every decayEvery learns)
makes forgetting possible. infer sums raw counters; new inferProb sums the
per-cell posterior P(class|cell) (scale-free, recommended readout).

Bitset path is the default and byte-for-byte unchanged: test_bitbrain 56/56
(was 32), and test_bitbrain_mnist reproduces 97.210% corrected / 96.540%
bug-compatible exactly.

Counted mode configurable at runtime (TR_BITBRAIN_MODE / TR_BITBRAIN_DECAY_*)
and compile time (-d:bitbrainDecay*). Measured: forgetting (86.2% vs 48.9% on
a permuted-label stream), probabilities (rare-class balanced 0.998 vs 0.500),
and the stationary cost (counted hurts MNIST; see docs/bitbrain_counted_sbc.md).

Harness: common_libs/tests/measure_counted_sbc.nim
This commit is contained in:
2026-09-25 08:39:10 +02:00
parent 39e06719fb
commit 40ba96f649
6 changed files with 921 additions and 53 deletions
+14
View File
@@ -86,6 +86,20 @@ Generic over the input element type (`openArray[SomeInteger]`) and over the inpu
width, ADE count and class count — nothing is hardcoded to 784/10. Deterministic
given the seed. Dependencies: `std/` only.
### Counted SBC mode (saturating counters + forgetting)
An optional `smCounted` mode replaces each bit with a saturating `uint8` counter
and adds global fractional decay (`c -= c shr decayShift` every `decayEvery`
learns). `initBitBrain(..., mode, decayEvery, decayShift)` selects it;
`initCountedSbc` builds a single counted memory. `infer` sums raw counters;
`inferProb` sums the per-cell posterior `P(class | cell)` (the recommended
counted readout). Runtime knobs: `TR_BITBRAIN_MODE` (`bitset` default,
`counted`), `TR_BITBRAIN_DECAY_EVERY`, `TR_BITBRAIN_DECAY_SHIFT`; compile-time
defaults: `-d:bitbrainDecayEvery=N`, `-d:bitbrainDecayShift=N`. The default
bitset path is unchanged and remains the reference-compatible one. Design,
memory cost and the measured forgetting/probability/stationary evidence are in
[`docs/bitbrain_counted_sbc.md`](../../docs/bitbrain_counted_sbc.md).
Reference SBC wiring: `crossPairs(4)` gives the 6 cross-AD SBCs used by the
reference C. `withinPairs(n)` adds the paper's 4 within-AD ("half-size") SBCs;
this implementation stores them full-size (half-size packing is a separate memory